4f363fa9e7
- HQ stores: partner column uses companyName/name/phone via partnerOptionLabel - Dev plan: version RELEASED auto-marks tasks RELEASED and tickets PUBLISHED with releasedVersionNo - mini-user/h5-shop/h5-partner v3.4.13 UX fixes (store UI, iOS scan OAuth, partner login guard) - Docs: v3.4.13 dev doc + status audit updates Co-authored-by: Cursor <cursoragent@cursor.com>
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
export type SupportTicketStatus =
|
|
| 'PENDING_REVIEW'
|
|
| 'REJECTED'
|
|
| 'DEVELOPING'
|
|
| 'TESTING'
|
|
| 'PASSED'
|
|
| 'PUBLISHED';
|
|
|
|
export type SupportTicketStatusTransitionContext = {
|
|
linkedTaskCount: number;
|
|
isSuperAdmin: boolean;
|
|
rejectReason?: string;
|
|
};
|
|
|
|
const FORWARD_TRANSITIONS: Record<SupportTicketStatus, SupportTicketStatus[]> = {
|
|
PENDING_REVIEW: ['DEVELOPING', 'REJECTED'],
|
|
DEVELOPING: ['TESTING', 'REJECTED'],
|
|
TESTING: ['PASSED', 'REJECTED'],
|
|
REJECTED: [],
|
|
PASSED: ['PUBLISHED'],
|
|
PUBLISHED: [],
|
|
};
|
|
|
|
/** 技术支持工单批量/人工改状态校验(禁止回退) */
|
|
export function validateSupportTicketStatusTransition(
|
|
from: SupportTicketStatus,
|
|
to: SupportTicketStatus,
|
|
ctx: SupportTicketStatusTransitionContext,
|
|
): { ok: boolean; message?: string } {
|
|
if (from === to) return { ok: true };
|
|
|
|
const allowed = FORWARD_TRANSITIONS[from] ?? [];
|
|
if (!allowed.includes(to)) {
|
|
return { ok: false, message: `不允许从「${from}」变更为「${to}」` };
|
|
}
|
|
|
|
if (to === 'REJECTED') {
|
|
if (!ctx.isSuperAdmin) return { ok: false, message: '仅最高管理员可驳回工单' };
|
|
if (!ctx.rejectReason?.trim()) return { ok: false, message: '请填写驳回理由' };
|
|
}
|
|
|
|
if (from === 'PENDING_REVIEW' && to === 'DEVELOPING' && ctx.linkedTaskCount < 1) {
|
|
return { ok: false, message: '待评审工单转入开发须至少 1 条关联开发任务' };
|
|
}
|
|
|
|
return { ok: true };
|
|
}
|