Update from Vibe Studio

This commit is contained in:
Vibe Studio
2026-01-16 06:29:38 +00:00
parent 64e97daf22
commit 976704f9ec
5 changed files with 539 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
export interface SpellCheckSystemRequest {
text_input: string
enable_error_category: boolean
enable_correction_suggestion: boolean
enable_batch_processing: boolean
}
export interface DifyRequest {
inputs: {
text_input: string
enable_error_category: boolean
enable_correction_suggestion: boolean
enable_batch_processing: boolean
}
query: string
response_mode: string
}
export interface SpellCheckResult {
error_word: string
context: string
suggestion: string
error_type?: string
}
export function detectSpellingErrors(params: SpellCheckSystemRequest) {
const requestBody: DifyRequest = {
inputs: {
text_input: params.text_input,
enable_error_category: params.enable_error_category,
enable_correction_suggestion: params.enable_correction_suggestion,
enable_batch_processing: params.enable_batch_processing
},
query: '1',
response_mode: 'streaming'
}
return fetch('https://copilot.sino-bridge.com/v1/chat-messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer app-YOaqLN0ZBsMozXCoYJqogwiA'
},
body: JSON.stringify(requestBody)
})
}

View File

@@ -28,6 +28,12 @@ const cards = [
description: '智能检测和纠正中文文本中的错别字', description: '智能检测和纠正中文文本中的错别字',
icon: <EditOutlined style={{ fontSize: 32, color: '#fa8c16' }} />, icon: <EditOutlined style={{ fontSize: 32, color: '#fa8c16' }} />,
link: '/spell-check' link: '/spell-check'
},
{
title: '错别字检测与修正系统',
description: '更智能的错别字检测与修正系统,支持分类和建议',
icon: <EditOutlined style={{ fontSize: 32, color: '#13c2c2' }} />,
link: '/spell-check-system'
} }
] ]

View File

