mirror of https://github.com/halo-dev/halo-admin
parent
b142b3ca80
commit
8bc6ff798e
|
@ -26,8 +26,8 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@halo-dev/admin-api": "^1.1.0",
|
||||
"@halo-dev/components": "workspace:*",
|
||||
"@halo-dev/admin-shared": "workspace:*",
|
||||
"@halo-dev/components": "workspace:*",
|
||||
"@vueuse/core": "^8.6.0",
|
||||
"filepond": "^4.30.4",
|
||||
"filepond-plugin-image-preview": "^4.6.11",
|
||||
|
@ -72,6 +72,7 @@
|
|||
"vite": "^2.9.12",
|
||||
"vite-compression-plugin": "^0.0.4",
|
||||
"vite-plugin-pwa": "^0.12.0",
|
||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||
"vitest": "^0.15.1",
|
||||
"vue-tsc": "^0.34.17"
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ importers:
|
|||
vite: ^2.9.12
|
||||
vite-compression-plugin: ^0.0.4
|
||||
vite-plugin-pwa: ^0.12.0
|
||||
vite-plugin-vue-setup-extend: ^0.4.0
|
||||
vitest: ^0.15.1
|
||||
vue: ^3.2.37
|
||||
vue-filepond: ^7.0.3
|
||||
|
@ -98,6 +99,7 @@ importers:
|
|||
vite: 2.9.12_sass@1.52.3
|
||||
vite-compression-plugin: 0.0.4
|
||||
vite-plugin-pwa: 0.12.0_vite@2.9.12
|
||||
vite-plugin-vue-setup-extend: 0.4.0_vite@2.9.12
|
||||
vitest: 0.15.1_fiumxgyk2tfafw3c4rsaverrnm
|
||||
vue-tsc: 0.34.17_typescript@4.7.3
|
||||
|
||||
|
@ -6783,6 +6785,16 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite-plugin-vue-setup-extend/0.4.0_vite@2.9.12:
|
||||
resolution: {integrity: sha512-WMbjPCui75fboFoUTHhdbXzu4Y/bJMv5N9QT9a7do3wNMNHHqrk+Tn2jrSJU0LS5fGl/EG+FEDBYVUeWIkDqXQ==}
|
||||
peerDependencies:
|
||||
vite: '>=2.0.0'
|
||||
dependencies:
|
||||
'@vue/compiler-sfc': 3.2.37
|
||||
magic-string: 0.25.9
|
||||
vite: 2.9.12_sass@1.52.3
|
||||
dev: true
|
||||
|
||||
/vite/2.9.12:
|
||||
resolution: {integrity: sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==}
|
||||
engines: {node: '>=12.2.0'}
|
||||
|
|
72
src/main.ts
72
src/main.ts
|
@ -2,16 +2,78 @@ import { createApp } from "vue";
|
|||
import { createPinia } from "pinia";
|
||||
import App from "./App.vue";
|
||||
import router from "./router";
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
// setup
|
||||
import "./setup/setupStyles";
|
||||
import { setupComponents } from "./setup/setupComponents";
|
||||
import { registerMenu } from "@/router/menus.config";
|
||||
|
||||
// modules
|
||||
import dashboardModule from "./modules/dashboard/module";
|
||||
import postModule from "./modules/contents/posts/module";
|
||||
import sheetModule from "./modules/contents/sheets/module";
|
||||
import commentModule from "./modules/contents/comments/module";
|
||||
import attachmentModule from "./modules/contents/attachments/module";
|
||||
import themeModule from "./modules/interface/themes/module";
|
||||
import menuModule from "./modules/interface/menus/module";
|
||||
import pluginModule from "./modules/system/plugins/module";
|
||||
import userModule from "./modules/system/users/module";
|
||||
import roleModule from "./modules/system/roles/module";
|
||||
import settingModule from "./modules/system/settings/module";
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
setupComponents(app);
|
||||
|
||||
app.use(createPinia());
|
||||
app.use(router);
|
||||
|
||||
app.mount("#app");
|
||||
async function registerModule(pluginModule: Plugin) {
|
||||
if (pluginModule.components) {
|
||||
for (const component of pluginModule.components) {
|
||||
component.name && app.component(component.name, component);
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginModule.routes) {
|
||||
for (const route of pluginModule.routes) {
|
||||
router.addRoute(route);
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginModule.menus) {
|
||||
for (const group of pluginModule.menus) {
|
||||
for (const menu of group.items) {
|
||||
registerMenu(group.name, menu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadCoreModules() {
|
||||
[
|
||||
dashboardModule,
|
||||
postModule,
|
||||
sheetModule,
|
||||
commentModule,
|
||||
attachmentModule,
|
||||
themeModule,
|
||||
menuModule,
|
||||
pluginModule,
|
||||
userModule,
|
||||
roleModule,
|
||||
settingModule,
|
||||
].forEach(registerModule);
|
||||
}
|
||||
|
||||
function loadPluginModules() {
|
||||
// TODO: load plugin modules
|
||||
}
|
||||
|
||||
initApp();
|
||||
|
||||
async function initApp() {
|
||||
loadCoreModules();
|
||||
loadPluginModules();
|
||||
app.use(router);
|
||||
app.mount("#app");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout } from "@/layouts";
|
||||
import AttachmentList from "./AttachmentList.vue";
|
||||
import { IconFolder } from "@halo-dev/components";
|
||||
|
||||
const attachmentModule: Plugin = {
|
||||
name: "attachmentModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/attachments",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Attachments",
|
||||
component: AttachmentList,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "内容",
|
||||
items: [
|
||||
{
|
||||
name: "附件",
|
||||
path: "/attachments",
|
||||
icon: IconFolder,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default attachmentModule;
|
|
@ -0,0 +1,36 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout } from "@/layouts";
|
||||
import { IconMessage } from "@halo-dev/components";
|
||||
import CommentList from "./CommentList.vue";
|
||||
|
||||
const commentModule: Plugin = {
|
||||
name: "commentModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/comments",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Comments",
|
||||
component: CommentList,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "内容",
|
||||
items: [
|
||||
{
|
||||
name: "评论",
|
||||
path: "/comments",
|
||||
icon: IconMessage,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default commentModule;
|
|
@ -0,0 +1,66 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout, BlankLayout } from "@/layouts";
|
||||
import { IconBookRead } from "@halo-dev/components";
|
||||
import PostList from "./PostList.vue";
|
||||
import PostEditor from "./PostEditor.vue";
|
||||
import CategoryList from "./categories/CategoryList.vue";
|
||||
import TagList from "./tags/TagList.vue";
|
||||
|
||||
const postModule: Plugin = {
|
||||
name: "postModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/posts",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Posts",
|
||||
component: PostList,
|
||||
},
|
||||
{
|
||||
path: "editor",
|
||||
name: "PostEditor",
|
||||
component: PostEditor,
|
||||
},
|
||||
{
|
||||
path: "categories",
|
||||
component: BlankLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Categories",
|
||||
component: CategoryList,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "tags",
|
||||
component: BlankLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Tags",
|
||||
component: TagList,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "内容",
|
||||
items: [
|
||||
{
|
||||
name: "文章",
|
||||
path: "/posts",
|
||||
icon: IconBookRead,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default postModule;
|
|
@ -0,0 +1,36 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout } from "@/layouts";
|
||||
import SheetList from "./SheetList.vue";
|
||||
import { IconPages } from "@halo-dev/components";
|
||||
|
||||
const sheetModule: Plugin = {
|
||||
name: "sheetModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/sheets",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Sheets",
|
||||
component: SheetList,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "内容",
|
||||
items: [
|
||||
{
|
||||
name: "页面",
|
||||
path: "/sheets",
|
||||
icon: IconPages,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default sheetModule;
|
|
@ -0,0 +1,55 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout } from "@/layouts";
|
||||
import Dashboard from "./Dashboard.vue";
|
||||
import { IconDashboard } from "@halo-dev/components";
|
||||
|
||||
import CommentStatsWidget from "./widgets/CommentStatsWidget.vue";
|
||||
import JournalPublishWidget from "./widgets/JournalPublishWidget.vue";
|
||||
import PostStatsWidget from "./widgets/PostStatsWidget.vue";
|
||||
import QuickLinkWidget from "./widgets/QuickLinkWidget.vue";
|
||||
import RecentLoginWidget from "./widgets/RecentLoginWidget.vue";
|
||||
import RecentPublishedWidget from "./widgets/RecentPublishedWidget.vue";
|
||||
import UserStatsWidget from "./widgets/UserStatsWidget.vue";
|
||||
import ViewsStatsWidget from "./widgets/ViewsStatsWidget.vue";
|
||||
|
||||
const dashboardModule: Plugin = {
|
||||
name: "dashboardModule",
|
||||
components: [
|
||||
CommentStatsWidget,
|
||||
JournalPublishWidget,
|
||||
PostStatsWidget,
|
||||
QuickLinkWidget,
|
||||
RecentLoginWidget,
|
||||
RecentPublishedWidget,
|
||||
UserStatsWidget,
|
||||
ViewsStatsWidget,
|
||||
],
|
||||
routes: [
|
||||
{
|
||||
path: "/",
|
||||
component: BasicLayout,
|
||||
redirect: "/dashboard",
|
||||
children: [
|
||||
{
|
||||
path: "dashboard",
|
||||
name: "Dashboard",
|
||||
component: Dashboard,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "",
|
||||
items: [
|
||||
{
|
||||
name: "仪表盘",
|
||||
path: "/dashboard",
|
||||
icon: IconDashboard,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default dashboardModule;
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
<script lang="ts" name="CommentStatsWidget" setup>
|
||||
import { VCard } from "@halo-dev/components";
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
<script lang="ts" name="JournalPublishWidget" setup>
|
||||
import { VButton, VCard, VTextarea } from "@halo-dev/components";
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
<script lang="ts" name="PostStatsWidget" setup>
|
||||
import { VCard } from "@halo-dev/components";
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
<script lang="ts" name="QuickLinkWidget" setup>
|
||||
import {
|
||||
IconArrowRight,
|
||||
IconBookRead,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
<script lang="ts" name="RecentLoginWidget" setup>
|
||||
import { VCard } from "@halo-dev/components";
|
||||
import { users } from "@/modules/system/users/users-mock";
|
||||
</script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
<script lang="ts" name="RecentPublishedWidget" setup>
|
||||
import { VCard, VSpace } from "@halo-dev/components";
|
||||
import { posts } from "@/modules/contents/posts/posts-mock";
|
||||
</script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
<script lang="ts" name="UserStatsWidget" setup>
|
||||
import { VCard } from "@halo-dev/components";
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
<script lang="ts" name="ViewsStatsWidget" setup>
|
||||
import { VCard } from "@halo-dev/components";
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import type { App } from "vue";
|
||||
|
||||
import PostStatsWidget from "./PostStatsWidget.vue";
|
||||
import UserStatsWidget from "./UserStatsWidget.vue";
|
||||
import CommentStatsWidget from "./CommentStatsWidget.vue";
|
||||
import ViewsStatsWidget from "./ViewsStatsWidget.vue";
|
||||
import RecentLoginWidget from "./RecentLoginWidget.vue";
|
||||
import RecentPublishedWidget from "./RecentPublishedWidget.vue";
|
||||
import JournalPublishWidget from "./JournalPublishWidget.vue";
|
||||
import QuickLinkWidget from "./QuickLinkWidget.vue";
|
||||
|
||||
const install = (app: App) => {
|
||||
app.component("PostStatsWidget", PostStatsWidget);
|
||||
app.component("UserStatsWidget", UserStatsWidget);
|
||||
app.component("CommentStatsWidget", CommentStatsWidget);
|
||||
app.component("ViewsStatsWidget", ViewsStatsWidget);
|
||||
app.component("RecentLoginWidget", RecentLoginWidget);
|
||||
app.component("RecentPublishedWidget", RecentPublishedWidget);
|
||||
app.component("JournalPublishWidget", JournalPublishWidget);
|
||||
app.component("QuickLinkWidget", QuickLinkWidget);
|
||||
};
|
||||
|
||||
export default install;
|
|
@ -0,0 +1,36 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout } from "@/layouts";
|
||||
import MenuList from "./MenuList.vue";
|
||||
import { IconListSettings } from "@halo-dev/components";
|
||||
|
||||
const menuModule: Plugin = {
|
||||
name: "menuModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/menus",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Menus",
|
||||
component: MenuList,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "外观",
|
||||
items: [
|
||||
{
|
||||
name: "菜单",
|
||||
path: "/menus",
|
||||
icon: IconListSettings,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default menuModule;
|
|
@ -0,0 +1,48 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout, BlankLayout } from "@/layouts";
|
||||
import ThemeDetail from "./ThemeDetail.vue";
|
||||
import Visual from "./Visual.vue";
|
||||
import { IconPalette } from "@halo-dev/components";
|
||||
|
||||
const themeModule: Plugin = {
|
||||
name: "themeModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/theme",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Theme",
|
||||
component: ThemeDetail,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/theme/visual",
|
||||
component: BlankLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "ThemeVisual",
|
||||
component: Visual,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "外观",
|
||||
items: [
|
||||
{
|
||||
name: "主题",
|
||||
path: "/theme",
|
||||
icon: IconPalette,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default themeModule;
|
|
@ -0,0 +1,42 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout } from "@/layouts";
|
||||
import PluginList from "./PluginList.vue";
|
||||
import PluginDetail from "./PluginDetail.vue";
|
||||
import { IconPlug } from "@halo-dev/components";
|
||||
|
||||
const pluginModule: Plugin = {
|
||||
name: "pluginModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/plugins",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Plugins",
|
||||
component: PluginList,
|
||||
},
|
||||
{
|
||||
path: ":id",
|
||||
name: "PluginDetail",
|
||||
component: PluginDetail,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "系统",
|
||||
items: [
|
||||
{
|
||||
name: "插件",
|
||||
path: "/plugins",
|
||||
icon: IconPlug,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default pluginModule;
|
|
@ -0,0 +1,30 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout } from "@/layouts";
|
||||
import RoleList from "./RoleList.vue";
|
||||
import RoleDetail from "./RoleDetail.vue";
|
||||
|
||||
const roleModule: Plugin = {
|
||||
name: "roleModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/users",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "roles",
|
||||
name: "Roles",
|
||||
component: RoleList,
|
||||
},
|
||||
{
|
||||
path: "roles/:id",
|
||||
name: "RoleDetail",
|
||||
component: RoleDetail,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [],
|
||||
};
|
||||
|
||||
export default roleModule;
|
|
@ -0,0 +1,43 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { SystemSettingsLayout } from "@/layouts";
|
||||
import GeneralSettings from "./GeneralSettings.vue";
|
||||
import NotificationSettings from "./NotificationSettings.vue";
|
||||
import { IconSettings } from "@halo-dev/components";
|
||||
|
||||
const settingModule: Plugin = {
|
||||
name: "settingModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/settings",
|
||||
component: SystemSettingsLayout,
|
||||
redirect: "/settings/general",
|
||||
children: [
|
||||
{
|
||||
path: "general",
|
||||
name: "GeneralSettings",
|
||||
component: GeneralSettings,
|
||||
},
|
||||
{
|
||||
path: "notification",
|
||||
name: "NotificationSettings",
|
||||
component: NotificationSettings,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "系统",
|
||||
items: [
|
||||
{
|
||||
name: "设置",
|
||||
path: "/settings",
|
||||
icon: IconSettings,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default settingModule;
|
|
@ -0,0 +1,73 @@
|
|||
import type { Plugin } from "@halo-dev/admin-shared";
|
||||
import { BasicLayout, BlankLayout, UserProfileLayout } from "@/layouts";
|
||||
import UserList from "./UserList.vue";
|
||||
import UserDetail from "./UserDetail.vue";
|
||||
import ProfileModification from "./ProfileModification.vue";
|
||||
import PasswordChange from "./PasswordChange.vue";
|
||||
import PersonalAccessTokens from "./PersonalAccessTokens.vue";
|
||||
import { IconUserSettings } from "@halo-dev/components";
|
||||
|
||||
const userModule: Plugin = {
|
||||
name: "userModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/users",
|
||||
component: BlankLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Users",
|
||||
component: UserList,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: ":username",
|
||||
component: UserProfileLayout,
|
||||
alias: ["profile"],
|
||||
children: [
|
||||
{
|
||||
path: "detail",
|
||||
name: "UserDetail",
|
||||
component: UserDetail,
|
||||
},
|
||||
{
|
||||
path: "profile-modification",
|
||||
name: "ProfileModification",
|
||||
component: ProfileModification,
|
||||
},
|
||||
{
|
||||
path: "password-change",
|
||||
name: "PasswordChange",
|
||||
component: PasswordChange,
|
||||
},
|
||||
{
|
||||
path: "tokens",
|
||||
name: "PersonalAccessTokens",
|
||||
component: PersonalAccessTokens,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
menus: [
|
||||
{
|
||||
name: "系统",
|
||||
items: [
|
||||
{
|
||||
name: "用户",
|
||||
path: "/users",
|
||||
icon: IconUserSettings,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default userModule;
|
|
@ -2,98 +2,28 @@ import {
|
|||
IconBookRead,
|
||||
IconDashboard,
|
||||
IconFolder,
|
||||
IconListSettings,
|
||||
IconMessage,
|
||||
IconPages,
|
||||
IconPalette,
|
||||
IconPlug,
|
||||
IconSettings,
|
||||
IconUserSettings,
|
||||
} from "@halo-dev/components";
|
||||
import type { Component } from "vue";
|
||||
|
||||
declare interface MenuGroupType {
|
||||
name?: string;
|
||||
items: MenuItemType[];
|
||||
}
|
||||
|
||||
declare interface MenuItemType {
|
||||
name: string;
|
||||
path: string;
|
||||
icon?: Component;
|
||||
meta?: Record<string, unknown>;
|
||||
children?: MenuItemType[];
|
||||
}
|
||||
import type { MenuGroupType, MenuItemType } from "@halo-dev/admin-shared";
|
||||
|
||||
export const menus: MenuGroupType[] = [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
name: "仪表盘",
|
||||
path: "/dashboard",
|
||||
icon: IconDashboard,
|
||||
},
|
||||
],
|
||||
name: "",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
name: "内容",
|
||||
items: [
|
||||
{
|
||||
name: "文章",
|
||||
path: "/posts",
|
||||
icon: IconBookRead,
|
||||
},
|
||||
{
|
||||
name: "页面",
|
||||
path: "/sheets",
|
||||
icon: IconPages,
|
||||
},
|
||||
{
|
||||
name: "评论",
|
||||
path: "/comments",
|
||||
icon: IconMessage,
|
||||
},
|
||||
{
|
||||
name: "附件",
|
||||
path: "/attachments",
|
||||
icon: IconFolder,
|
||||
},
|
||||
],
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
name: "外观",
|
||||
items: [
|
||||
{
|
||||
name: "主题",
|
||||
path: "/theme",
|
||||
icon: IconPalette,
|
||||
},
|
||||
{
|
||||
name: "菜单",
|
||||
path: "/menus",
|
||||
icon: IconListSettings,
|
||||
},
|
||||
],
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
name: "系统",
|
||||
items: [
|
||||
{
|
||||
name: "插件",
|
||||
path: "/plugins",
|
||||
icon: IconPlug,
|
||||
},
|
||||
{
|
||||
name: "用户",
|
||||
path: "/users",
|
||||
icon: IconUserSettings,
|
||||
},
|
||||
{
|
||||
name: "设置",
|
||||
path: "/settings",
|
||||
icon: IconSettings,
|
||||
},
|
||||
],
|
||||
items: [],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -125,6 +55,18 @@ export const minimenus: MenuItemType[] = [
|
|||
},
|
||||
];
|
||||
|
||||
export function registerMenu(group: string | undefined, menu: MenuItemType) {
|
||||
const groupIndex = menus.findIndex((g) => g.name === group);
|
||||
if (groupIndex !== -1) {
|
||||
menus[groupIndex].items.push(menu);
|
||||
return;
|
||||
}
|
||||
menus.push({
|
||||
name: group,
|
||||
items: [menu],
|
||||
});
|
||||
}
|
||||
|
||||
export type { MenuItemType, MenuGroupType };
|
||||
|
||||
export default menus;
|
||||
|
|
|
@ -1,246 +1,12 @@
|
|||
import type { RouteRecordRaw } from "vue-router";
|
||||
import {
|
||||
BasicLayout,
|
||||
BlankLayout,
|
||||
SystemSettingsLayout,
|
||||
UserProfileLayout,
|
||||
} from "@/layouts";
|
||||
|
||||
import Dashboard from "../modules/dashboard/Dashboard.vue";
|
||||
|
||||
import PostList from "../modules/contents/posts/PostList.vue";
|
||||
import PostEditor from "../modules/contents/posts/PostEditor.vue";
|
||||
import SheetList from "../modules/contents/sheets/SheetList.vue";
|
||||
import CategoryList from "../modules/contents/posts/categories/CategoryList.vue";
|
||||
import TagList from "../modules/contents/posts/tags/TagList.vue";
|
||||
import CommentList from "../modules/contents/comments/CommentList.vue";
|
||||
import AttachmentList from "../modules/contents/attachments/AttachmentList.vue";
|
||||
|
||||
import ThemeDetail from "../modules/interface/themes/ThemeDetail.vue";
|
||||
import MenuList from "../modules/interface/menus/MenuList.vue";
|
||||
import Visual from "../modules/interface/themes/Visual.vue";
|
||||
|
||||
import PluginList from "../modules/system/plugins/PluginList.vue";
|
||||
import PluginDetail from "../modules/system/plugins/PluginDetail.vue";
|
||||
import UserList from "../modules/system/users/UserList.vue";
|
||||
import RoleList from "../modules/system/roles/RoleList.vue";
|
||||
import RoleDetail from "../modules/system/roles/RoleDetail.vue";
|
||||
import UserDetail from "../modules/system/users/UserDetail.vue";
|
||||
import ProfileModification from "../modules/system/users/ProfileModification.vue";
|
||||
import PasswordChange from "../modules/system/users/PasswordChange.vue";
|
||||
import PersonalAccessTokens from "../modules/system/users/PersonalAccessTokens.vue";
|
||||
import GeneralSettings from "../modules/system/settings/GeneralSettings.vue";
|
||||
import NotificationSettings from "../modules/system/settings/NotificationSettings.vue";
|
||||
import NotFound from "@/views/exceptions/NotFound.vue";
|
||||
import { BasicLayout } from "@/layouts";
|
||||
|
||||
export const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "/",
|
||||
path: "/:pathMatch(.*)*",
|
||||
component: BasicLayout,
|
||||
redirect: "/dashboard",
|
||||
children: [
|
||||
{
|
||||
path: "dashboard",
|
||||
name: "Dashboard",
|
||||
component: Dashboard,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/posts",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Posts",
|
||||
component: PostList,
|
||||
},
|
||||
{
|
||||
path: "editor",
|
||||
name: "PostEditor",
|
||||
component: PostEditor,
|
||||
},
|
||||
{
|
||||
path: "categories",
|
||||
component: BlankLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Categories",
|
||||
component: CategoryList,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "tags",
|
||||
component: BlankLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Tags",
|
||||
component: TagList,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/sheets",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Sheets",
|
||||
component: SheetList,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/comments",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Comments",
|
||||
component: CommentList,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/attachments",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Attachments",
|
||||
component: AttachmentList,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/theme",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Theme",
|
||||
component: ThemeDetail,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/theme/visual",
|
||||
component: BlankLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "ThemeVisual",
|
||||
component: Visual,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/menus",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Menus",
|
||||
component: MenuList,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/plugins",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Plugins",
|
||||
component: PluginList,
|
||||
},
|
||||
{
|
||||
path: ":id",
|
||||
name: "PluginDetail",
|
||||
component: PluginDetail,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/users",
|
||||
component: BlankLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Users",
|
||||
component: UserList,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: ":username",
|
||||
component: UserProfileLayout,
|
||||
alias: ["profile"],
|
||||
children: [
|
||||
{
|
||||
path: "detail",
|
||||
name: "UserDetail",
|
||||
component: UserDetail,
|
||||
},
|
||||
{
|
||||
path: "profile-modification",
|
||||
name: "ProfileModification",
|
||||
component: ProfileModification,
|
||||
},
|
||||
{
|
||||
path: "password-change",
|
||||
name: "PasswordChange",
|
||||
component: PasswordChange,
|
||||
},
|
||||
{
|
||||
path: "tokens",
|
||||
name: "PersonalAccessTokens",
|
||||
component: PersonalAccessTokens,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "roles",
|
||||
name: "Roles",
|
||||
component: RoleList,
|
||||
},
|
||||
{
|
||||
path: "roles/:id",
|
||||
name: "RoleDetail",
|
||||
component: RoleDetail,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/settings",
|
||||
component: SystemSettingsLayout,
|
||||
redirect: "/settings/general",
|
||||
children: [
|
||||
{
|
||||
path: "general",
|
||||
name: "GeneralSettings",
|
||||
component: GeneralSettings,
|
||||
},
|
||||
{
|
||||
path: "notification",
|
||||
name: "NotificationSettings",
|
||||
component: NotificationSettings,
|
||||
},
|
||||
],
|
||||
children: [{ path: "", name: "NotFound", component: NotFound }],
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -3,11 +3,9 @@ import { Dropdown, Menu, Tooltip, VClosePopper, VTooltip } from "floating-vue";
|
|||
import "floating-vue/dist/style.css";
|
||||
// @ts-ignore
|
||||
import VueGridLayout from "vue-grid-layout";
|
||||
import Widgets from "@/modules/dashboard/widgets";
|
||||
|
||||
export function setupComponents(app: App) {
|
||||
app.use(VueGridLayout);
|
||||
app.use(Widgets);
|
||||
|
||||
app.directive("tooltip", VTooltip);
|
||||
app.directive("close-popper", VClosePopper);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<template>404</template>
|
|
@ -3,14 +3,15 @@ import { fileURLToPath, URL } from "url";
|
|||
import { defineConfig } from "vite";
|
||||
import Vue from "@vitejs/plugin-vue";
|
||||
import VueJsx from "@vitejs/plugin-vue-jsx";
|
||||
import VueSetupExtend from "vite-plugin-vue-setup-extend";
|
||||
import Compression from "vite-compression-plugin";
|
||||
import { VitePWA } from "vite-plugin-pwa";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
Vue(),
|
||||
VueJsx(),
|
||||
VueSetupExtend(),
|
||||
Compression(),
|
||||
VitePWA({
|
||||
manifest: {
|
||||
|
|
Loading…
Reference in New Issue