8de41796fb
- maskPhone/maskContactPhone 支持座机(含区号/分机)脱敏展示,domain 补充单测 - 套餐「使用时间/其他说明」由单行 input 改为多行 textarea(admin/h5-partner/h5-shop) - 后台「套餐审核」标签文字恒为白色(不受 Badge 角标影响) - 新增 deploy/sync-prod-db-to-local.sh:线上库经 SSH 隧道同步至本地(含 @ 密码/base64 解析、--lock-tables=0 兼容受限账号) Co-Authored-By: WorkBuddy <workbuddy@tencent.com>
176 lines
4.9 KiB
TypeScript
176 lines
4.9 KiB
TypeScript
/** 与后端 PaginationQueryDto @Max(100) 一致,下拉选项拉取勿超过此值 */
|
||
export const ADMIN_OPTIONS_PAGE_SIZE = 100;
|
||
|
||
export const DELIVERY_PROVIDER_LABELS: Record<string, string> = {
|
||
XFX: '小飞侠',
|
||
LOGISTICS: '物流快递',
|
||
MANUAL: '手动',
|
||
};
|
||
|
||
export const ORDER_STATUS_LABELS: Record<string, string> = {
|
||
PENDING_PAY: '待付款',
|
||
PENDING_SHIP: '待发货',
|
||
OUT_WAREHOUSE: '已出库',
|
||
SHIPPING: '配送中',
|
||
PENDING_RECEIVE: '待收货',
|
||
COMPLETED: '已完成',
|
||
CANCELLED: '已取消',
|
||
REFUNDING: '退款中',
|
||
REFUNDED: '已退款',
|
||
};
|
||
|
||
/** 订单状态流转操作人(common_event.param3) */
|
||
export const ORDER_STATUS_OPERATOR_LABELS: Record<string, string> = {
|
||
USER: '用户',
|
||
USER_ON_SITE: '用户·现场取货',
|
||
USER_WECHAT_CONFIRM: '用户·微信确认收货',
|
||
WECHAT_TRADE_MANAGE: '微信结算同步',
|
||
MOCK: 'Mock',
|
||
MOCK_PAY: 'Mock 支付',
|
||
SYSTEM: '系统',
|
||
};
|
||
|
||
/** 订单状态 Tag 颜色(Ant Design preset) */
|
||
export const ORDER_STATUS_COLORS: Record<string, string> = {
|
||
PENDING_PAY: 'red',
|
||
PENDING_SHIP: 'green',
|
||
OUT_WAREHOUSE: 'green',
|
||
SHIPPING: 'processing',
|
||
PENDING_RECEIVE: 'cyan',
|
||
COMPLETED: 'green',
|
||
CANCELLED: 'default',
|
||
REFUNDING: 'orange',
|
||
REFUNDED: 'default',
|
||
};
|
||
|
||
export const STORE_STATUS_LABELS: Record<string, string> = {
|
||
OPEN: '营业中',
|
||
PAUSED: '临时闭店',
|
||
CLOSED: '永久关闭',
|
||
};
|
||
|
||
export const STORE_AUDIT_STATUS_LABELS: Record<string, string> = {
|
||
PENDING: '待审核',
|
||
APPROVED: '已通过',
|
||
REJECTED: '已驳回',
|
||
};
|
||
|
||
export const ACCOUNT_STATUS_LABELS: Record<string, string> = {
|
||
ACTIVE: '正常',
|
||
DISABLED: '停用',
|
||
};
|
||
|
||
export const COUPON_STATUS_LABELS: Record<string, string> = {
|
||
ACTIVE: '可用',
|
||
USED_UP: '已用完',
|
||
VOID: '已作废',
|
||
};
|
||
|
||
export const CITY_STATUS_LABELS: Record<string, string> = {
|
||
PENDING: '待开城',
|
||
ACTIVE: '已开城',
|
||
PAUSED: '已暂停',
|
||
};
|
||
|
||
export const PARTNER_BILL_STATUS_LABELS: Record<string, string> = {
|
||
PENDING_REVIEW: '待审核',
|
||
AWAITING_CONFIRM: '待合伙人确认',
|
||
UNPAID: '未打款',
|
||
PAID: '已打款',
|
||
REJECTED: '已驳回',
|
||
};
|
||
|
||
export const MEDIA_TYPE_LABELS: Record<string, string> = {
|
||
IMAGE: '图片',
|
||
VIDEO: '视频',
|
||
FILE: '文件',
|
||
};
|
||
|
||
export const RESOURCE_OWNER_TYPE_LABELS: Record<string, string> = {
|
||
PRODUCT: '商品',
|
||
STORE: '门店',
|
||
PARTNER: '合伙人',
|
||
USER: '用户',
|
||
ORDER: '订单',
|
||
HQ: '总部',
|
||
};
|
||
|
||
export const RESOURCE_BIZ_TYPE_LABELS: Record<string, string> = {
|
||
COVER: '封面',
|
||
ENV: '环境图',
|
||
CONTRACT: '合同',
|
||
CAROUSEL: '轮播',
|
||
DETAIL: '详情',
|
||
AVATAR: '头像',
|
||
QRCODE: '二维码',
|
||
SIGN_PHOTO: '签收照',
|
||
VIDEO: '视频',
|
||
};
|
||
|
||
export const RESOURCE_STATUS_LABELS: Record<string, string> = {
|
||
ACTIVE: '有效',
|
||
DELETED: '已删除',
|
||
};
|
||
|
||
export const PRODUCT_STATUS_LABELS: Record<string, string> = {
|
||
DRAFT: '草稿',
|
||
ON_SALE: '在售',
|
||
OFF_SALE: '下架',
|
||
};
|
||
|
||
export const AROMA_TYPE_LABELS: Record<string, string> = {
|
||
QINGXIANG: '清香型',
|
||
JIANGXIANG: '酱香型',
|
||
NONGXIANG: '浓香型',
|
||
};
|
||
|
||
export const DETAIL_TEMPLATE_STATUS_LABELS: Record<string, string> = {
|
||
ACTIVE: '启用',
|
||
DISABLED: '停用',
|
||
};
|
||
|
||
export const LEDGER_TYPE_LABELS: Record<string, string> = {
|
||
GRANT: '发放',
|
||
REDEEM: '核销',
|
||
REFUND_VOID: '退款作废',
|
||
ADJUST: '调整',
|
||
};
|
||
|
||
export function fmtTime(v?: string | null) {
|
||
return v ? new Date(v).toLocaleString('zh-CN') : '—';
|
||
}
|
||
|
||
/** 联系电话脱敏:手机 138****5678;座机 0379-****888;空值返回 — */
|
||
export function maskPhone(phone?: string | null): string {
|
||
const raw = String(phone ?? '').trim().replace(/\s+/g, '');
|
||
if (!raw) return '—';
|
||
if (/^1[3-9]\d{9}$/.test(raw)) {
|
||
const digits = raw.replace(/\D/g, '');
|
||
return `${digits.slice(0, 3)}****${digits.slice(-4)}`;
|
||
}
|
||
if (/^0\d{2,3}-?\d{7,8}(-\d{1,6})?$/.test(raw)) {
|
||
const extMatch = raw.match(/-(\d{1,6})$/);
|
||
const hasExt = !!extMatch && raw.indexOf('-') !== raw.lastIndexOf('-');
|
||
const ext = hasExt ? extMatch![1] : '';
|
||
const main = hasExt ? raw.slice(0, -(ext.length + 1)) : raw;
|
||
const digits = main.replace(/\D/g, '');
|
||
const areaLen = digits.startsWith('01') || digits.startsWith('02') ? 3 : 4;
|
||
const area = digits.slice(0, areaLen);
|
||
const local = digits.slice(areaLen);
|
||
const keepTail = Math.min(4, Math.max(2, local.length - 4));
|
||
const maskedLocal =
|
||
local.length <= 4 ? '*'.repeat(local.length) : `${'*'.repeat(local.length - keepTail)}${local.slice(-keepTail)}`;
|
||
const joiner = main.includes('-') ? '-' : '';
|
||
return ext ? `${area}${joiner}${maskedLocal}-${ext}` : `${area}${joiner}${maskedLocal}`;
|
||
}
|
||
const digits = raw.replace(/\D/g, '');
|
||
if (digits.length >= 11) {
|
||
return `${digits.slice(0, 3)}****${digits.slice(-4)}`;
|
||
}
|
||
if (digits.length >= 7) {
|
||
return `${digits.slice(0, 3)}****${digits.slice(-2)}`;
|
||
}
|
||
if (digits.length > 0) return `${digits.slice(0, 1)}****`;
|
||
return '****';
|
||
}
|