151 lines
4.9 KiB
TypeScript
151 lines
4.9 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Button } from '@/components/ui/button';
|
|
import { FormRenderer } from '@/components/FormDesigner';
|
|
import { ArrowLeft, Loader2 } from 'lucide-react';
|
|
import { getFormDataById } from './service';
|
|
import type { FormDataResponse, FormDataStatus, FormDataBusinessType } from './types';
|
|
|
|
/**
|
|
* 表单数据详情页
|
|
*/
|
|
const FormDataDetail: React.FC = () => {
|
|
const navigate = useNavigate();
|
|
const { id } = useParams<{ id: string }>();
|
|
const [loading, setLoading] = useState(false);
|
|
const [data, setData] = useState<FormDataResponse | null>(null);
|
|
|
|
// 加载数据
|
|
useEffect(() => {
|
|
if (id) {
|
|
loadData(Number(id));
|
|
}
|
|
}, [id]);
|
|
|
|
const loadData = async (dataId: number) => {
|
|
setLoading(true);
|
|
try {
|
|
const result = await getFormDataById(dataId);
|
|
setData(result);
|
|
} catch (error) {
|
|
console.error('加载表单数据失败:', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
// 返回列表
|
|
const handleBack = () => {
|
|
navigate('/form/data');
|
|
};
|
|
|
|
// 状态徽章
|
|
const getStatusBadge = (status: FormDataStatus) => {
|
|
const statusMap: Record<FormDataStatus, { variant: 'default' | 'secondary' | 'destructive' | 'success' | 'outline'; text: string }> = {
|
|
DRAFT: { variant: 'outline', text: '草稿' },
|
|
SUBMITTED: { variant: 'success', text: '已提交' },
|
|
COMPLETED: { variant: 'default', text: '已完成' },
|
|
};
|
|
const statusInfo = statusMap[status];
|
|
return <Badge variant={statusInfo.variant}>{statusInfo.text}</Badge>;
|
|
};
|
|
|
|
// 业务类型徽章
|
|
const getBusinessTypeBadge = (type: FormDataBusinessType) => {
|
|
const typeMap: Record<FormDataBusinessType, { variant: 'default' | 'secondary' | 'outline'; text: string }> = {
|
|
STANDALONE: { variant: 'outline', text: '独立' },
|
|
WORKFLOW: { variant: 'default', text: '工作流' },
|
|
ORDER: { variant: 'secondary', text: '订单' },
|
|
};
|
|
const typeInfo = typeMap[type];
|
|
return <Badge variant={typeInfo.variant}>{typeInfo.text}</Badge>;
|
|
};
|
|
|
|
// 描述项组件
|
|
const DescriptionItem: React.FC<{ label: string; value: React.ReactNode }> = ({ label, value }) => (
|
|
<div className="flex py-3 border-b last:border-b-0">
|
|
<div className="w-32 text-muted-foreground flex-shrink-0">{label}</div>
|
|
<div className="flex-1 font-medium">{value}</div>
|
|
</div>
|
|
);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="p-6">
|
|
<Card>
|
|
<CardContent className="py-12">
|
|
<div className="flex items-center justify-center">
|
|
<Loader2 className="h-8 w-8 animate-spin mr-2" />
|
|
<span>加载中...</span>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!data) {
|
|
return (
|
|
<div className="p-6">
|
|
<Card>
|
|
<CardContent className="py-12">
|
|
<div className="text-center text-muted-foreground">数据不存在</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="p-6">
|
|
<Card className="mb-4">
|
|
<CardHeader>
|
|
<div className="flex items-center justify-between">
|
|
<CardTitle>表单数据详情</CardTitle>
|
|
<Button variant="outline" onClick={handleBack}>
|
|
<ArrowLeft className="h-4 w-4 mr-2" />
|
|
返回列表
|
|
</Button>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-0">
|
|
<DescriptionItem label="表单标识" value={data.formKey} />
|
|
<DescriptionItem label="表单版本" value={`v${data.formVersion}`} />
|
|
<DescriptionItem label="业务类型" value={getBusinessTypeBadge(data.businessType)} />
|
|
<DescriptionItem label="业务标识" value={data.businessKey || '-'} />
|
|
<DescriptionItem label="提交人" value={data.submitter || '-'} />
|
|
<DescriptionItem label="提交时间" value={data.submitTime || '-'} />
|
|
<DescriptionItem label="状态" value={getStatusBadge(data.status)} />
|
|
<DescriptionItem label="创建时间" value={data.createTime || '-'} />
|
|
<DescriptionItem label="更新时间" value={data.updateTime || '-'} />
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>表单数据</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{/* 使用 FormRenderer 以只读模式展示数据 */}
|
|
<FormRenderer
|
|
schema={data.schemaSnapshot}
|
|
value={data.data}
|
|
readonly={true}
|
|
showSubmit={false}
|
|
showCancel={true}
|
|
cancelText="返回"
|
|
onCancel={handleBack}
|
|
/>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default FormDataDetail;
|
|
|