From 76f5c73773bf4cde190a9bdbeb3132af66b9c244 Mon Sep 17 00:00:00 2001 From: liangxu Date: Fri, 17 Apr 2026 09:02:39 +0800 Subject: [PATCH] feat(kol): sidebar nav groups for marketplace + KOL workspace --- apps/admin-web/src/i18n/messages/en-US.ts | 70 ++++++++++++++ apps/admin-web/src/i18n/messages/zh-CN.ts | 70 ++++++++++++++ apps/admin-web/src/layouts/AppShell.vue | 112 +++++++++++++--------- apps/admin-web/src/stores/auth.ts | 5 +- 4 files changed, 211 insertions(+), 46 deletions(-) diff --git a/apps/admin-web/src/i18n/messages/en-US.ts b/apps/admin-web/src/i18n/messages/en-US.ts index 8e8c323..60c9ce9 100644 --- a/apps/admin-web/src/i18n/messages/en-US.ts +++ b/apps/admin-web/src/i18n/messages/en-US.ts @@ -78,6 +78,11 @@ const enUS = { contentManagement: "Content Management", knowledge: "Knowledge Base", images: "Image Management", + kolMarket: "KOL Marketplace", + kolMarketplace: "Template Marketplace", + kolWorkspace: "KOL Workspace", + kolManage: "Prompt Management", + kolDashboard: "Dashboard", }, auth: { welcomeBack: "Welcome back", @@ -152,6 +157,70 @@ const enUS = { description: "Manage image assets, including folders, reference analysis, and cover library usage.", }, }, + kol: { + marketplace: { + title: "KOL Template Marketplace", + filter: { + industry: "Industry", + keyword: "Keyword", + all: "All", + }, + empty: "No published subscription packages yet", + subscribers: "{count} subscribed tenants", + prompts: "{count} prompts", + }, + package: { + subscribe: "Request subscription", + pending: "Pending", + subscribed: "Subscribed", + revoked: "Revoked", + expired: "Expired", + notSubscribed: "Not subscribed", + }, + generate: { + title: "Generate Article", + submit: "Generate", + fillVariables: "Please fill in all required variables", + }, + manage: { + title: "KOL Prompt Management", + createPackage: "Create package", + editPackage: "Edit package", + publishPackage: "Publish", + archivePackage: "Archive", + createPrompt: "Create prompt", + editor: { + saveDraft: "Save draft", + publish: "Publish", + preview: "Preview form", + aiGenerate: "AI Generate", + aiOptimize: "AI Optimize", + aiPlaceholder: "Describe the prompt effect you want, and AI will generate or optimize it...", + }, + variable: { + input: "Input", + textarea: "Textarea", + select: "Select", + number: "Number", + checkbox: "Checkbox", + key: "Variable key", + label: "Label", + required: "Required", + placeholder: "Placeholder", + options: "Options (comma separated)", + }, + }, + dashboard: { + title: "KOL Dashboard", + totalSubs: "Total subscribed tenants", + monthSubs: "New this month", + totalUsage: "Total usage", + monthUsage: "Usage this month", + failRate: "Failure rate", + byPackage: "By package", + trend: "Trend", + }, + }, workspace: { eyebrow: "Dashboard", metrics: { @@ -360,6 +429,7 @@ const enUS = { instant_task: "Instant task", schedule_task: "Scheduled task", free_create: "Free create", + kol: "KOL generation", }, }, freeCreate: { diff --git a/apps/admin-web/src/i18n/messages/zh-CN.ts b/apps/admin-web/src/i18n/messages/zh-CN.ts index dbb3d4a..bff2b98 100644 --- a/apps/admin-web/src/i18n/messages/zh-CN.ts +++ b/apps/admin-web/src/i18n/messages/zh-CN.ts @@ -78,6 +78,11 @@ const zhCN = { contentManagement: "内容管理", knowledge: "知识库", images: "图片管理", + kolMarket: "KOL 市场", + kolMarketplace: "模版市场", + kolWorkspace: "KOL 工作台", + kolManage: "提示词管理", + kolDashboard: "数据看板", }, auth: { welcomeBack: "欢迎回来", @@ -152,6 +157,70 @@ const zhCN = { description: "管理图片素材库,支持分组管理、引用分析与封面图库引用。", }, }, + kol: { + marketplace: { + title: "KOL 模版市场", + filter: { + industry: "行业", + keyword: "关键字", + all: "全部", + }, + empty: "暂无已上架的订阅包", + subscribers: "{count} 个订阅租户", + prompts: "{count} 个 Prompt", + }, + package: { + subscribe: "申请订阅", + pending: "审核中", + subscribed: "已订阅", + revoked: "已撤销", + expired: "已到期", + notSubscribed: "未订阅", + }, + generate: { + title: "生成文章", + submit: "生成", + fillVariables: "请填写所有必填变量", + }, + manage: { + title: "KOL 提示词管理", + createPackage: "创建订阅包", + editPackage: "编辑包", + publishPackage: "发布", + archivePackage: "归档", + createPrompt: "新增 Prompt", + editor: { + saveDraft: "保存草稿", + publish: "发布", + preview: "预览表单", + aiGenerate: "AI 生成", + aiOptimize: "AI 优化", + aiPlaceholder: "描述你想要的 prompt 效果,AI 帮你生成 / 优化...", + }, + variable: { + input: "输入框", + textarea: "多行文本", + select: "选择框", + number: "数字框", + checkbox: "多选框", + key: "变量 key", + label: "显示名", + required: "必填", + placeholder: "提示语", + options: "选项(逗号分隔)", + }, + }, + dashboard: { + title: "KOL 数据看板", + totalSubs: "总订阅租户数", + monthSubs: "本月新增", + totalUsage: "总使用次数", + monthUsage: "本月使用", + failRate: "失败率", + byPackage: "按包维度", + trend: "趋势", + }, + }, workspace: { eyebrow: "Dashboard", metrics: { @@ -360,6 +429,7 @@ const zhCN = { instant_task: "即时任务", schedule_task: "定时任务", free_create: "自由创作", + kol: "KOL 生成", }, }, freeCreate: { diff --git a/apps/admin-web/src/layouts/AppShell.vue b/apps/admin-web/src/layouts/AppShell.vue index e541cad..cb23471 100644 --- a/apps/admin-web/src/layouts/AppShell.vue +++ b/apps/admin-web/src/layouts/AppShell.vue @@ -55,51 +55,73 @@ const currentLocaleLabel = computed(() => { return localeOptions.value.find((opt) => opt.value === currentLocale.value)?.label ?? "Language"; }); -const navSections = computed(() => [ - { - key: "workspace", - title: "", - items: [ - { - key: "/workspace", - label: t("nav.workspace"), - icon: AppstoreOutlined, - }, - ], - }, - { - key: "articleCreation", - title: t("nav.articleCreation"), - items: [ - { key: "/articles/templates", label: t("nav.templates") }, - { key: "/articles/custom", label: t("nav.custom") }, - { key: "/articles/free-create", label: t("nav.freeCreate") }, - { key: "/media", label: t("nav.media"), icon: GlobalOutlined }, - ], - }, - { - key: "brandManagement", - title: t("nav.brandManagement"), - items: [ - { key: "/brands", label: t("nav.brands"), icon: SearchOutlined }, - ], - }, - { - key: "tracking", - title: t("nav.tracking"), - items: [ - { key: "/tracking", label: t("nav.trackingDetail"), icon: RadarChartOutlined }, - ], - }, - { - key: "contentManagement", - title: t("nav.contentManagement"), - items: [ - { key: "/knowledge", label: t("nav.knowledge"), icon: BookOutlined }, - { key: "/images", label: t("nav.images"), icon: PictureOutlined }, - ], - }, -]); +const navSections = computed(() => { + const base = [ + { + key: "workspace", + title: "", + items: [ + { + key: "/workspace", + label: t("nav.workspace"), + icon: AppstoreOutlined, + }, + ], + }, + { + key: "articleCreation", + title: t("nav.articleCreation"), + items: [ + { key: "/articles/templates", label: t("nav.templates") }, + { key: "/articles/custom", label: t("nav.custom") }, + { key: "/articles/free-create", label: t("nav.freeCreate") }, + { key: "/media", label: t("nav.media"), icon: GlobalOutlined }, + ], + }, + { + key: "brandManagement", + title: t("nav.brandManagement"), + items: [ + { key: "/brands", label: t("nav.brands"), icon: SearchOutlined }, + ], + }, + { + key: "tracking", + title: t("nav.tracking"), + items: [ + { key: "/tracking", label: t("nav.trackingDetail"), icon: RadarChartOutlined }, + ], + }, + { + key: "contentManagement", + title: t("nav.contentManagement"), + items: [ + { key: "/knowledge", label: t("nav.knowledge"), icon: BookOutlined }, + { key: "/images", label: t("nav.images"), icon: PictureOutlined }, + ], + }, + { + key: "kolMarket", + title: t("nav.kolMarket"), + items: [ + { key: "/kol/marketplace", label: t("nav.kolMarketplace") }, + ], + }, + ]; + + if (authStore.isActiveKol) { + base.push({ + key: "kolWorkspace", + title: t("nav.kolWorkspace"), + items: [ + { key: "/kol/manage", label: t("nav.kolManage") }, + { key: "/kol/dashboard", label: t("nav.kolDashboard") }, + ], + }); + } + + return base; +}); function go(path: string): void { void router.push(path); diff --git a/apps/admin-web/src/stores/auth.ts b/apps/admin-web/src/stores/auth.ts index 2f76997..b19a424 100644 --- a/apps/admin-web/src/stores/auth.ts +++ b/apps/admin-web/src/stores/auth.ts @@ -65,6 +65,8 @@ export const useAuthStore = defineStore("auth", () => { } const isAuthenticated = computed(() => Boolean(accessToken.value && user.value)); + const kolProfile = computed(() => user.value?.kol_profile ?? null); + const isActiveKol = computed(() => kolProfile.value?.status === "active"); return { accessToken, @@ -72,9 +74,10 @@ export const useAuthStore = defineStore("auth", () => { user, initialized, isAuthenticated, + kolProfile, + isActiveKol, bootstrap, login, logout, }; }); -