import { useState } from 'react' import { Button, Card, Form, Input, message, Space, Typography } from 'antd' import { reviewContract } from '@/api/contract-review' const { Title, Paragraph, Text } = Typography const { TextArea } = Input const HomePage: React.FC = () => { const [form] = Form.useForm() const [loading, setLoading] = useState(false) const [reviewResult, setReviewResult] = useState('') const [currentInput, setCurrentInput] = useState('') const maxChars = 5000 // 简单的markdown处理函数 const formatMarkdown = (text: string) => { if (!text) return [] const lines = text.split('\n') const elements: React.ReactNode[] = [] let currentList: string[] = [] let inTable = false let tableHeaders: string[] = [] let tableRows: string[][] = [] const flushList = () => { if (currentList.length > 0) { elements.push( ) currentList = [] } } const flushTable = () => { if (tableHeaders.length > 0) { elements.push(
{tableHeaders.map((header, index) => ( ))} {tableRows.map((row, rowIndex) => ( {row.map((cell, cellIndex) => ( ))} ))}
{header}
{cell}
) tableHeaders = [] tableRows = [] inTable = false } } lines.forEach((line, index) => { const trimmedLine = line.trim() // 处理标题 if (trimmedLine.startsWith('# ')) { flushList() flushTable() elements.push( {trimmedLine.substring(2)} ) } else if (trimmedLine.startsWith('## ')) { flushList() flushTable() elements.push( {trimmedLine.substring(3)} ) } else if (trimmedLine.startsWith('### ')) { flushList() flushTable() elements.push( {trimmedLine.substring(4)} ) } // 处理分割线 else if (trimmedLine === '---') { flushList() flushTable() elements.push(
) } // 处理列表项 else if (trimmedLine.startsWith('- ') || trimmedLine.startsWith('* ')) { flushTable() currentList.push(trimmedLine.substring(2)) } // 处理表格 else if (trimmedLine.includes('|') && !inTable) { flushList() inTable = true tableHeaders = trimmedLine.split('|').map(h => h.trim()).filter(h => h) } else if (trimmedLine.includes('|') && inTable && !trimmedLine.includes('---')) { const row = trimmedLine.split('|').map(c => c.trim()).filter(c => c) if (row.length > 0) { tableRows.push(row) } } else if (trimmedLine.includes('|') && inTable && trimmedLine.includes('---')) { // 跳过分隔行 } // 处理普通段落 else if (trimmedLine) { flushList() flushTable() // 处理加粗文本 const boldRegex = /\*\*(.*?)\*\*/g const parts = trimmedLine.split(boldRegex) if (parts.length > 1) { elements.push( {parts.map((part, partIndex) => partIndex % 2 === 1 ? {part} : part )} ) } else { elements.push( {trimmedLine} ) } } }) // 清理剩余的内容 flushList() flushTable() return elements } const handleReview = async () => { try { const contract_text = form.getFieldValue('contract_text') || '' if (!contract_text.trim()) { message.warning('请输入合同片段内容') return } setLoading(true) setReviewResult('') const response = await reviewContract(contract_text) 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 = '' 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('审核完成') setLoading(false) return } 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 setReviewResult(fullContent) } else if (parsed.event === 'error') { throw new Error(parsed.message || 'Dify API 返回错误') } } catch (parseError) { console.warn('跳过无法解析的行:', trimmedLine) } } } } } finally { reader.releaseLock() } if (fullContent) { message.success('审核完成') } else { throw new Error('未收到审核结果') } } catch (error) { console.error('审核错误:', error) message.error(error instanceof Error ? error.message : '审核失败,请稍后重试') } finally { setLoading(false) } } const handleReset = () => { form.resetFields() setReviewResult('') setCurrentInput('') message.info('已重置内容') } const handleReReview = () => { handleReview() } return (
合同智能审核 通过AI技术对合同片段进行智能审核,提供专业建议 {/* 参数输入区 */}
合同片段文本 maxChars ? '#ff4d4f' : '#999' }}> {currentInput.length} / {maxChars}
} rules={[ { required: true, message: '请输入合同片段内容' }, { max: maxChars, message: `输入内容不能超过${maxChars}个字符` } ]} >