front/src/constants/orderStatus.ts
zzh eb12f9fb9e
Some checks failed
Build and Deploy Front / deploy (push) Has been cancelled
feat: 官网手机端适配、EventBus 菜单与图标扩展
同步 H5/登录回官网、仓库 PeekModal、运单状态展示与菜单图标目录。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-27 15:11:57 +08:00

298 lines
8.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 订单状态(与 oms0414-back OrderStatusCodes、设计文档 §10.3.1 一致)
*
* 标签色系:按生命周期语义分色;渲染仍走 utils/statusTag。
*/
import {
STATUS_TAG_TONES,
buildBooleanTagHtml,
buildStatusTagHtml,
getStatusTagStyle,
type StatusTagTone,
} from '@/utils/statusTag'
export const ORDER_STATUS_ALL = 'all' as const
/** @deprecated 历史值 received 已废弃,见 normalizeOrderStatusCode */
export const ORDER_STATUS_LEGACY_RECEIVED = 'received' as const
export type OrderStatusCode =
| typeof ORDER_STATUS_ALL
| 'draft'
| 'predeclared'
| 'pendingAllocation'
| 'pendingPayment'
| 'pendingShip'
| 'pendingOnline'
| 'shipping'
| 'deliverySuccess'
| 'deliveryFailed'
| 'problematic'
| 'deleted'
| 'claimed'
/** @deprecated 使用 StatusTagTone;保留别名兼容 */
export type OrderStatusTagTone = StatusTagTone
/** @deprecated 使用 STATUS_TAG_TONES */
export const ORDER_STATUS_TAG_TONES = STATUS_TAG_TONES
/** 允许删除的订单状态:草稿、已预报 */
export const ORDER_DELETABLE_STATUSES: readonly OrderStatusCode[] = ['draft', 'predeclared']
export function isOrderDeletable(status: unknown): boolean {
const code = normalizeOrderStatusCode(typeof status === 'string' ? status.trim() : '')
return ORDER_DELETABLE_STATUSES.includes(code as OrderStatusCode)
}
export interface OrderStatusMeta {
value: OrderStatusCode
/** i18n key:tabs.* 与 status.* 共用同一套文案 */
labelKey: string
tagColor?: string
tagBgColor?: string
tagBorder?: string
/** 表格行背景(极淡,仅待办/异常) */
rowBg?: string
/** Tab 是否展示数量 */
showTabCount?: boolean
}
/** 历史 received 归并为待排货(入库后不再停留已收货) */
export function normalizeOrderStatusCode(code: string): string {
return code === ORDER_STATUS_LEGACY_RECEIVED ? 'pendingAllocation' : code
}
/** 后端返回的中文状态名 → code(OmsDocHelper.GetOrderStatusName) */
export const ORDER_STATUS_NAME_TO_CODE: Record<string, OrderStatusCode> = {
草稿: 'draft',
已预报: 'predeclared',
已收货: 'pendingAllocation',
待排货: 'pendingAllocation',
待支付: 'pendingPayment',
待发货: 'pendingShip',
待上网: 'pendingOnline',
运输中: 'shipping',
派送成功: 'deliverySuccess',
派送失败: 'deliveryFailed',
问题件: 'problematic',
已删除: 'deleted',
理赔件: 'claimed',
已理赔: 'claimed',
已认领: 'claimed',
}
/**
* 订单状态标签色:按生命周期语义分色(软底标签),便于列表一眼区分。
* 待办暖色 / 在途品牌色 / 成功绿 / 失败红 / 问题橙 / 理赔紫。
*/
export const ORDER_STATUS_LIST: OrderStatusMeta[] = [
{
value: 'draft',
labelKey: 'order.myOrders.status.draft',
tagColor: '#6b7280',
tagBgColor: '#f3f4f6',
tagBorder: '#e5e7eb',
},
{
value: 'predeclared',
labelKey: 'order.myOrders.status.predeclared',
tagColor: '#3d6a8a',
tagBgColor: '#eef4f8',
tagBorder: '#d0dee8',
},
{
value: 'pendingAllocation',
labelKey: 'order.myOrders.status.pendingAllocation',
tagColor: '#8a6d3b',
tagBgColor: '#f7f2e8',
tagBorder: '#e8dcc6',
rowBg: '#faf8f5',
showTabCount: true,
},
{
value: 'pendingPayment',
labelKey: 'order.myOrders.status.pendingPayment',
tagColor: '#ea580c',
tagBgColor: '#fff4e5',
tagBorder: '#fb923c',
rowBg: '#fff7ed',
showTabCount: true,
},
{
value: 'pendingShip',
labelKey: 'order.myOrders.status.pendingShip',
tagColor: '#0f766e',
tagBgColor: '#f0fdfa',
tagBorder: '#99f6e4',
showTabCount: true,
},
{
value: 'pendingOnline',
labelKey: 'order.myOrders.status.pendingOnline',
tagColor: '#1d4ed8',
tagBgColor: '#eff6ff',
tagBorder: '#bfdbfe',
showTabCount: true,
},
{
value: 'shipping',
labelKey: 'order.myOrders.status.shipping',
tagColor: '#054f74',
tagBgColor: '#eef3f6',
tagBorder: '#b6cdd9',
showTabCount: true,
},
{
value: 'deliverySuccess',
labelKey: 'order.myOrders.status.deliverySuccess',
tagColor: '#15803d',
tagBgColor: '#f0fdf4',
tagBorder: '#bbf7d0',
showTabCount: true,
},
{
value: 'deliveryFailed',
labelKey: 'order.myOrders.status.deliveryFailed',
tagColor: '#b91c1c',
tagBgColor: '#fef2f2',
tagBorder: '#fecaca',
showTabCount: true,
},
{
value: 'deleted',
labelKey: 'order.myOrders.status.deleted',
tagColor: '#9ca3af',
tagBgColor: '#f9fafb',
tagBorder: '#e5e7eb',
},
{
value: 'problematic',
labelKey: 'order.myOrders.status.problematic',
tagColor: '#c2410c',
tagBgColor: '#fff7ed',
tagBorder: '#fdba74',
rowBg: '#fff7ed',
showTabCount: true,
},
{
value: 'claimed',
labelKey: 'order.myOrders.status.claimed',
tagColor: '#6d28d9',
tagBgColor: '#f5f3ff',
tagBorder: '#ddd6fe',
},
]
/** 已出库/在途及之后(不可拦截) */
export const ORDER_SHIPPED_STATUSES: readonly OrderStatusCode[] = [
'pendingOnline',
'shipping',
'deliverySuccess',
'deliveryFailed',
]
/**
* 出库后可人工校正的状态集合。
* 规则:四态互改;派送成功只进不出(见 getPostShipStatusChangeTargets)。
*/
export const ORDER_POST_SHIP_CHANGEABLE_STATUSES: readonly OrderStatusCode[] = [
'pendingOnline',
'shipping',
'deliverySuccess',
'deliveryFailed',
]
/** 当前状态允许改到的目标(派送成功返回空) */
export function getPostShipStatusChangeTargets(fromStatus: unknown): OrderStatusCode[] {
const code = normalizeOrderStatusCode(
typeof fromStatus === 'string' ? fromStatus.trim() : resolveOrderStatusCode(fromStatus as any),
) as OrderStatusCode
if (!ORDER_POST_SHIP_CHANGEABLE_STATUSES.includes(code)) return []
if (code === 'deliverySuccess') return []
return ORDER_POST_SHIP_CHANGEABLE_STATUSES.filter((s) => s !== code)
}
const ORDER_SHIPPED_STATUS_SET = new Set<string>(ORDER_SHIPPED_STATUSES)
/** 未发货:待上网之前的状态均可尝试拦截/取消拦截 */
export function isOrderNotShipped(
statusOrRow?: string | { status?: string; Status?: string; orderStatus?: string; OrderStatus?: string },
): boolean {
const code =
typeof statusOrRow === 'string'
? normalizeOrderStatusCode(statusOrRow.trim())
: resolveOrderStatusCode(statusOrRow)
if (!code || code === ORDER_STATUS_ALL) return false
return !ORDER_SHIPPED_STATUS_SET.has(code)
}
const ORDER_STATUS_BY_CODE = new Map(ORDER_STATUS_LIST.map((item) => [item.value, item]))
/** 我的订单 Tab:全部 + 各业务状态 */
export const ORDER_STATUS_TABS: OrderStatusMeta[] = [
{ value: ORDER_STATUS_ALL, labelKey: 'order.myOrders.tabs.all', showTabCount: true },
...ORDER_STATUS_LIST.map(({ value, tagColor, tagBgColor, tagBorder, rowBg, showTabCount }) => ({
value,
labelKey: `order.myOrders.tabs.${value}`,
tagColor,
tagBgColor,
tagBorder,
rowBg,
showTabCount: showTabCount ?? true,
})),
]
export function resolveOrderStatusCode(row?: {
status?: string
Status?: string
orderStatus?: string
OrderStatus?: string
}): string {
if (!row) return ''
const rawCode = normalizeOrderStatusCode(String(row.status ?? row.Status ?? '').trim())
if (rawCode && ORDER_STATUS_BY_CODE.has(rawCode as OrderStatusCode)) {
return rawCode
}
const rawName = String(row.orderStatus ?? row.OrderStatus ?? '').trim()
if (rawName && ORDER_STATUS_NAME_TO_CODE[rawName]) {
return ORDER_STATUS_NAME_TO_CODE[rawName]
}
if (rawName && ORDER_STATUS_BY_CODE.has(rawName as OrderStatusCode)) {
return rawName
}
return rawCode || rawName
}
export function getOrderStatusMeta(codeOrName?: string): OrderStatusMeta | undefined {
if (!codeOrName) return undefined
const normalized = normalizeOrderStatusCode(String(codeOrName).trim())
if (ORDER_STATUS_BY_CODE.has(normalized as OrderStatusCode)) {
return ORDER_STATUS_BY_CODE.get(normalized as OrderStatusCode)
}
const code = ORDER_STATUS_NAME_TO_CODE[codeOrName]
return code ? ORDER_STATUS_BY_CODE.get(code) : undefined
}
export function getOrderStatusTagStyle(
meta?: Pick<OrderStatusMeta, 'tagColor' | 'tagBgColor' | 'tagBorder'> | null,
): Record<string, string> {
return getStatusTagStyle(meta ?? undefined)
}
export function buildOrderStatusTagHtml(
text: string,
meta?: Pick<OrderStatusMeta, 'tagColor' | 'tagBgColor' | 'tagBorder'> | null,
): string {
return buildStatusTagHtml(text, meta ?? undefined)
}
export function buildOrderStatusSubTagHtml(
text: string,
meta?: { tagColor?: string; tagBgColor?: string; tagBorder?: string } | null,
): string {
return buildStatusTagHtml(text, meta ?? undefined, 'ghost')
}
export { buildBooleanTagHtml }