@@ -0,0 +1,356 @@
import { useState } from 'react'
import { Button, Card, Form, Input, Table, Switch, Space, message } from 'antd'
import { detectSpellingErrors, SpellCheckResult } from '@/api/spell-check-system'
interface FeedbackItem extends SpellCheckResult {
id: string
status: 'pending' | 'confirmed' | 'rejected'
}
const SpellCheckSystem = () => {
const [form] = Form.useForm()
const [isDetecting, setIsDetecting] = useState(false)
const [detectionResults, setDetectionResults] = useState<FeedbackItem[]>([])
const [feedbackData, setFeedbackData] = useState<{
confirmed: string[]
rejected: string[]
}>({
confirmed: [],
rejected: []
})
const handleDetect = async () => {
try {
const formValues = await form.validateFields()
// 验证用户输入文本
if (!formValues.text_input?.trim()) {
message.warning('请输入需要检测的文本内容')
return
}
setIsDetecting(true)
setDetectionResults([])
const response = await detectSpellingErrors({
text_input: formValues.text_input,
enable_error_category: formValues.enable_error_category || false,
enable_correction_suggestion: formValues.enable_correction_suggestion !== false,
enable_batch_processing: formValues.enable_batch_processing || false
})
if (!response.ok) {
const errorText = await response.text()
throw new Error(`检测请求失败: ${response.status} ${errorText}`)
}
if (!response.body) {
throw new Error('响应体为空')
}
const reader = response.body.getReader()
const decoder = new TextDecoder('utf-8')
let buffer = ''
let fullContent = ''
let results: SpellCheckResult[] = []
try {
while (true) {
const { done, value } = await reader.read()
if (done) break
buffer += decoder.decode(value, { stream: true })
const lines = buffer.split('\n')
buffer = lines.pop() || ''
for (const line of lines) {
const trimmedLine = line.trim()
if (!trimmedLine || trimmedLine === 'data: [DONE]') {
if (trimmedLine === 'data: [DONE]') {
message.success('检测完成')
break
}
continue
}
if (trimmedLine.startsWith('data: ')) {
try {
const data = trimmedLine.slice(6)
const parsed = JSON.parse(data)
if (parsed.event === 'message' && parsed.answer) {
fullContent += parsed.answer
// 尝试解析JSON结果
try {
results = JSON.parse(fullContent)
const feedbackItems: FeedbackItem[] = results.map((item, index) => ({
...item,
id: `item-${index}`,
status: 'pending' as const
}))
setDetectionResults(feedbackItems)
} catch (e) {
// 解析失败,继续等待
}
} else if (parsed.event === 'error') {
throw new Error(parsed.message || 'Dify API 返回错误')
}
} catch (parseError) {
console.warn('跳过无法解析的行:', trimmedLine)
}
}
}
}
} finally {
reader.releaseLock()
}
if (results.length === 0 && fullContent) {
try {
results = JSON.parse(fullContent)
const feedbackItems: FeedbackItem[] = results.map((item, index) => ({
...item,
id: `item-${index}`,
status: 'pending' as const
}))
setDetectionResults(feedbackItems)
} catch (e) {
message.warning('检测完成,但结果格式异常')
}
}
} catch (error) {
console.error('检测错误:', error)
message.error(error instanceof Error ? error.message : '检测失败,请稍后重试')
} finally {
setIsDetecting(false)
}
}
const handleFeedback = (id: string, status: 'confirmed' | 'rejected') => {
setDetectionResults(prev =>
prev.map(item =>
item.id === id ? { ...item, status } : item
)
)
}
const handleSubmitFeedback = () => {
const confirmed: string[] = []
const rejected: string[] = []
detectionResults.forEach(item => {
if (item.status === 'confirmed') {
confirmed.push(item.suggestion)
} else if (item.status === 'rejected') {
rejected.push(item.error_word)
}
})
const feedback = { confirmed, rejected }
// 存储到本地存储
localStorage.setItem('spell_check_feedback', JSON.stringify(feedback))
setFeedbackData(feedback)
message.success('反馈数据已提交并保存到本地存储')
}
const renderFeedbackButtons = (record: FeedbackItem) => {
if (record.status !== 'pending') {
return (
<span style={{ color: record.status === 'confirmed' ? '#52c41a' : '#ff4d4f', fontWeight: 'bold' }}>
{record.status === 'confirmed' ? '已确认' : '已否决'}
</span>
)
}
return (
<Space size="small">
<Button
size="small"
type="primary"
onClick={() => handleFeedback(record.id, 'confirmed')}
style={{ fontSize: '12px', height: '24px' }}
>
</Button>
<Button
size="small"
danger
onClick={() => handleFeedback(record.id, 'rejected')}
style={{ fontSize: '12px', height: '24px' }}
>
</Button>
</Space>
)
}
const columns = [
{
title: '错误词',
dataIndex: 'error_word',
key: 'error_word',
width: 120,
render: (text: string) => (
<span style={{ color: '#ff4d4f', fontWeight: 'bold' }}>{text}</span>
)
},
{
title: '上下文',
dataIndex: 'context',
key: 'context',
ellipsis: true
},
{
title: '建议词',
dataIndex: 'suggestion',
key: 'suggestion',
width: 120,
render: (text: string) => (
<span style={{ color: '#52c41a', fontWeight: 'bold' }}>{text}</span>
)
},
{
title: '错误类型',
dataIndex: 'error_type',
key: 'error_type',
width: 120,
render: (text: string) => text || '-'
},
{
title: '操作',
key: 'action',
width: 150,
render: (_: any, record: FeedbackItem) => renderFeedbackButtons(record)
}
]
return (
<div style={{ maxWidth: '1000px', margin: '0 auto', padding: '20px' }}>
{/* 页面标题区 */}
<div style={{ textAlign: 'center', marginBottom: '40px' }}>
<h1 style={{ color: '#1890ff', fontSize: '32px', fontWeight: 'bold', margin: 0 }}>
</h1>
</div>
<Space direction="vertical" style={{ width: '100%' }} size="large">
{/* 参数输入区 */}
<Card title="参数输入区">
<Form form={form} layout="vertical" initialValues={{
enable_error_category: false,
enable_correction_suggestion: true,
enable_batch_processing: false
}}>
<Form.Item
name="text_input"
label="待检测文本"
rules={[
{ required: true, message: '请输入需要检测的文本内容' }
]}
>
<Input.TextArea
rows={6}
placeholder="请输入需要检测错别字的文本内容..."
style={{ fontSize: '14px' }}
/>
</Form.Item>
<div style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', marginTop: '16px' }}>
<Form.Item
name="enable_error_category"
label="是否启用分类"
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
name="enable_correction_suggestion"
label="是否启用建议"
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
name="enable_batch_processing"
label="是否启用批量处理"
valuePropName="checked"
>
<Switch />
</Form.Item>
</div>
</Form>
</Card>
{/* 操作按钮区 */}
<div style={{ display: 'flex', justifyContent: 'center', gap: '16px' }}>
<Button
type="primary"
size="large"
onClick={handleDetect}
loading={isDetecting}
style={{ minWidth: '120px', height: '40px', fontSize: '16px' }}
>
</Button>
<Button
size="large"
onClick={() => {
form.resetFields()
setDetectionResults([])
setFeedbackData({ confirmed: [], rejected: [] })
message.info('已重置表单')
}}
disabled={isDetecting}
style={{ minWidth: '120px', height: '40px', fontSize: '16px' }}
>
</Button>
</div>
{/* 内容展示区 */}
<Card
title="错别字检测结果"
style={{
display: detectionResults.length > 0 || isDetecting ? 'block' : 'none'
}}
>
{isDetecting ? (
<div style={{ textAlign: 'center', color: '#999', padding: '40px' }}>
...
</div>
) : detectionResults.length > 0 ? (
<>
<Table
columns={columns}
dataSource={detectionResults}
rowKey="id"
pagination={{ pageSize: 10 }}
scroll={{ y: 400 }}
/>
<div style={{ marginTop: '16px', textAlign: 'center' }}>
<Button
type="primary"
onClick={handleSubmitFeedback}
disabled={detectionResults.every(item => item.status === 'pending')}
style={{ minWidth: '140px', height: '36px', fontSize: '14px' }}
>
</Button>
</div>
</>
) : (
<div style={{ textAlign: 'center', color: '#999' }}>
</div>
)}
</Card>
</Space>
</div>
)
}
export default SpellCheckSystem

