Some checks failed
Build and Deploy Front / deploy (push) Has been cancelled
同步 H5/登录回官网、仓库 PeekModal、运单状态展示与菜单图标目录。 Co-authored-by: Cursor <cursoragent@cursor.com>
298 lines
8.7 KiB
TypeScript
298 lines
8.7 KiB
TypeScript
/**
|
||
* 订单状态(与 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 }
|