import type { TagType } from '@/utils/status-tag-registry' /** 生产结论 cg=成功 sb=失败 */ export function productionConclusionLabel(code?: string | null): string { const c = (code || '').trim() if (c === 'cg') return '成功' if (c === 'sb') return '失败' return c || '—' } export function productionConclusionTagType(code?: string | null): TagType | undefined { const c = (code || '').trim() if (c === 'cg') return 'success' if (c === 'sb') return 'danger' return undefined } /** 生产任务来源:inbound / temporary / outbound */ export function productionOrderSourceTag(orderSource?: string | null): { label: string type: TagType } { const s = (orderSource || '').trim() || 'inbound' if (s === 'temporary') return { label: '临时', type: 'warning' } if (s === 'outbound') return { label: '出库', type: 'primary' } return { label: '入库', type: 'success' } } /** 生产任务类型(临时单看 orderSource,入库/出库看 taskType) */ export function productionTaskTypeTag( taskType?: string | null, orderSource?: string | null ): { label: string; type: TagType } { if ((orderSource || '').trim() === 'temporary') { return { label: '临时生产单', type: 'warning' } } const t = (taskType || '').trim() || 'cell_storage' const map: Record = { cell_storage: { label: '入库生产单', type: 'primary' }, outbound: { label: '出库生产单', type: 'warning' } } return map[t] || { label: t, type: 'info' } } /** 按工单类型派生创建任务时的 task_type */ export function productionTaskTypeForWorkOrder(workOrderType?: string | null): string { if (workOrderType === 'outbound') return 'outbound' return 'cell_storage' } /** 工艺步骤状态 dzx=待执行 jxz=进行中 ywc=已完成 */ export function productionStepStatusTag(status?: string | null): { label: string; type: TagType } { const map: Record = { dzx: { label: '待执行', type: 'info' }, jxz: { label: '进行中', type: 'warning' }, ywc: { label: '已完成', type: 'success' } } const s = (status || '').trim() return map[s] || { label: s || '—', type: 'info' } } export function extractProductionTaskSteps(detail: Record | null | undefined) { if (!detail || typeof detail !== 'object') return [] const steps = detail.steps ?? detail.taskSteps ?? detail.stepList return Array.isArray(steps) ? steps : [] } /** 计划开始时间:展示为 YYYY-MM-DD */ export function formatPlannedStartDate(raw?: string | null): string { const s = String(raw || '').trim() if (!s) return '' const datePart = s.slice(0, 10) if (/^\d{4}-\d{2}-\d{2}$/.test(datePart)) return datePart const matched = s.match(/^(\d{4}-\d{2}-\d{2})/) return matched ? matched[1] : '' } /** 计划开始时间:表单绑定为 YYYY-MM-DD 或 null */ export function normalizePlannedStartDate(raw?: string | null): string | null { const formatted = formatPlannedStartDate(raw) return formatted || null } export function productionStepAssigneeDisplayName(raw: string): string { const s = String(raw || '').trim() if (!s) return '' const matched = s.match(/^(.+?)[((][^))]*[))]$/) if (matched) return matched[1].trim() return s } export function productionStepAssigneeLabels(row: Record): string[] { const namesStr = String(row.assigneeUserNames || '').trim() if (namesStr) { return namesStr .split(/[,,、]/) .map((n) => productionStepAssigneeDisplayName(n)) .filter(Boolean) } const namesArr: string[] = Array.isArray(row.assigneeNames) ? row.assigneeNames : [] const fromNamesArr = namesArr .map((n) => productionStepAssigneeDisplayName(String(n || ''))) .filter(Boolean) if (fromNamesArr.length) return fromNamesArr const assignees: Array<{ userId?: string; nickName?: string; userNo?: string }> = Array.isArray( row.assignees ) ? row.assignees : [] const assigneeIds: string[] = Array.isArray(row.assigneeUserIds) ? row.assigneeUserIds.map((id) => String(id || '').trim()).filter(Boolean) : [] if (assigneeIds.length) { const byId = new Map( assignees .map((a) => [String(a.userId || '').trim(), a] as const) .filter(([id]) => Boolean(id)) ) const fromIds = assigneeIds .map((id) => { const matched = byId.get(id) const name = String(matched?.nickName || matched?.userNo || '').trim() return name ? productionStepAssigneeDisplayName(name) : '' }) .filter(Boolean) if (fromIds.length) return fromIds } if (assignees.length) { return assignees .map((a) => String(a.nickName || a.userNo || '').trim()) .map((n) => productionStepAssigneeDisplayName(n)) .filter(Boolean) } return [] } export function productionStepAssigneeText(row: Record): string { return productionStepAssigneeLabels(row).join('、') } export function productionStepPlannedStartText(row: Record): string { return formatPlannedStartDate(row.plannedStartTime) } /** 中文日期展示:2026-07-01 → 2026年7月1日 */ export function formatChineseDateYmd(ymd: string): string { const matched = String(ymd || '').trim().match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/) if (!matched) return ymd return `${matched[1]}年${Number(matched[2])}月${Number(matched[3])}日` } /** 汇总工单下全部生产任务工艺步骤的计划开始时间区间 */ export function computeWorkOrderPlannedStartTimeRange( tasks: Record[] | undefined ): string { const dates: string[] = [] for (const task of tasks || []) { for (const step of Array.isArray(task.steps) ? task.steps : []) { const date = formatPlannedStartDate(step.plannedStartTime) if (date) dates.push(date) } } if (!dates.length) return '' dates.sort() const min = dates[0] const max = dates[dates.length - 1] return `${formatChineseDateYmd(min)} ~ ${formatChineseDateYmd(max)}` }