174 lines
5.9 KiB
TypeScript
174 lines
5.9 KiB
TypeScript
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<string, { label: string; type: TagType }> = {
|
||
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<string, { label: string; type: TagType }> = {
|
||
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<string, any> | 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, any>): 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, any>): string {
|
||
return productionStepAssigneeLabels(row).join('、')
|
||
}
|
||
|
||
export function productionStepPlannedStartText(row: Record<string, any>): 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<string, any>[] | 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)}`
|
||
}
|