'use client' import { useState } from 'react' import { DINGTALK_APPROVAL_NO_MAX_LENGTH, getDingtalkApprovalNoError, } from '@/lib/dingtalk-approval-no' import { fieldControlClass, fieldErrorClass, fieldLabelClass, } from '@/components/upload/upload-field-styles' interface TaskReferenceFieldsProps { idPrefix: string taskNo: string onTaskNoChange: (value: string) => void dingtalkApprovalNo: string onDingtalkApprovalNoChange: (value: string) => void taskNoRequired?: boolean disabled?: boolean } function getTaskNoError(value: string): string | null { const normalized = value.trim().toUpperCase() if (!normalized) { return null } return /^TASK\d{12,18}(-\d{2})*$/.test(normalized) ? null : '任务号格式错误' } export default function TaskReferenceFields({ idPrefix, taskNo, onTaskNoChange, dingtalkApprovalNo, onDingtalkApprovalNoChange, taskNoRequired = false, disabled = false, }: TaskReferenceFieldsProps) { const [taskNoTouched, setTaskNoTouched] = useState(false) const [approvalNoTouched, setApprovalNoTouched] = useState(false) const taskNoId = `${idPrefix}-task-no` const taskNoErrorId = `${taskNoId}-error` const approvalNoId = `${idPrefix}-dingtalk-approval-no` const approvalNoErrorId = `${approvalNoId}-error` const taskNoError = getTaskNoError(taskNo) const approvalNoError = getDingtalkApprovalNoError(dingtalkApprovalNo) const visibleTaskNoError = taskNoTouched ? taskNoError : null const visibleApprovalNoError = approvalNoTouched ? approvalNoError : null return (
onTaskNoChange(event.target.value.toUpperCase())} onBlur={() => setTaskNoTouched(true)} placeholder="例如:TASK202601030184" className={fieldControlClass} disabled={disabled} required={taskNoRequired} aria-invalid={Boolean(visibleTaskNoError)} aria-describedby={visibleTaskNoError ? taskNoErrorId : undefined} /> {visibleTaskNoError && (

{visibleTaskNoError}

)}
onDingtalkApprovalNoChange(event.target.value)} onBlur={() => setApprovalNoTouched(true)} placeholder="例如:202508211445000157693" className={fieldControlClass} disabled={disabled} aria-invalid={Boolean(visibleApprovalNoError)} aria-describedby={visibleApprovalNoError ? approvalNoErrorId : undefined} /> {visibleApprovalNoError && (

{visibleApprovalNoError}

)}
) }