Files
geo/apps/admin-web/src/router/index.ts
T
root 40d9a6cc63 feat(imitation): add article imitation create flow
Introduce 仿写创作: new list and create views, backend imitation service
and prompt templates, worker task routing for imitation jobs, and one-click
rewrite triggers from question citation sources. Surface source article
URL/title on article list/detail, and restrict failed articles to delete-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 21:36:44 +08:00

277 lines
8.0 KiB
TypeScript

import { createRouter, createWebHistory } from "vue-router";
import { pinia } from "@/stores/pinia";
import { useAuthStore } from "@/stores/auth";
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/login",
name: "login",
component: () => import("@/views/LoginView.vue"),
meta: {
titleKey: "route.login.title",
descriptionKey: "route.login.description",
},
},
{
path: "/membership-blocked",
name: "membership-blocked",
component: () => import("@/views/MembershipBlockedView.vue"),
meta: {
requiresAuth: true,
},
},
{
path: "/",
component: () => import("@/layouts/AppShell.vue"),
meta: {
requiresAuth: true,
},
children: [
{
path: "",
redirect: "/workspace",
},
{
path: "workspace",
name: "workspace",
component: () => import("@/views/WorkspaceView.vue"),
meta: {
titleKey: "route.workspace.title",
descriptionKey: "route.workspace.description",
navKey: "/workspace",
},
},
{
path: "articles/templates",
name: "articles-templates",
component: () => import("@/views/TemplatesView.vue"),
meta: {
titleKey: "route.templates.title",
descriptionKey: "route.templates.description",
navKey: "/articles/templates",
},
},
{
path: "articles/wizard",
name: "article-wizard",
component: () => import("@/views/TemplateWizardView.vue"),
meta: {
titleKey: "route.wizard.title",
descriptionKey: "route.wizard.description",
navKey: "/articles/templates",
},
},
{
path: "articles/:id/edit",
name: "article-editor",
component: () => import("@/views/ArticleEditorView.vue"),
meta: {
titleKey: "route.articleEditor.title",
descriptionKey: "route.articleEditor.description",
navKey: null,
},
},
{
path: "articles/custom",
name: "articles-custom",
component: () => import("@/views/CustomGenerateView.vue"),
meta: {
titleKey: "route.custom.title",
descriptionKey: "route.custom.description",
navKey: "/articles/custom",
},
},
{
path: "articles/free-create",
name: "articles-free-create",
component: () => import("@/views/FreeCreateView.vue"),
meta: {
titleKey: "route.freeCreate.title",
descriptionKey: "route.freeCreate.description",
navKey: "/articles/free-create",
},
},
{
path: "articles/imitations",
name: "articles-imitations",
component: () => import("@/views/ImitationView.vue"),
meta: {
titleKey: "route.imitation.title",
descriptionKey: "route.imitation.description",
navKey: "/articles/imitations",
},
},
{
path: "articles/imitations/create",
name: "article-imitation-create",
component: () => import("@/views/ImitationGenerateView.vue"),
meta: {
titleKey: "route.imitationCreate.title",
descriptionKey: "route.imitationCreate.description",
navKey: "/articles/imitations",
},
},
{
path: "media",
name: "media",
component: () => import("@/views/MediaView.vue"),
meta: {
titleKey: "route.media.title",
descriptionKey: "route.media.description",
navKey: "/media",
},
},
{
path: "brands",
name: "brands",
component: () => import("@/views/BrandsView.vue"),
meta: {
titleKey: "route.brands.title",
descriptionKey: "route.brands.description",
navKey: "/brands",
},
},
{
path: "tracking",
name: "tracking",
component: () => import("@/views/TrackingView.vue"),
meta: {
titleKey: "route.tracking.title",
descriptionKey: "route.tracking.description",
navKey: "/tracking",
},
},
{
path: "tracking/questions/:brandId/:questionId",
name: "tracking-question-detail",
component: () => import("@/views/TrackingQuestionDetailView.vue"),
meta: {
titleKey: "route.trackingQuestion.title",
descriptionKey: "route.trackingQuestion.description",
navKey: "/tracking",
},
},
{
path: "knowledge",
name: "knowledge",
component: () => import("@/views/KnowledgeView.vue"),
meta: {
titleKey: "route.knowledge.title",
descriptionKey: "route.knowledge.description",
navKey: "/knowledge",
},
},
{
path: "images",
name: "images",
component: () => import("@/views/ImagesView.vue"),
meta: {
titleKey: "route.images.title",
descriptionKey: "route.images.description",
navKey: "/images",
},
},
{
path: "kol/manage",
name: "kol-manage",
component: () => import("@/views/KolManageView.vue"),
meta: {
titleKey: "kol.manage.title",
navKey: "/kol/manage",
requiresKol: true,
},
},
{
path: "kol/dashboard",
name: "kol-dashboard",
component: () => import("@/views/KolDashboardView.vue"),
meta: {
titleKey: "kol.dashboard.title",
navKey: "/kol/dashboard",
requiresKol: true,
},
},
{
path: "kol/profile",
name: "kol-profile",
component: () => import("@/views/KolProfileView.vue"),
meta: {
titleKey: "kol.profile.title",
navKey: "/kol/profile",
requiresKol: true,
},
},
{
path: "kol/marketplace",
name: "kol-marketplace",
component: () => import("@/views/KolMarketplaceView.vue"),
meta: {
titleKey: "kol.marketplace.title",
navKey: "/kol/marketplace",
},
},
{
path: "kol/packages/:id",
name: "kol-package-detail",
component: () => import("@/views/KolPackageDetailView.vue"),
meta: {
titleKey: "kol.marketplace.title",
navKey: "/kol/marketplace",
},
},
{
path: "kol/generate/:subscriptionPromptId",
name: "kol-generate",
component: () => import("@/views/KolGenerateView.vue"),
meta: {
titleKey: "kol.generate.title",
navKey: "/articles/templates",
},
},
],
},
],
});
router.beforeEach(async (to) => {
const authStore = useAuthStore(pinia);
if (!authStore.initialized) {
await authStore.bootstrap();
}
const requiresAuth = to.matched.some((record) => record.meta.requiresAuth);
if (requiresAuth && !authStore.isAuthenticated) {
return {
name: "login",
query: { redirect: to.fullPath },
};
}
if (authStore.isAuthenticated && authStore.isMembershipBlocked && to.name !== "membership-blocked") {
return { name: "membership-blocked" };
}
if (to.name === "membership-blocked" && authStore.isAuthenticated && !authStore.isMembershipBlocked) {
return { name: "workspace" };
}
if (to.meta.requiresKol && !authStore.isActiveKol) {
return { name: "workspace" };
}
if (to.name === "login" && authStore.isAuthenticated) {
if (authStore.isMembershipBlocked) {
return { name: "membership-blocked" };
}
return { name: "workspace" };
}
return true;
});
export { router };