40d9a6cc63
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>
277 lines
8.0 KiB
TypeScript
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 };
|