Add product/channel billing condition editors, place-order additional services, billing simulator, forecast-to-inbound fee delta and margin warnings, insurance-aware claim tips, OMS preset dict seeds, and related AI skills/system pages. Co-authored-by: Cursor <cursoragent@cursor.com>
146 lines
4.5 KiB
TypeScript
146 lines
4.5 KiB
TypeScript
/**
|
||
* 列表状态标签:按信息强弱分档(低饱和墨色),对齐 OMS 主色 #007979。
|
||
*
|
||
* 强弱(弱 → 强):
|
||
* - mute 弱信息:否 / 关闭 / 删除 / 无效
|
||
* - neutral 基线:草稿 / 普通 / 未知
|
||
* - brand 流程推进:进行中 / 已启用
|
||
* - wait 待办提醒:待处理 / 待审核 / 预警中
|
||
* - ok 正向终态:成功 / 已完成
|
||
* - alert 负向终态:失败 / 问题 / 超时
|
||
* 布尔「是」单独用 BOOLEAN_YES_TAG 高亮绿,不走上述分档。
|
||
*/
|
||
export type StatusTagTone = 'mute' | 'neutral' | 'brand' | 'wait' | 'ok' | 'alert'
|
||
|
||
export interface StatusTagColors {
|
||
tagColor: string
|
||
tagBgColor: string
|
||
tagBorder: string
|
||
/** 可选行底 tint(极淡) */
|
||
rowBg?: string
|
||
}
|
||
|
||
export const STATUS_TAG_TONES: Record<StatusTagTone, StatusTagColors> = {
|
||
mute: {
|
||
tagColor: '#8b939b',
|
||
tagBgColor: '#f7f8f9',
|
||
tagBorder: '#e7e9eb',
|
||
},
|
||
neutral: {
|
||
tagColor: '#5c656d',
|
||
tagBgColor: '#f3f4f5',
|
||
tagBorder: '#e2e4e6',
|
||
},
|
||
brand: {
|
||
tagColor: '#1a6b6b',
|
||
tagBgColor: '#eef5f5',
|
||
tagBorder: '#d2e3e3',
|
||
},
|
||
wait: {
|
||
tagColor: '#7a6a52',
|
||
tagBgColor: '#f5f2ed',
|
||
tagBorder: '#e4ddd2',
|
||
rowBg: '#faf8f5',
|
||
},
|
||
ok: {
|
||
tagColor: '#456654',
|
||
tagBgColor: '#f0f4f1',
|
||
tagBorder: '#d6e0d9',
|
||
},
|
||
alert: {
|
||
tagColor: '#8a5c58',
|
||
tagBgColor: '#f5f0ef',
|
||
tagBorder: '#e4d9d7',
|
||
rowBg: '#faf6f5',
|
||
},
|
||
}
|
||
|
||
export function getStatusTagTone(tone: StatusTagTone): StatusTagColors {
|
||
return STATUS_TAG_TONES[tone]
|
||
}
|
||
|
||
export type StatusTagVariant = 'solid' | 'ghost'
|
||
|
||
function escapeAttr(text: string): string {
|
||
return String(text)
|
||
.replace(/&/g, '&')
|
||
.replace(/</g, '<')
|
||
.replace(/>/g, '>')
|
||
.replace(/"/g, '"')
|
||
}
|
||
|
||
/** Vue / a-tag 内联样式 */
|
||
export function getStatusTagStyle(
|
||
toneOrColors: StatusTagTone | StatusTagColors | null | undefined,
|
||
variant: StatusTagVariant = 'solid',
|
||
): Record<string, string> {
|
||
const colors =
|
||
!toneOrColors
|
||
? STATUS_TAG_TONES.neutral
|
||
: typeof toneOrColors === 'string'
|
||
? STATUS_TAG_TONES[toneOrColors]
|
||
: toneOrColors
|
||
if (variant === 'ghost') {
|
||
return {
|
||
color: colors.tagColor,
|
||
background: 'transparent',
|
||
border: `1px solid ${colors.tagBorder}`,
|
||
borderRadius: '3px',
|
||
fontWeight: '500',
|
||
}
|
||
}
|
||
return {
|
||
color: colors.tagColor,
|
||
background: colors.tagBgColor,
|
||
border: `1px solid ${colors.tagBorder}`,
|
||
borderRadius: '3px',
|
||
fontWeight: '500',
|
||
}
|
||
}
|
||
|
||
/** Handsontable 单元格 HTML */
|
||
export function buildStatusTagHtml(
|
||
text: string,
|
||
toneOrColors: StatusTagTone | StatusTagColors | null | undefined = 'neutral',
|
||
variant: StatusTagVariant = 'solid',
|
||
): string {
|
||
const colors =
|
||
!toneOrColors
|
||
? STATUS_TAG_TONES.neutral
|
||
: typeof toneOrColors === 'string'
|
||
? STATUS_TAG_TONES[toneOrColors]
|
||
: toneOrColors
|
||
const safe = escapeAttr(text)
|
||
if (variant === 'ghost') {
|
||
return `<span style="display:inline-flex;align-items:center;height:20px;padding:0 6px;border-radius:3px;font-size:11px;font-weight:500;line-height:18px;color:${colors.tagColor};background:transparent;border:1px solid ${colors.tagBorder};white-space:nowrap;">${safe}</span>`
|
||
}
|
||
return `<span style="display:inline-flex;align-items:center;height:22px;padding:0 8px;border-radius:3px;font-size:12px;font-weight:500;line-height:20px;letter-spacing:0.02em;color:${colors.tagColor};background:${colors.tagBgColor};border:1px solid ${colors.tagBorder};white-space:nowrap;">${safe}</span>`
|
||
}
|
||
|
||
/** 布尔「是」专用高亮绿(比状态档 ok 更醒目) */
|
||
export const BOOLEAN_YES_TAG: StatusTagColors = {
|
||
tagColor: '#1a7f37',
|
||
tagBgColor: '#e6f7eb',
|
||
tagBorder: '#a8d9b5',
|
||
}
|
||
|
||
/** 布尔:是 → 高亮绿,否 → mute(弱信息) */
|
||
export function buildBooleanTagHtml(text: string, positive: boolean): string {
|
||
return buildStatusTagHtml(text, positive ? BOOLEAN_YES_TAG : 'mute')
|
||
}
|
||
|
||
/** Vue / a-tag:布尔列样式 */
|
||
export function getBooleanTagStyle(positive: boolean): Record<string, string> {
|
||
return getStatusTagStyle(positive ? BOOLEAN_YES_TAG : 'mute')
|
||
}
|
||
|
||
/** 金额正负:仅改文字色,不做标签(避免抢状态列) */
|
||
export function getMoneyToneColor(positive: boolean): string {
|
||
return positive ? STATUS_TAG_TONES.ok.tagColor : STATUS_TAG_TONES.alert.tagColor
|
||
}
|
||
|
||
/** 强调文字色(超时/预警行内数字等) */
|
||
export function getEmphasisTextColor(tone: StatusTagTone = 'alert'): string {
|
||
return STATUS_TAG_TONES[tone].tagColor
|
||
}
|