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.map((item, index) => (
- {item}
))}
)
currentList = []
}
}
const flushTable = () => {
if (tableHeaders.length > 0) {
elements.push(
{tableHeaders.map((header, index) => (
|
{header}
|
))}
{tableRows.map((row, rowIndex) => (
{row.map((cell, cellIndex) => (
|
{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}个字符` }
]}
>