View File

@@ -48,6 +48,10 @@ const router: RouteObject[] = [
path: '/spell-check', path: '/spell-check',
element: LazyLoad(lazy(() => import('@/pages/spell-check'))) element: LazyLoad(lazy(() => import('@/pages/spell-check')))
}, },
{
path: '/spell-check-system',
element: LazyLoad(lazy(() => import('@/pages/spell-check-system')))
},
{ {
path: '/404', path: '/404',
element: <>404</> element: <>404</>

View File

@@ -0,0 +1,127 @@
# 错别字检测与修正系统 - 使用说明
## 系统概述
错别字检测与修正系统是一个基于AI技术的智能文本校对工具能够自动识别中文文本中的错别字并提供修正建议。
## 功能特点
### 核心功能
- **智能检测**:自动识别文本中的错别字
- **上下文分析**:提供错误词在原文中的上下文信息
- **修正建议**:为每个错别字提供准确的修正建议
- **错误分类**:可选择启用错别字类型分类(如:同音字、形近字等)
- **用户反馈**:支持用户对修正建议进行确认或否决
- **批量处理**:支持多段文本的批量检测
### 交互功能
- **实时反馈**:用户可以逐条确认或否决检测结果
- **结果统计**:自动统计确认和否决的反馈数据
- **本地存储**:反馈数据自动保存到本地存储
## 页面结构
### 1. 页面标题区
- 居中显示蓝色标题"错别字检测与修正系统"
### 2. 参数输入区
- **待检测文本**:大型文本输入框,支持多段文本
- **配置选项**
- 是否启用分类:控制是否显示错别字类型
- 是否启用建议:控制是否提供修正建议(默认启用)
- 是否启用批量处理:控制是否支持多段文本处理
### 3. 操作按钮区
- **检测按钮**:触发错别字检测流程
- **重置按钮**:清空表单和结果
### 4. 内容展示区
- **检测结果表格**:展示所有检测到的错别字
- **表格列**
- 错误词:显示识别到的错别字(红色高亮)
- 上下文:显示错别字在原文中的位置和上下文
- 建议词:显示系统提供的修正建议(绿色高亮)
- 错误类型:显示错别字分类(如适用)
- 操作:提供确认/否决按钮供用户反馈
- **反馈提交按钮**:提交用户反馈数据
## 使用方法
### 基本流程
1. **输入文本**
- 在"待检测文本"区域输入需要检测的文本内容
- 文本支持中文,可包含多段内容
2. **配置选项**
- 根据需要开启/关闭各项功能开关
- 默认启用"是否启用建议"
3. **开始检测**
- 点击"检测"按钮
- 系统将发送请求到Dify AI平台
- 等待流式响应返回检测结果
4. **查看结果**
- 检测完成后,结果将显示在下方表格中
- 表格显示错误词、上下文、建议词、错误类型等信息
5. **提交反馈**
- 对每条检测结果点击"确认"或"否决"
- 点击"提交反馈"按钮保存反馈数据
- 数据将自动保存到本地存储
### API配置
- **请求地址**https://copilot.sino-bridge.com/v1/chat-messages
- **鉴权方式**Bearer Token (app-YOaqLN0ZBsMozXCoYJqogwiA)
- **请求方式**POST
- **响应模式**:流式 (streaming)
## 技术实现
### 前端技术栈
- React 18 + TypeScript
- Ant Design 5.xUI组件库
- Tailwind CSS 4.x样式框架
- React Router DOM 6.x路由管理
### 核心特性
- **流式数据处理**实时接收和解析Dify平台的流式响应
- **响应式设计**:自适应不同屏幕尺寸
- **类型安全**完整的TypeScript类型定义
- **模块化设计**清晰的API和组件分离
## 文件结构
```
src/
├── api/
│ └── spell-check-system.ts # API接口定义
├── pages/
│ └── spell-check-system/
│ └── index.tsx # 主页面组件
└── router/
└── index.tsx # 路由配置
```
## 访问路径
- 主页导航:`/` → 选择"错别字检测与修正系统"卡片
- 直接访问:`/#/spell-check-system`
## 注意事项
1. **文本长度**:建议单次检测的文本长度不超过合理范围,以保证检测效果
2. **网络连接**需要稳定的网络连接以访问Dify AI服务
3. **浏览器兼容性**推荐使用现代浏览器Chrome、Firefox、Safari、Edge
4. **数据存储**:用户反馈数据仅保存在本地浏览器存储中
## 更新日志
### v1.0.0
- 初始版本发布
- 实现基础的错别字检测功能
- 支持流式数据处理
- 添加用户反馈系统
- 集成Dify AI平台