Files
copilot-toolbox-template-26…/src/pages/number-to-chinese/index.tsx
2026-02-04 09:39:59 +00:00

174 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react'
import { Form, Input, Button, Card, Typography, Space, Spin } from 'antd'
import { ArrowRightOutlined, ClearOutlined } from '@ant-design/icons'
import type { FetchStreamOptions } from '@copilotkit/react-core'
const { Title, Text } = Typography
interface DifyResponse {
message: string
}
export default function NumberToChinese() {
const [form] = Form.useForm()
const [loading, setLoading] = useState(false)
const [result, setResult] = useState('')
const [error, setError] = useState('')
const handleConvert = async (values: { number: string }) => {
setLoading(true)
setError('')
setResult('')
try {
const response = await fetch(`${import.meta.env.VITE_DIFY_API_BASE}/chat-messages`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${import.meta.env.VITE_DIFY_APP_KEY}`
},
body: JSON.stringify({
inputs: { number: values.number },
query: '1',
response_mode: 'streaming'
})
})
if (!response.ok) {
throw new Error('请求失败')
}
const reader = response.body?.getReader()
if (!reader) {
throw new Error('无法读取响应流')
}
const decoder = new TextDecoder()
let fullContent = ''
while (true) {
const { done, value } = await reader.read()
if (done) break
const chunk = decoder.decode(value)
const lines = chunk.split('\n')
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.slice(6)) as DifyResponse
if (data.message) {
fullContent += data.message
setResult(fullContent)
}
} catch {
// 忽略解析错误
}
}
}
}
} catch (err) {
setError(err instanceof Error ? err.message : '转换失败,请稍后重试')
} finally {
setLoading(false)
}
}
const handleReset = () => {
form.resetFields()
setResult('')
setError('')
}
return (
<div className="min-h-screen bg-white p-6">
<div className="max-w-2xl mx-auto">
{/* 页面标题区 */}
<div className="text-center mb-8">
<Title level={2} style={{ color: '#1890ff', margin: 0 }}>
</Title>
</div>
{/* 参数输入区 */}
<Card className="mb-6 shadow-sm border-radius-lg">
<Form
form={form}
layout="vertical"
onFinish={handleConvert}
autoComplete="off"
>
<Form.Item
name="number"
rules={[
{ required: true, message: '请输入数字' },
{ pattern: /^-?\d+(\.\d+)?$/, message: '请输入有效数字' }
]}
>
<Input.TextArea
placeholder="请输入要转换的数字"
rows={3}
className="text-lg"
allowClear
/>
</Form.Item>
<Form.Item className="mb-0">
<Space className="w-full justify-center">
<Button
type="primary"
htmlType="submit"
icon={<ArrowRightOutlined />}
loading={loading}
size="large"
>
</Button>
<Button
icon={<ClearOutlined />}
onClick={handleReset}
size="large"
>
</Button>
</Space>
</Form.Item>
</Form>
</Card>
{/* 内容展示区 */}
<Card
className="shadow-sm"
style={{ minHeight: '150px', maxHeight: '60vh', overflow: 'auto' }}
>
{loading && (
<div className="text-center py-8">
<Spin size="large" />
<Text className="block mt-4 text-gray-400">...</Text>
</div>
)}
{!loading && error && (
<div className="text-center py-8">
<Text type="danger">{error}</Text>
</div>
)}
{!loading && !error && result && (
<div>
<Text strong className="block mb-4"></Text>
<div className="text-lg leading-relaxed whitespace-pre-wrap">{result}</div>
</div>
)}
{!loading && !error && !result && (
<div className="text-center py-8">
<Text type="secondary"></Text>
</div>
)}
</Card>
</div>
</div>
)
}