import { useState } from 'react' import { useQuery } from '@tanstack/react-query' import { FileText, Copy, X, ChevronRight } from 'lucide-react' import { toast } from 'sonner' import api from '../lib/api' import Card from '../components/ui/Card' import Button from '../components/ui/Button' import EmptyState from '../components/ui/EmptyState' const CATEGORY_LABELS: Record = { CONTRACT: '合同', RULES: '规章制度', NOTICE: '通知', AGREEMENT: '协议', OTHER: '其他', } const VARIABLE_LABELS: Record = { companyName: '公司名称', employeeName: '员工姓名', idCard: '身份证号', address: '地址', startDate: '开始日期', position: '岗位', endDate: '结束日期', terminationDate: '解除日期', publishDate: '公示日期', effectiveDate: '生效日期', meetingDate: '会议日期', meetingLocation: '会议地点', policyTitle: '制度名称', department: '部门', violationDate: '违纪日期', violationDescription: '违纪描述', probationEndDate: '试用期截止', regularDate: '转正日期', contractEndDate: '合同到期日', salary: '工资', phone: '手机号', hireDate: '入职日期', gender: '性别', birthDate: '出生日期', bankAccount: '银行账号', bankName: '开户银行', emergencyContact: '紧急联系人', emergencyPhone: '紧急联系电话', workYears: '工作年限', compAmount: '补偿金额', noticeDate: '通知日期', reason: '原因', overtimeHours: '加班时长', overtimePay: '加班费', socialInsBase: '社保基数', housingFundBase: '公积金基数', compensation: '经济补偿', lastWorkDay: '最后工作日', socialInsEndMonth: '社保截止月', housingFundEndMonth: '公积金截止月', probationMonths: '试用期月数', monthlySalary: '月薪', workplace: '工作地点', disciplineType: '处分类型', policyBasis: '制度依据', } /** * 用工文本模板库页面 */ export default function Templates() { const [category, setCategory] = useState('') const [selected, setSelected] = useState(null) const [rendered, setRendered] = useState('') const [variables, setVariables] = useState>({}) const { data: list, isLoading } = useQuery({ queryKey: ['templates', category], queryFn: async () => { const params = category ? `?category=${category}` : '' const res = await api.get(`/templates${params}`) as any return res.data }, }) const { data: detail } = useQuery({ queryKey: ['template-detail', selected?.id], queryFn: async () => { const res = await api.get(`/templates/${selected.id}`) as any return res.data }, enabled: !!selected, }) const handleRender = async () => { if (!selected) return try { const res = await api.post(`/templates/${selected.id}/render`, { variables }) as any setRendered(res.data.content) } catch (err: any) { toast.error('渲染失败') } } const handleCopy = () => { navigator.clipboard.writeText(rendered) toast.success('已复制到剪贴板') } return (

用工文本模板库

合同、制度、通知等常用文本模板,支持变量替换

{['', 'CONTRACT', 'RULES', 'NOTICE', 'AGREEMENT', 'OTHER'].map(c => ( ))}
{isLoading ? (
加载中...
) : !list || list.length === 0 ? ( ) : (
{list.map((t: any) => (
{ setSelected(t); setRendered(''); setVariables({}) }}>
{CATEGORY_LABELS[t.category]} {t.name}

{t.description}

{t.variables?.slice(0, 4).map((v: string) => ( {VARIABLE_LABELS[v] || v} ))} {t.variables?.length > 4 && +{t.variables.length - 4}}
))}
)} {/* 模板详情弹窗 */} {selected && (
setSelected(null)}>
e.stopPropagation()}>

{selected.name}

{/* 变量输入 */} {detail?.variables && detail.variables.length > 0 && (
填写变量
{detail.variables.map((v: string) => (
setVariables(prev => ({ ...prev, [v]: e.target.value }))} className="w-full px-2 py-1 text-sm border rounded focus:outline-none focus:ring-1 focus:ring-primary" placeholder={`输入${VARIABLE_LABELS[v] || v}`} />
))}
)} {/* 渲染结果 */} {rendered ? (
渲染结果
{rendered}
) : detail?.content ? (
模板原文
{detail.content}
) : null}
)}
) }