Files
shanxia2.0/web-admin/src/utils/mp-pl-plan-detail-actions.ts
T
wuzilongandCursor bde19c0644 feat: 锁定执行中计划并按装卸明细差量归档库存,补齐派车日历数量与酸碱类型。
执行中的运输计划不再随意改单;库存流水记到装卸产品明细;手工派车日历区分酸碱并记录数量。同时收紧合同附件与子表的差量保存,并清理已废弃的 bak 备份目录。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-29 07:59:53 +08:00

136 lines
4.0 KiB
TypeScript

export type MpDetailActionKind =
| 'edit'
| 'arrange'
| 'copy-driver'
| 'copy-site'
| 'copy-pound-qrcode'
| 'copy'
| 'wait'
| 'cancel-wait'
| 'void'
| 'void-blocked'
| 'force-void'
export type MpDetailAction = {
kind: MpDetailActionKind
label: string
danger?: boolean
}
/**
* 主栏最多 2 个:优先 edit、arrange;其余进 more。
* 若无可展示主操作,再从 more 补足最多 2 个,避免底栏空白。
* 安排后复制类(司机/现场/磅单码)始终进 more(详情页另有显眼入口)。
*/
export function splitMpPlanDetailActions(input: {
canEdit: boolean
canArrange: boolean
arrangeLabel: string
canCopyDriver?: boolean
canCopySite?: boolean
canCopyPoundQrcode?: boolean
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 })
}
if (input.canCopyDriver) more.push({ kind: 'copy-driver', label: '复制给司机' })
if (input.canCopySite) more.push({ kind: 'copy-site', label: '复制给现场' })
if (input.canCopyPoundQrcode) more.push({ kind: 'copy-pound-qrcode', label: '复制磅单二维码' })
more.push({ kind: 'copy', label: '复制' })
if (input.canWait) more.push({ kind: 'wait', label: '等客户通知' })
if (input.canCancelWait) more.push({ kind: 'cancel-wait', label: '取消等通知' })
if (input.canVoid) more.push({ kind: 'void', label: '作废', danger: true })
while (primary.length > 2) more.unshift(primary.pop()!)
// 仅当主栏完全为空时补位;优先补非复制类业务操作,避免把「复制给司机」挤到主栏
if (primary.length === 0) {
const preferKinds: MpDetailActionKind[] = ['copy', 'wait', 'cancel-wait', 'void']
for (const kind of preferKinds) {
if (primary.length >= 2) break
const idx = more.findIndex((a) => a.kind === kind)
if (idx < 0) continue
primary.push(more.splice(idx, 1)[0])
}
while (primary.length < 2 && more.length) {
primary.push(more.shift()!)
}
}
return { primary, more }
}
export type MpFormFooterActionKey =
| 'cancel'
| 'draft'
| 'save'
| 'saveAndArrange'
| 'rearrange'
export type MpFormFooterAction = {
key: MpFormFooterActionKey
label: string
type?: 'primary' | 'default'
ghost?: boolean
}
/** 表单底栏:暂存 / 创建(保存) / 主操作 外显;取消进更多 */
export function splitMpPlanFormFooterActions(input: {
showDraft: boolean
showSave: boolean
showSaveAndArrange: boolean
showRearrange: boolean
saveLabel: string
saveAndArrangeLabel: string
}): { primary: MpFormFooterAction[]; more: MpFormFooterAction[] } {
const more: MpFormFooterAction[] = [{ key: 'cancel', label: '取消' }]
const primary: MpFormFooterAction[] = []
const hasStrongPrimary = input.showSaveAndArrange || input.showRearrange
if (input.showDraft) {
primary.push({ key: 'draft', label: '暂存' })
}
if (input.showSave) {
primary.push({
key: 'save',
label: input.saveLabel,
type: hasStrongPrimary ? 'default' : 'primary',
ghost: hasStrongPrimary
})
}
if (input.showRearrange) {
primary.push({ key: 'rearrange', label: '调整运输', type: 'primary' })
} else if (input.showSaveAndArrange) {
primary.push({
key: 'saveAndArrange',
label: input.saveAndArrangeLabel,
type: 'primary'
})
}
// 主栏最多 3 个,多出的收进更多(取消仍排最前)
while (primary.length > 3) {
const overflow = primary.pop()!
more.splice(1, 0, overflow)
}
if (primary.length === 0 && more.length > 1) {
const first = more.find((a) => a.key !== 'cancel') || more[0]
if (first) {
more.splice(more.indexOf(first), 1)
primary.push({ ...first, type: first.type || 'primary' })
}
}
return { primary, more }
}