feat(studio-ds-polish): 品牌→绘境AI + 3 helper 标签 i18n + 裸令牌收口
- 对外品牌 common.brand: 造梦AI→绘境AI / ZaoMeng AI→Huijing AI(创始人拍板 huijing) - helper i18n: status.ts/msg-type.ts/biz-meta.ts 的 label→labelKey(common.projectStatus/msgType/bizStatus/bizType),状态徽章/消息类型/biz 标签英文态也翻译;8 消费方包 t()(13 处) - 裸旧令牌收口: var(--cyan/--green/--amber)→--accent/--success/--warning(严格等值,零视觉变化) - 逻辑/契约枚举键/color/查找语义零改 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
96081a574c
commit
2c96e63a5f
@ -117,8 +117,8 @@ function onClick(ev: MouseEvent) {
|
||||
/* ghost 透明描边青 */
|
||||
.app-btn--ghost {
|
||||
background: transparent;
|
||||
color: var(--cyan);
|
||||
border: 1px solid var(--cyan);
|
||||
color: var(--accent);
|
||||
border: 1px solid var(--accent);
|
||||
}
|
||||
/* danger 危险 */
|
||||
.app-btn--danger {
|
||||
|
||||
@ -81,8 +81,8 @@ const emit = defineEmits<{ (e: 'action'): void }>()
|
||||
padding: 0 18px;
|
||||
border-radius: var(--radius);
|
||||
background: transparent;
|
||||
border: 1px solid var(--cyan);
|
||||
color: var(--cyan);
|
||||
border: 1px solid var(--accent);
|
||||
color: var(--accent);
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -13,7 +13,7 @@ const props = withDefaults(
|
||||
percent?: number
|
||||
/** 不确定进度(无法预估时的滑动动画) */
|
||||
indeterminate?: boolean
|
||||
/** 进度条颜色(默认 cyan,可传 token 变量名对应色,如 var(--amber)) */
|
||||
/** 进度条颜色(默认 accent,可传 token 变量名对应色,如 var(--warning)) */
|
||||
color?: string
|
||||
/** 是否在右侧显示百分比文字 */
|
||||
showText?: boolean
|
||||
@ -21,7 +21,7 @@ const props = withDefaults(
|
||||
{
|
||||
percent: 0,
|
||||
indeterminate: false,
|
||||
color: 'var(--cyan)',
|
||||
color: 'var(--accent)',
|
||||
showText: false,
|
||||
},
|
||||
)
|
||||
|
||||
@ -36,8 +36,8 @@ const fullPath = computed(() => route.fullPath)
|
||||
}
|
||||
.placeholder__badge {
|
||||
font-size: 12px;
|
||||
color: var(--cyan);
|
||||
border: 1px solid var(--cyan);
|
||||
color: var(--accent);
|
||||
border: 1px solid var(--accent);
|
||||
border-radius: var(--radius);
|
||||
padding: 3px 10px;
|
||||
}
|
||||
|
||||
@ -3,11 +3,19 @@
|
||||
*/
|
||||
export default {
|
||||
common: {
|
||||
brand: 'ZaoMeng AI',
|
||||
brand: 'Huijing AI',
|
||||
nav: { feed: 'Feed', create: 'Create', message: 'Inbox', me: 'Me', discover: 'Discover' },
|
||||
action: { play: 'Play now', share: 'Share', save: 'Save', submit: 'Submit', cancel: 'Cancel', confirm: 'Confirm', back: 'Back', retry: 'Retry', more: 'More', prev: 'Previous', next: 'Next' },
|
||||
state: { loading: 'Loading', empty: 'Nothing here yet', saved: 'Saved', failed: 'Failed', success: 'Success' },
|
||||
status: { draft: 'Draft', review: 'In review', published: 'Published', rejected: 'Rejected' },
|
||||
// 项目状态机文案(与 zh-CN 同构:s0..s6 贴契约 0-6,unknown=越界兜底,all=「全部」)
|
||||
projectStatus: { s0: 'Draft', s1: 'In review', s2: 'Approved', s3: 'Rejected', s4: 'Published', s5: 'Removed', s6: 'Banned', unknown: 'Unknown', all: 'All' },
|
||||
// 站内消息类型文案(与 zh-CN 同构:t1..t4 贴契约 1-4,fallback=越界兜底,all=「全部」)
|
||||
msgType: { t1: 'System', t2: 'Announcement', t3: 'Review', t4: 'Earnings', all: 'All', fallback: 'Message' },
|
||||
// biz 询单状态文案(与 zh-CN 同构:s0..s4 贴契约 0-4,unknown=越界兜底,all=「全部」)
|
||||
bizStatus: { s0: 'Following up', s1: 'Quoted', s2: 'In production', s3: 'Acceptance', s4: 'Delivered', all: 'All', unknown: 'Unknown' },
|
||||
// biz 场景类型文案(与 zh-CN 同构:t1..t3 贴契约 1-3,fallback=越界兜底)
|
||||
bizType: { t1: 'Brand marketing', t2: 'Tourism', t3: 'Custom', fallback: 'Custom' },
|
||||
},
|
||||
appearance: {
|
||||
title: 'Appearance',
|
||||
|
||||
@ -4,11 +4,19 @@
|
||||
*/
|
||||
export default {
|
||||
common: {
|
||||
brand: '造梦AI',
|
||||
brand: '绘境AI',
|
||||
nav: { feed: '游戏流', create: '创作', message: '消息', me: '我的', discover: '发现' },
|
||||
action: { play: '立即玩', share: '分享', save: '保存', submit: '提交', cancel: '取消', confirm: '确定', back: '返回', retry: '重试', more: '更多', prev: '上一个', next: '下一个' },
|
||||
state: { loading: '加载中', empty: '这里还没有内容', saved: '已保存', failed: '失败', success: '成功' },
|
||||
status: { draft: '草稿', review: '审核中', published: '已发布', rejected: '已驳回' },
|
||||
// 项目状态机文案(贴契约 ProjectRespVO.status 0-6;s0..s6 对应数字键,unknown=越界兜底,all=筛选「全部」)
|
||||
projectStatus: { s0: '草稿', s1: '审核中', s2: '已通过', s3: '已拒绝', s4: '已发布', s5: '已下架', s6: '已封禁', unknown: '未知', all: '全部' },
|
||||
// 站内消息类型文案(贴契约 CommunityMessageRespVO.type 1-4;t1..t4 对应数字键,fallback=越界兜底,all=筛选「全部」)
|
||||
msgType: { t1: '系统', t2: '公告', t3: '审核', t4: '收益', all: '全部', fallback: '消息' },
|
||||
// biz 询单状态文案(贴契约 game_biz_lead.status 0-4;s0..s4 对应数字键,unknown=越界兜底,all=筛选「全部」)
|
||||
bizStatus: { s0: '待跟进', s1: '已报价', s2: '制作中', s3: '待验收', s4: '已交付', all: '全部', unknown: '未知' },
|
||||
// biz 场景类型文案(贴契约 bizType 1-3;t1..t3 对应数字键,fallback=越界兜底)
|
||||
bizType: { t1: '品牌营销', t2: '文旅', t3: '通用定制', fallback: '定制' },
|
||||
},
|
||||
appearance: {
|
||||
title: '外观',
|
||||
|
||||
@ -134,7 +134,7 @@ function goBack() {
|
||||
:class="{ 'is-active': form.bizType === opt.value }"
|
||||
@click="pickType(opt.value)"
|
||||
>
|
||||
{{ opt.label }}
|
||||
{{ t(opt.labelKey) }}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -169,7 +169,7 @@ onMounted(fetchDetail)
|
||||
class="biz-detail__badge"
|
||||
:style="{ color: getBizStatusMeta(lead.status).color, borderColor: getBizStatusMeta(lead.status).color }"
|
||||
>
|
||||
{{ getBizStatusMeta(lead.status).label }}
|
||||
{{ t(getBizStatusMeta(lead.status).labelKey) }}
|
||||
</span>
|
||||
</header>
|
||||
|
||||
@ -194,7 +194,7 @@ onMounted(fetchDetail)
|
||||
<section class="biz-detail__overview">
|
||||
<h2 class="biz-detail__lead-title">{{ lead.title }}</h2>
|
||||
<p class="biz-detail__meta">
|
||||
<span class="biz-detail__type">{{ getBizTypeLabel(lead.bizType) }}</span>
|
||||
<span class="biz-detail__type">{{ t(getBizTypeLabel(lead.bizType)) }}</span>
|
||||
<span class="biz-detail__time">{{ t('bizDetail.submittedAt', { time: formatTime(lead.createTime) }) }}</span>
|
||||
</p>
|
||||
</section>
|
||||
@ -286,7 +286,7 @@ onMounted(fetchDetail)
|
||||
class="timeline__status"
|
||||
:style="{ color: getBizStatusMeta(p.toStatus).color }"
|
||||
>
|
||||
{{ getBizStatusMeta(p.toStatus).label }}
|
||||
{{ t(getBizStatusMeta(p.toStatus).labelKey) }}
|
||||
</span>
|
||||
<span class="timeline__time">{{ formatTime(p.createTime) }}</span>
|
||||
</div>
|
||||
|
||||
@ -96,7 +96,7 @@ onBeforeUnmount(() => {
|
||||
:class="{ 'is-active': activeStatus === f.value }"
|
||||
@click="onSwitchStatus(f.value)"
|
||||
>
|
||||
{{ f.label }}
|
||||
{{ t(f.labelKey) }}
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
@ -133,11 +133,11 @@ onBeforeUnmount(() => {
|
||||
class="biz-card__badge"
|
||||
:style="{ color: getBizStatusMeta(lead.status).color, borderColor: getBizStatusMeta(lead.status).color }"
|
||||
>
|
||||
{{ getBizStatusMeta(lead.status).label }}
|
||||
{{ t(getBizStatusMeta(lead.status).labelKey) }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="biz-card__sub">
|
||||
<span class="biz-card__type">{{ getBizTypeLabel(lead.bizType) }}</span>
|
||||
<span class="biz-card__type">{{ t(getBizTypeLabel(lead.bizType)) }}</span>
|
||||
<span v-if="lead.createTime" class="biz-card__time">{{ formatTime(lead.createTime) }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -58,7 +58,7 @@ function pick(templateId: string) {
|
||||
|
||||
<template>
|
||||
<div class="tpl-picker">
|
||||
<p class="tpl-picker__hint">{{ t('bizPicker.hint', { scene: getBizTypeLabel(bizType) }) }}</p>
|
||||
<p class="tpl-picker__hint">{{ t('bizPicker.hint', { scene: t(getBizTypeLabel(bizType)) }) }}</p>
|
||||
|
||||
<!-- 加载中 -->
|
||||
<div v-if="templatesLoading" class="tpl-picker__loading">
|
||||
|
||||
@ -6,29 +6,29 @@
|
||||
* - bizType:1品牌营销 / 2文旅 / 3通用定制
|
||||
* 与 src/api/types.ts 的 BizLeadStatus / BizType 联合类型严格对齐,禁止发明契约外值。
|
||||
*
|
||||
* 颜色映射 D4 token:待跟进 muted / 已报价 cyan / 制作中 amber / 待验收 violet / 已交付 green。
|
||||
* 颜色映射 D4 token:待跟进 muted / 已报价 accent / 制作中 warning / 待验收 violet / 已交付 success。
|
||||
*/
|
||||
import type { BizLeadStatus, BizType } from '../../api/types'
|
||||
|
||||
/** 单个状态的展示配置 */
|
||||
export interface BizStatusMeta {
|
||||
/** 徽标文案 */
|
||||
label: string
|
||||
/** 徽标文案 i18n key(common.bizStatus.*,消费方 t() 取译文) */
|
||||
labelKey: string
|
||||
/** D4 token 颜色变量名(CSS var()) */
|
||||
color: string
|
||||
}
|
||||
|
||||
/** 状态 → 展示元数据(覆盖全部 5 态;getBizStatusMeta 对越界兜底) */
|
||||
export const BIZ_STATUS_META: Record<BizLeadStatus, BizStatusMeta> = {
|
||||
0: { label: '待跟进', color: 'var(--muted)' },
|
||||
1: { label: '已报价', color: 'var(--cyan)' },
|
||||
2: { label: '制作中', color: 'var(--amber)' },
|
||||
3: { label: '待验收', color: 'var(--violet)' },
|
||||
4: { label: '已交付', color: 'var(--green)' },
|
||||
0: { labelKey: 'common.bizStatus.s0', color: 'var(--muted)' },
|
||||
1: { labelKey: 'common.bizStatus.s1', color: 'var(--accent)' },
|
||||
2: { labelKey: 'common.bizStatus.s2', color: 'var(--warning)' },
|
||||
3: { labelKey: 'common.bizStatus.s3', color: 'var(--violet)' },
|
||||
4: { labelKey: 'common.bizStatus.s4', color: 'var(--success)' },
|
||||
}
|
||||
|
||||
/** 默认兜底(遇契约外未知状态时使用,保证 UI 不崩) */
|
||||
const FALLBACK_STATUS: BizStatusMeta = { label: '未知', color: 'var(--muted)' }
|
||||
const FALLBACK_STATUS: BizStatusMeta = { labelKey: 'common.bizStatus.unknown', color: 'var(--muted)' }
|
||||
|
||||
/**
|
||||
* 按状态取展示元数据(含越界兜底)。
|
||||
@ -39,34 +39,34 @@ export function getBizStatusMeta(status: number | undefined): BizStatusMeta {
|
||||
return BIZ_STATUS_META[status as BizLeadStatus] ?? FALLBACK_STATUS
|
||||
}
|
||||
|
||||
/** 场景(bizType)→ 中文标签 */
|
||||
/** 场景(bizType)→ i18n key(common.bizType.*,消费方 t() 取译文) */
|
||||
export const BIZ_TYPE_LABEL: Record<BizType, string> = {
|
||||
1: '品牌营销',
|
||||
2: '文旅',
|
||||
3: '通用定制',
|
||||
1: 'common.bizType.t1',
|
||||
2: 'common.bizType.t2',
|
||||
3: 'common.bizType.t3',
|
||||
}
|
||||
|
||||
/** 按场景取标签(含兜底) */
|
||||
/** 按场景取标签 i18n key(含兜底;消费方需 t() 包裹取译文) */
|
||||
export function getBizTypeLabel(bizType: number | undefined): string {
|
||||
if (bizType === undefined) return '定制'
|
||||
return BIZ_TYPE_LABEL[bizType as BizType] ?? '定制'
|
||||
if (bizType === undefined) return 'common.bizType.fallback'
|
||||
return BIZ_TYPE_LABEL[bizType as BizType] ?? 'common.bizType.fallback'
|
||||
}
|
||||
|
||||
/** 场景下拉选项(提单表单 + 模板库筛选用;不含「全部」,提单必选其一) */
|
||||
export const BIZ_TYPE_OPTIONS: Array<{ label: string; value: BizType }> = [
|
||||
{ label: '品牌营销', value: 1 },
|
||||
{ label: '文旅', value: 2 },
|
||||
{ label: '通用定制', value: 3 },
|
||||
export const BIZ_TYPE_OPTIONS: Array<{ labelKey: string; value: BizType }> = [
|
||||
{ labelKey: 'common.bizType.t1', value: 1 },
|
||||
{ labelKey: 'common.bizType.t2', value: 2 },
|
||||
{ labelKey: 'common.bizType.t3', value: 3 },
|
||||
]
|
||||
|
||||
/** 我的订单列表状态筛选项(含「全部」;value=undefined 不筛选) */
|
||||
export const BIZ_STATUS_FILTERS: Array<{ label: string; value: BizLeadStatus | undefined }> = [
|
||||
{ label: '全部', value: undefined },
|
||||
{ label: '待跟进', value: 0 },
|
||||
{ label: '已报价', value: 1 },
|
||||
{ label: '制作中', value: 2 },
|
||||
{ label: '待验收', value: 3 },
|
||||
{ label: '已交付', value: 4 },
|
||||
export const BIZ_STATUS_FILTERS: Array<{ labelKey: string; value: BizLeadStatus | undefined }> = [
|
||||
{ labelKey: 'common.bizStatus.all', value: undefined },
|
||||
{ labelKey: 'common.bizStatus.s0', value: 0 },
|
||||
{ labelKey: 'common.bizStatus.s1', value: 1 },
|
||||
{ labelKey: 'common.bizStatus.s2', value: 2 },
|
||||
{ labelKey: 'common.bizStatus.s3', value: 3 },
|
||||
{ labelKey: 'common.bizStatus.s4', value: 4 },
|
||||
]
|
||||
|
||||
/**
|
||||
|
||||
@ -152,7 +152,7 @@ onMounted(() => {
|
||||
:class="{ 'is-active': activeType === f.value }"
|
||||
@click="onSwitchType(f.value)"
|
||||
>
|
||||
{{ f.label }}
|
||||
{{ t(f.labelKey) }}
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
@ -191,7 +191,7 @@ onMounted(() => {
|
||||
<div class="msg-card__row">
|
||||
<h3 class="msg-card__title">{{ m.title }}</h3>
|
||||
<span class="msg-card__type" :style="{ color: getMsgTypeMeta(m.type).color }">
|
||||
{{ getMsgTypeMeta(m.type).label }}
|
||||
{{ t(getMsgTypeMeta(m.type).labelKey) }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="msg-card__content">{{ m.content }}</p>
|
||||
|
||||
@ -6,14 +6,14 @@
|
||||
* 与 src/api/types.ts 的 CommunityMsgType 联合类型严格对齐,禁止发明契约外类型值。
|
||||
*
|
||||
* 颜色映射 D4 token(与项目内既有语义就近一致):
|
||||
* 系统 cyan(中性强调)/ 公告 violet(辅助强调)/ 审核 amber(进行/提示)/ 收益 green(正向)。
|
||||
* 系统 accent(中性强调)/ 公告 violet(辅助强调)/ 审核 warning(进行/提示)/ 收益 success(正向)。
|
||||
*/
|
||||
import type { CommunityMsgType } from '../../api/types'
|
||||
|
||||
/** 单个消息类型的展示配置 */
|
||||
export interface MsgTypeMeta {
|
||||
/** 类型文案 */
|
||||
label: string
|
||||
/** 类型文案 i18n key(common.msgType.*,消费方 t() 取译文) */
|
||||
labelKey: string
|
||||
/** 图标字符(与 TabBar/EmptyState 同走符号风,离线无依赖) */
|
||||
icon: string
|
||||
/** D4 token 颜色变量(CSS var(),用于图标/标签) */
|
||||
@ -22,14 +22,14 @@ export interface MsgTypeMeta {
|
||||
|
||||
/** 类型 → 展示元数据映射表(覆盖契约 4 类) */
|
||||
export const MSG_TYPE_META: Record<CommunityMsgType, MsgTypeMeta> = {
|
||||
1: { label: '系统', icon: '⚙', color: 'var(--cyan)' },
|
||||
2: { label: '公告', icon: '◈', color: 'var(--violet)' },
|
||||
3: { label: '审核', icon: '✓', color: 'var(--amber)' },
|
||||
4: { label: '收益', icon: '¥', color: 'var(--green)' },
|
||||
1: { labelKey: 'common.msgType.t1', icon: '⚙', color: 'var(--accent)' },
|
||||
2: { labelKey: 'common.msgType.t2', icon: '◈', color: 'var(--violet)' },
|
||||
3: { labelKey: 'common.msgType.t3', icon: '✓', color: 'var(--warning)' },
|
||||
4: { labelKey: 'common.msgType.t4', icon: '¥', color: 'var(--success)' },
|
||||
}
|
||||
|
||||
/** 默认兜底(遇契约外未知类型值时使用,保证 UI 不崩) */
|
||||
const FALLBACK_META: MsgTypeMeta = { label: '消息', icon: '✦', color: 'var(--muted)' }
|
||||
const FALLBACK_META: MsgTypeMeta = { labelKey: 'common.msgType.fallback', icon: '✦', color: 'var(--muted)' }
|
||||
|
||||
/**
|
||||
* 按类型取展示元数据(含越界兜底)。
|
||||
@ -44,10 +44,10 @@ export function getMsgTypeMeta(type: number | undefined): MsgTypeMeta {
|
||||
* 消息中心顶部类型筛选项(含「全部」)。
|
||||
* value=undefined 表示不筛选(取全部);其余对齐契约 4 类。
|
||||
*/
|
||||
export const MSG_TYPE_FILTERS: Array<{ label: string; value: CommunityMsgType | undefined }> = [
|
||||
{ label: '全部', value: undefined },
|
||||
{ label: '系统', value: 1 },
|
||||
{ label: '公告', value: 2 },
|
||||
{ label: '审核', value: 3 },
|
||||
{ label: '收益', value: 4 },
|
||||
export const MSG_TYPE_FILTERS: Array<{ labelKey: string; value: CommunityMsgType | undefined }> = [
|
||||
{ labelKey: 'common.msgType.all', value: undefined },
|
||||
{ labelKey: 'common.msgType.t1', value: 1 },
|
||||
{ labelKey: 'common.msgType.t2', value: 2 },
|
||||
{ labelKey: 'common.msgType.t3', value: 3 },
|
||||
{ labelKey: 'common.msgType.t4', value: 4 },
|
||||
]
|
||||
|
||||
@ -218,7 +218,7 @@ onMounted(fetchDetail)
|
||||
<section v-if="!isDraft" class="proj-detail__notice" :style="{ borderColor: statusMeta.color }">
|
||||
<span class="proj-detail__notice-dot" :style="{ background: statusMeta.color }"></span>
|
||||
<span class="proj-detail__notice-text">
|
||||
{{ t('detail.noticePrefix') }}<b :style="{ color: statusMeta.color }">{{ statusMeta.label }}</b>
|
||||
{{ t('detail.noticePrefix') }}<b :style="{ color: statusMeta.color }">{{ t(statusMeta.labelKey) }}</b>
|
||||
<template v-if="current.status === 1">{{ t('detail.noticeReview') }}</template>
|
||||
<template v-else-if="current.status === 2">{{ t('detail.noticeApproved') }}</template>
|
||||
<template v-else-if="current.status === 3">{{ t('detail.noticeRejected') }}</template>
|
||||
@ -462,8 +462,8 @@ onMounted(fetchDetail)
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
.age-option.is-active {
|
||||
color: var(--cyan);
|
||||
border-color: var(--cyan);
|
||||
color: var(--accent);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
.age-option:disabled {
|
||||
opacity: 0.6;
|
||||
|
||||
@ -144,7 +144,7 @@ onMounted(() => {
|
||||
:class="{ 'is-active': activeStatus === f.value }"
|
||||
@click="onSwitchStatus(f.value)"
|
||||
>
|
||||
{{ f.label }}
|
||||
{{ t(f.labelKey) }}
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
@ -263,8 +263,8 @@ onMounted(() => {
|
||||
.proj-list__filter.is-active {
|
||||
/* 深色 on 霓虹前景统一走令牌(原硬编码 #04222a) */
|
||||
color: var(--on-accent);
|
||||
background: var(--cyan);
|
||||
border-color: var(--cyan);
|
||||
background: var(--accent);
|
||||
border-color: var(--accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
||||
@ -445,8 +445,8 @@ onMounted(() => {
|
||||
text-align: left;
|
||||
}
|
||||
.zone-option.is-active {
|
||||
border-color: var(--cyan);
|
||||
background: color-mix(in srgb, var(--cyan) 12%, var(--panel-2));
|
||||
border-color: var(--accent);
|
||||
background: color-mix(in srgb, var(--accent) 12%, var(--panel-2));
|
||||
}
|
||||
.zone-option__name {
|
||||
font-size: 14px;
|
||||
|
||||
@ -5,21 +5,25 @@
|
||||
* 纯展示组件:仅按传入 status 渲染对应 D4 色徽标,不发请求。
|
||||
*/
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { getStatusMeta } from './status'
|
||||
|
||||
// 全局 i18n:用于把 getStatusMeta 返回的 labelKey(common.projectStatus.*)翻成当前语言文案
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
/** 项目状态(契约 0-6;undefined 时兜底为“未知”) */
|
||||
status: number | undefined
|
||||
}>()
|
||||
|
||||
/** 当前状态展示元数据(文案 + D4 token 颜色) */
|
||||
/** 当前状态展示元数据(labelKey + D4 token 颜色) */
|
||||
const meta = computed(() => getStatusMeta(props.status))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 描边 + 文字同色,背景半透明,弱化但可辨 -->
|
||||
<span class="status-badge" :style="{ color: meta.color, borderColor: meta.color }">
|
||||
{{ meta.label }}
|
||||
{{ t(meta.labelKey) }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
|
||||
@ -6,15 +6,15 @@
|
||||
* 与 src/api/types.ts 的 ProjectStatus 联合类型严格对齐,禁止发明契约外的状态值。
|
||||
*
|
||||
* 颜色按任务要求映射 D4 token:
|
||||
* 草稿 muted / 审核中 amber / 通过·发布 green / 拒绝·下架·封禁 danger。
|
||||
* 草稿 muted / 审核中 warning / 通过·发布 success / 拒绝·下架·封禁 danger。
|
||||
* (下架/封禁同属“不可见/受限”负向态,统一用 danger,与拒绝同色,符合任务“拒绝/封禁 danger”口径并就近归类下架。)
|
||||
*/
|
||||
import type { ProjectStatus } from '../../api/types'
|
||||
|
||||
/** 单个状态的展示配置 */
|
||||
export interface StatusMeta {
|
||||
/** 徽标文案(对齐 project 模块枚举语义) */
|
||||
label: string
|
||||
/** 徽标文案 i18n key(common.projectStatus.*,消费方 t() 取译文;对齐 project 模块枚举语义) */
|
||||
labelKey: string
|
||||
/** D4 token 颜色变量名(CSS var(),用于徽标文字/描边) */
|
||||
color: string
|
||||
/** 是否可编辑草稿(仅 status=0 草稿可改,贴契约 /draft 约束) */
|
||||
@ -28,18 +28,18 @@ export interface StatusMeta {
|
||||
* 注意:键覆盖全部 7 个合法状态;getStatusMeta 对越界值兜底,避免运行期崩溃。
|
||||
*/
|
||||
export const STATUS_META: Record<ProjectStatus, StatusMeta> = {
|
||||
0: { label: '草稿', color: 'var(--muted)', editable: true, publishable: true },
|
||||
1: { label: '审核中', color: 'var(--amber)', editable: false, publishable: false },
|
||||
2: { label: '已通过', color: 'var(--green)', editable: false, publishable: false },
|
||||
3: { label: '已拒绝', color: 'var(--danger)', editable: false, publishable: false },
|
||||
4: { label: '已发布', color: 'var(--green)', editable: false, publishable: false },
|
||||
5: { label: '已下架', color: 'var(--danger)', editable: false, publishable: false },
|
||||
6: { label: '已封禁', color: 'var(--danger)', editable: false, publishable: false },
|
||||
0: { labelKey: 'common.projectStatus.s0', color: 'var(--muted)', editable: true, publishable: true },
|
||||
1: { labelKey: 'common.projectStatus.s1', color: 'var(--warning)', editable: false, publishable: false },
|
||||
2: { labelKey: 'common.projectStatus.s2', color: 'var(--success)', editable: false, publishable: false },
|
||||
3: { labelKey: 'common.projectStatus.s3', color: 'var(--danger)', editable: false, publishable: false },
|
||||
4: { labelKey: 'common.projectStatus.s4', color: 'var(--success)', editable: false, publishable: false },
|
||||
5: { labelKey: 'common.projectStatus.s5', color: 'var(--danger)', editable: false, publishable: false },
|
||||
6: { labelKey: 'common.projectStatus.s6', color: 'var(--danger)', editable: false, publishable: false },
|
||||
}
|
||||
|
||||
/** 默认兜底元数据(遇到契约外的未知状态值时使用,保证 UI 不崩) */
|
||||
const FALLBACK_META: StatusMeta = {
|
||||
label: '未知',
|
||||
labelKey: 'common.projectStatus.unknown',
|
||||
color: 'var(--muted)',
|
||||
editable: false,
|
||||
publishable: false,
|
||||
@ -58,13 +58,13 @@ export function getStatusMeta(status: number | undefined): StatusMeta {
|
||||
* “我的项目”列表的状态筛选项(含“全部”)。
|
||||
* value=undefined 表示不筛选(取全部);其余对齐契约 7 态。
|
||||
*/
|
||||
export const STATUS_FILTERS: Array<{ label: string; value: number | undefined }> = [
|
||||
{ label: '全部', value: undefined },
|
||||
{ label: '草稿', value: 0 },
|
||||
{ label: '审核中', value: 1 },
|
||||
{ label: '已通过', value: 2 },
|
||||
{ label: '已拒绝', value: 3 },
|
||||
{ label: '已发布', value: 4 },
|
||||
{ label: '已下架', value: 5 },
|
||||
{ label: '已封禁', value: 6 },
|
||||
export const STATUS_FILTERS: Array<{ labelKey: string; value: number | undefined }> = [
|
||||
{ labelKey: 'common.projectStatus.all', value: undefined },
|
||||
{ labelKey: 'common.projectStatus.s0', value: 0 },
|
||||
{ labelKey: 'common.projectStatus.s1', value: 1 },
|
||||
{ labelKey: 'common.projectStatus.s2', value: 2 },
|
||||
{ labelKey: 'common.projectStatus.s3', value: 3 },
|
||||
{ labelKey: 'common.projectStatus.s4', value: 4 },
|
||||
{ labelKey: 'common.projectStatus.s5', value: 5 },
|
||||
{ labelKey: 'common.projectStatus.s6', value: 6 },
|
||||
]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user