From 92bb4bf0d0f950b4e26cb886db5be2d229aebe9a Mon Sep 17 00:00:00 2001 From: wuzilong <704541015@qq.com> Date: Tue, 15 Sep 2026 09:31:43 +0800 Subject: [PATCH] feat(web-admin): add mp plan detail action splitter. Cap the sticky footer at two primary actions and park the rest in a more sheet. Co-authored-by: Cursor --- .../check-mp-pl-plan-detail-actions.mjs | 63 +++++++++++++++++++ .../src/utils/mp-pl-plan-detail-actions.ts | 44 +++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 web-admin/scripts/check-mp-pl-plan-detail-actions.mjs create mode 100644 web-admin/src/utils/mp-pl-plan-detail-actions.ts diff --git a/web-admin/scripts/check-mp-pl-plan-detail-actions.mjs b/web-admin/scripts/check-mp-pl-plan-detail-actions.mjs new file mode 100644 index 000000000..456950e83 --- /dev/null +++ b/web-admin/scripts/check-mp-pl-plan-detail-actions.mjs @@ -0,0 +1,63 @@ +/** + * Mirrors web-admin/src/utils/mp-pl-plan-detail-actions.ts (no vitest in web-admin). + */ +function splitMpPlanDetailActions(input) { + const primary = [] + const more = [] + + if (input.canEdit) primary.push({ kind: 'edit', label: '编辑' }) + if (input.canArrange) { + primary.push({ kind: 'arrange', label: input.arrangeLabel }) + } + + more.push({ kind: 'copy', label: '复制' }) + if (input.canWait) more.push({ kind: 'wait', label: '等客户通知' }) + if (input.canCancelWait) more.push({ kind: 'cancel-wait', label: '取消等通知' }) + more.push({ kind: 'print', label: '打印单据' }) + if (input.canVoid) more.push({ kind: 'void', label: '作废', danger: true }) + + while (primary.length > 2) more.unshift(primary.pop()) + while (primary.length < 2 && more.length) { + primary.push(more.shift()) + } + return { primary, more } +} + +function assert(cond, msg) { + if (!cond) { + console.error('FAIL:', msg) + process.exit(1) + } +} + +const both = splitMpPlanDetailActions({ + canEdit: true, + canArrange: true, + arrangeLabel: '安排运输', + canWait: true, + canCancelWait: false, + canVoid: true +}) +assert( + both.primary.map((a) => a.kind).join(',') === 'edit,arrange', + 'primary should be edit,arrange' +) +assert( + both.more.map((a) => a.kind).join(',') === 'copy,wait,print,void', + 'more should be copy,wait,print,void' +) + +const onlyVoid = splitMpPlanDetailActions({ + canEdit: false, + canArrange: false, + arrangeLabel: '安排运输', + canWait: false, + canCancelWait: false, + canVoid: true +}) +assert(onlyVoid.primary.length === 2, 'promote more into primary until 2') +assert(onlyVoid.primary[0].kind === 'copy', 'first promoted is copy') +assert(onlyVoid.primary[1].kind === 'print', 'second promoted is print') +assert(onlyVoid.more.map((a) => a.kind).join(',') === 'void', 'void remains in more') + +console.log('check-mp-pl-plan-detail-actions: ok') diff --git a/web-admin/src/utils/mp-pl-plan-detail-actions.ts b/web-admin/src/utils/mp-pl-plan-detail-actions.ts new file mode 100644 index 000000000..4142f076b --- /dev/null +++ b/web-admin/src/utils/mp-pl-plan-detail-actions.ts @@ -0,0 +1,44 @@ +export type MpDetailActionKind = + | 'edit' + | 'arrange' + | 'copy' + | 'wait' + | 'cancel-wait' + | 'print' + | 'void' + +export type MpDetailAction = { + kind: MpDetailActionKind + label: string + danger?: boolean +} + +/** 主栏最多 2 个:优先 edit、arrange;其余进 more */ +export function splitMpPlanDetailActions(input: { + canEdit: boolean + canArrange: boolean + arrangeLabel: string + canWait: boolean + canCancelWait: boolean + canVoid: boolean +}): { primary: MpDetailAction[]; more: MpDetailAction[] } { + const primary: MpDetailAction[] = [] + const more: MpDetailAction[] = [] + + if (input.canEdit) primary.push({ kind: 'edit', label: '编辑' }) + if (input.canArrange) { + primary.push({ kind: 'arrange', label: input.arrangeLabel }) + } + + more.push({ kind: 'copy', label: '复制' }) + if (input.canWait) more.push({ kind: 'wait', label: '等客户通知' }) + if (input.canCancelWait) more.push({ kind: 'cancel-wait', label: '取消等通知' }) + more.push({ kind: 'print', label: '打印单据' }) + if (input.canVoid) more.push({ kind: 'void', label: '作废', danger: true }) + + while (primary.length > 2) more.unshift(primary.pop()!) + while (primary.length < 2 && more.length) { + primary.push(more.shift()!) + } + return { primary, more } +}