2026-04-01 00:58:42 +08:00
|
|
|
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: "/",
|
|
|
|
|
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",
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-04-02 00:31:28 +08:00
|
|
|
{
|
|
|
|
|
path: "articles/:id/edit",
|
|
|
|
|
name: "article-editor",
|
|
|
|
|
component: () => import("@/views/ArticleEditorView.vue"),
|
|
|
|
|
meta: {
|
|
|
|
|
titleKey: "route.articleEditor.title",
|
|
|
|
|
descriptionKey: "route.articleEditor.description",
|
2026-04-02 21:16:12 +08:00
|
|
|
navKey: null,
|
2026-04-02 00:31:28 +08:00
|
|
|
},
|
|
|
|
|
},
|
2026-04-01 00:58:42 +08:00
|
|
|
{
|
|
|
|
|
path: "articles/custom",
|
|
|
|
|
name: "articles-custom",
|
2026-04-02 00:31:28 +08:00
|
|
|
component: () => import("@/views/CustomGenerateView.vue"),
|
2026-04-01 00:58:42 +08:00
|
|
|
meta: {
|
|
|
|
|
titleKey: "route.custom.title",
|
|
|
|
|
descriptionKey: "route.custom.description",
|
|
|
|
|
navKey: "/articles/custom",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
2026-04-06 22:18:55 +08:00
|
|
|
path: "articles/free-create",
|
|
|
|
|
name: "articles-free-create",
|
|
|
|
|
component: () => import("@/views/FreeCreateView.vue"),
|
2026-04-01 00:58:42 +08:00
|
|
|
meta: {
|
2026-04-06 22:18:55 +08:00
|
|
|
titleKey: "route.freeCreate.title",
|
|
|
|
|
descriptionKey: "route.freeCreate.description",
|
|
|
|
|
navKey: "/articles/free-create",
|
2026-04-01 00:58:42 +08:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: "media",
|
|
|
|
|
name: "media",
|
2026-04-03 00:39:15 +08:00
|
|
|
component: () => import("@/views/MediaView.vue"),
|
2026-04-01 00:58:42 +08:00
|
|
|
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",
|
2026-04-12 09:56:18 +08:00
|
|
|
component: () => import("@/views/TrackingView.vue"),
|
2026-04-01 00:58:42 +08:00
|
|
|
meta: {
|
|
|
|
|
titleKey: "route.tracking.title",
|
|
|
|
|
descriptionKey: "route.tracking.description",
|
|
|
|
|
navKey: "/tracking",
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-04-12 09:56:18 +08:00
|
|
|
{
|
|
|
|
|
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",
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-04-01 00:58:42 +08:00
|
|
|
{
|
|
|
|
|
path: "knowledge",
|
|
|
|
|
name: "knowledge",
|
2026-04-05 17:14:13 +08:00
|
|
|
component: () => import("@/views/KnowledgeView.vue"),
|
2026-04-01 00:58:42 +08:00
|
|
|
meta: {
|
|
|
|
|
titleKey: "route.knowledge.title",
|
|
|
|
|
descriptionKey: "route.knowledge.description",
|
|
|
|
|
navKey: "/knowledge",
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-04-16 20:40:41 +08:00
|
|
|
{
|
|
|
|
|
path: "images",
|
|
|
|
|
name: "images",
|
|
|
|
|
component: () => import("@/views/ImagesView.vue"),
|
|
|
|
|
meta: {
|
|
|
|
|
titleKey: "route.images.title",
|
|
|
|
|
descriptionKey: "route.images.description",
|
|
|
|
|
navKey: "/images",
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-04-01 00:58:42 +08:00
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
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 (to.name === "login" && authStore.isAuthenticated) {
|
|
|
|
|
return { name: "workspace" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export { router };
|