mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-21 19:16:37 +08:00
feat(projects): new i18n function $t & login page and setting drawer config i18n
This commit is contained in:
parent
458e387b68
commit
854d0bcf20
29
.vscode/settings.json
vendored
29
.vscode/settings.json
vendored
@ -1,11 +1,32 @@
|
|||||||
{
|
{
|
||||||
|
"cSpell.ignorePaths": [
|
||||||
|
"package.json",
|
||||||
|
"package-lock.json",
|
||||||
|
"yarn.lock",
|
||||||
|
"pnpm-lock.yaml",
|
||||||
|
"node_modules",
|
||||||
|
"vscode-extension",
|
||||||
|
".git/objects",
|
||||||
|
".vscode",
|
||||||
|
".vscode-insiders",
|
||||||
|
"CHANGELOG.md",
|
||||||
|
"dist",
|
||||||
|
"public",
|
||||||
|
"styles"
|
||||||
|
],
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"AMAP",
|
"AMAP",
|
||||||
"antv",
|
"antv",
|
||||||
|
"bmapgl",
|
||||||
"colord",
|
"colord",
|
||||||
"echarts",
|
"echarts",
|
||||||
|
"gitee",
|
||||||
|
"gridicons",
|
||||||
"iconify",
|
"iconify",
|
||||||
|
"jsapi",
|
||||||
|
"naiveui",
|
||||||
"Sider",
|
"Sider",
|
||||||
|
"tauri",
|
||||||
"unocss",
|
"unocss",
|
||||||
"unplugin",
|
"unplugin",
|
||||||
"vditor",
|
"vditor",
|
||||||
@ -29,7 +50,13 @@
|
|||||||
"*.svg": "html"
|
"*.svg": "html"
|
||||||
},
|
},
|
||||||
"files.eol": "\n",
|
"files.eol": "\n",
|
||||||
"i18n-ally.localesPaths": ["src/locales", "src/locales/lang"],
|
"i18n-ally.displayLanguage": "zh-CN",
|
||||||
|
"i18n-ally.enabledParsers": ["ts"],
|
||||||
|
"i18n-ally.enabledFrameworks": ["vue"],
|
||||||
|
"i18n-ally.editor.preferEditor": true,
|
||||||
|
"i18n-ally.keystyle": "nested",
|
||||||
|
"i18n-ally.localesPaths": ["src/locales/lang"],
|
||||||
|
"material-icon-theme.activeIconPack": "vue",
|
||||||
"[html][css][less][scss][sass][markdown][yaml][yml][jsonc]": {
|
"[html][css][less][scss][sass][markdown][yaml][yml][jsonc]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
|
@ -13,7 +13,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
title: '分析页',
|
title: '分析页',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'icon-park-outline:analysis',
|
icon: 'icon-park-outline:analysis',
|
||||||
i18nTitle: 'message.routes.dashboard.analysis'
|
i18nTitle: 'routes.dashboard.analysis'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -24,7 +24,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
title: '工作台',
|
title: '工作台',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'icon-park-outline:workbench',
|
icon: 'icon-park-outline:workbench',
|
||||||
i18nTitle: 'message.routes.dashboard.workbench'
|
i18nTitle: 'routes.dashboard.workbench'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -32,7 +32,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
title: '仪表盘',
|
title: '仪表盘',
|
||||||
icon: 'mdi:monitor-dashboard',
|
icon: 'mdi:monitor-dashboard',
|
||||||
order: 1,
|
order: 1,
|
||||||
i18nTitle: 'message.routes.dashboard._value'
|
i18nTitle: 'routes.dashboard._value'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -46,7 +46,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'vue文档',
|
title: 'vue文档',
|
||||||
i18nTitle: 'message.routes.document.vue',
|
i18nTitle: 'routes.document.vue',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'logos:vue'
|
icon: 'logos:vue'
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'vite文档',
|
title: 'vite文档',
|
||||||
i18nTitle: 'message.routes.document.vite',
|
i18nTitle: 'routes.document.vite',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'logos:vitejs'
|
icon: 'logos:vitejs'
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'naive文档',
|
title: 'naive文档',
|
||||||
i18nTitle: 'message.routes.document.naive',
|
i18nTitle: 'routes.document.naive',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'logos:naiveui'
|
icon: 'logos:naiveui'
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '项目文档',
|
title: '项目文档',
|
||||||
i18nTitle: 'message.routes.document.project',
|
i18nTitle: 'routes.document.project',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
localIcon: 'logo'
|
localIcon: 'logo'
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
path: '/document/project-link',
|
path: '/document/project-link',
|
||||||
meta: {
|
meta: {
|
||||||
title: '项目文档(外链)',
|
title: '项目文档(外链)',
|
||||||
i18nTitle: 'message.routes.document.project-link',
|
i18nTitle: 'routes.document.project-link',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
localIcon: 'logo',
|
localIcon: 'logo',
|
||||||
href: 'https://docs.soybean.pro/'
|
href: 'https://docs.soybean.pro/'
|
||||||
@ -98,7 +98,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '文档',
|
title: '文档',
|
||||||
i18nTitle: 'message.routes.document._value',
|
i18nTitle: 'routes.document._value',
|
||||||
icon: 'mdi:file-document-multiple-outline',
|
icon: 'mdi:file-document-multiple-outline',
|
||||||
order: 2
|
order: 2
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '按钮',
|
title: '按钮',
|
||||||
i18nTitle: 'message.routes.component.button',
|
i18nTitle: 'routes.component.button',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:button-cursor'
|
icon: 'mdi:button-cursor'
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '卡片',
|
title: '卡片',
|
||||||
i18nTitle: 'message.routes.component.card',
|
i18nTitle: 'routes.component.card',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:card-outline'
|
icon: 'mdi:card-outline'
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '表格',
|
title: '表格',
|
||||||
i18nTitle: 'message.routes.component.table',
|
i18nTitle: 'routes.component.table',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:table-large'
|
icon: 'mdi:table-large'
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '组件示例',
|
title: '组件示例',
|
||||||
i18nTitle: 'message.routes.component._value',
|
i18nTitle: 'routes.component._value',
|
||||||
icon: 'cib:app-store',
|
icon: 'cib:app-store',
|
||||||
order: 3
|
order: 3
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'ECharts',
|
title: 'ECharts',
|
||||||
i18nTitle: 'message.routes.plugin.charts.echarts',
|
i18nTitle: 'routes.plugin.charts.echarts',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'simple-icons:apacheecharts'
|
icon: 'simple-icons:apacheecharts'
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'AntV',
|
title: 'AntV',
|
||||||
i18nTitle: 'message.routes.plugin.charts.antv',
|
i18nTitle: 'routes.plugin.charts.antv',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'simple-icons:antdesign'
|
icon: 'simple-icons:antdesign'
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '图表',
|
title: '图表',
|
||||||
i18nTitle: 'message.routes.plugin.charts._value',
|
i18nTitle: 'routes.plugin.charts._value',
|
||||||
icon: 'mdi:chart-areaspline'
|
icon: 'mdi:chart-areaspline'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -194,7 +194,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '地图',
|
title: '地图',
|
||||||
i18nTitle: 'message.routes.plugin.map',
|
i18nTitle: 'routes.plugin.map',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:map'
|
icon: 'mdi:map'
|
||||||
}
|
}
|
||||||
@ -205,7 +205,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '视频',
|
title: '视频',
|
||||||
i18nTitle: 'message.routes.plugin.video',
|
i18nTitle: 'routes.plugin.video',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:video'
|
icon: 'mdi:video'
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '富文本编辑器',
|
title: '富文本编辑器',
|
||||||
i18nTitle: 'message.routes.plugin.editor.quill',
|
i18nTitle: 'routes.plugin.editor.quill',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:file-document-edit-outline'
|
icon: 'mdi:file-document-edit-outline'
|
||||||
}
|
}
|
||||||
@ -232,7 +232,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'markdown编辑器',
|
title: 'markdown编辑器',
|
||||||
i18nTitle: 'message.routes.plugin.editor.markdown',
|
i18nTitle: 'routes.plugin.editor.markdown',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ri:markdown-line'
|
icon: 'ri:markdown-line'
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '编辑器',
|
title: '编辑器',
|
||||||
i18nTitle: 'message.routes.plugin.editor._value',
|
i18nTitle: 'routes.plugin.editor._value',
|
||||||
icon: 'icon-park-outline:editor'
|
icon: 'icon-park-outline:editor'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -250,7 +250,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Swiper插件',
|
title: 'Swiper插件',
|
||||||
i18nTitle: 'message.routes.plugin.swiper',
|
i18nTitle: 'routes.plugin.swiper',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'simple-icons:swiper'
|
icon: 'simple-icons:swiper'
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '剪贴板',
|
title: '剪贴板',
|
||||||
i18nTitle: 'message.routes.plugin.copy',
|
i18nTitle: 'routes.plugin.copy',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:clipboard-outline'
|
icon: 'mdi:clipboard-outline'
|
||||||
}
|
}
|
||||||
@ -272,7 +272,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '图标',
|
title: '图标',
|
||||||
i18nTitle: 'message.routes.plugin.icon',
|
i18nTitle: 'routes.plugin.icon',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
localIcon: 'custom-icon'
|
localIcon: 'custom-icon'
|
||||||
}
|
}
|
||||||
@ -283,7 +283,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '打印',
|
title: '打印',
|
||||||
i18nTitle: 'message.routes.plugin.print',
|
i18nTitle: 'routes.plugin.print',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:printer'
|
icon: 'mdi:printer'
|
||||||
}
|
}
|
||||||
@ -291,7 +291,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '插件示例',
|
title: '插件示例',
|
||||||
i18nTitle: 'message.routes.plugin._value',
|
i18nTitle: 'routes.plugin._value',
|
||||||
icon: 'clarity:plugin-line',
|
icon: 'clarity:plugin-line',
|
||||||
order: 4
|
order: 4
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限切换',
|
title: '权限切换',
|
||||||
i18nTitle: 'message.routes.auth-demo.permission',
|
i18nTitle: 'routes.auth-demo.permission',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-construction'
|
icon: 'ic:round-construction'
|
||||||
}
|
}
|
||||||
@ -318,7 +318,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '超级管理员可见',
|
title: '超级管理员可见',
|
||||||
i18nTitle: 'message.routes.auth-demo.super',
|
i18nTitle: 'routes.auth-demo.super',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-supervisor-account'
|
icon: 'ic:round-supervisor-account'
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限示例',
|
title: '权限示例',
|
||||||
i18nTitle: 'message.routes.auth-demo._value',
|
i18nTitle: 'routes.auth-demo._value',
|
||||||
icon: 'ic:baseline-security',
|
icon: 'ic:baseline-security',
|
||||||
order: 5
|
order: 5
|
||||||
}
|
}
|
||||||
@ -342,7 +342,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Tab',
|
title: 'Tab',
|
||||||
i18nTitle: 'message.routes.function.tab',
|
i18nTitle: 'routes.function.tab',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-tab'
|
icon: 'ic:round-tab'
|
||||||
}
|
}
|
||||||
@ -375,7 +375,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '功能',
|
title: '功能',
|
||||||
i18nTitle: 'message.routes.function._value',
|
i18nTitle: 'routes.function._value',
|
||||||
icon: 'icon-park-outline:all-application',
|
icon: 'icon-park-outline:all-application',
|
||||||
order: 6
|
order: 6
|
||||||
}
|
}
|
||||||
@ -391,7 +391,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '异常页403',
|
title: '异常页403',
|
||||||
i18nTitle: 'message.routes.exception.403',
|
i18nTitle: 'routes.exception.403',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-block'
|
icon: 'ic:baseline-block'
|
||||||
}
|
}
|
||||||
@ -402,7 +402,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '异常页404',
|
title: '异常页404',
|
||||||
i18nTitle: 'message.routes.exception.404',
|
i18nTitle: 'routes.exception.404',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-web-asset-off'
|
icon: 'ic:baseline-web-asset-off'
|
||||||
}
|
}
|
||||||
@ -413,14 +413,14 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '异常页500',
|
title: '异常页500',
|
||||||
i18nTitle: 'message.routes.exception.500',
|
i18nTitle: 'routes.exception.500',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-wifi-off'
|
icon: 'ic:baseline-wifi-off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
i18nTitle: 'message.routes.exception._value',
|
i18nTitle: 'routes.exception._value',
|
||||||
title: '异常页',
|
title: '异常页',
|
||||||
icon: 'ant-design:exception-outlined',
|
icon: 'ant-design:exception-outlined',
|
||||||
order: 7
|
order: 7
|
||||||
@ -442,7 +442,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '二级菜单',
|
title: '二级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second',
|
i18nTitle: 'routes.multi-menu.first.second',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
@ -458,7 +458,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '三级菜单',
|
title: '三级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second-new.third',
|
i18nTitle: 'routes.multi-menu.first.second-new.third',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
@ -466,21 +466,21 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '二级菜单(有子菜单)',
|
title: '二级菜单(有子菜单)',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second-new._value',
|
i18nTitle: 'routes.multi-menu.first.second-new._value',
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '一级菜单',
|
title: '一级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first._value',
|
i18nTitle: 'routes.multi-menu.first._value',
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '多级菜单',
|
title: '多级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu._value',
|
i18nTitle: 'routes.multi-menu._value',
|
||||||
icon: 'carbon:menu',
|
icon: 'carbon:menu',
|
||||||
order: 8
|
order: 8
|
||||||
}
|
}
|
||||||
@ -496,7 +496,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限管理',
|
title: '权限管理',
|
||||||
i18nTitle: 'message.routes.management.auth',
|
i18nTitle: 'routes.management.auth',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-security'
|
icon: 'ic:baseline-security'
|
||||||
}
|
}
|
||||||
@ -507,7 +507,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '角色管理',
|
title: '角色管理',
|
||||||
i18nTitle: 'message.routes.management.role',
|
i18nTitle: 'routes.management.role',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'carbon:user-role'
|
icon: 'carbon:user-role'
|
||||||
}
|
}
|
||||||
@ -518,7 +518,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '用户管理',
|
title: '用户管理',
|
||||||
i18nTitle: 'message.routes.management.user',
|
i18nTitle: 'routes.management.user',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-manage-accounts'
|
icon: 'ic:round-manage-accounts'
|
||||||
}
|
}
|
||||||
@ -529,7 +529,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '路由管理',
|
title: '路由管理',
|
||||||
i18nTitle: 'message.routes.management.route',
|
i18nTitle: 'routes.management.route',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'material-symbols:route'
|
icon: 'material-symbols:route'
|
||||||
}
|
}
|
||||||
@ -537,7 +537,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '系统管理',
|
title: '系统管理',
|
||||||
i18nTitle: 'message.routes.management._value',
|
i18nTitle: 'routes.management._value',
|
||||||
icon: 'carbon:cloud-service-management',
|
icon: 'carbon:cloud-service-management',
|
||||||
order: 9
|
order: 9
|
||||||
}
|
}
|
||||||
@ -548,7 +548,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '关于',
|
title: '关于',
|
||||||
i18nTitle: 'message.routes.about',
|
i18nTitle: 'routes.about',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
singleLayout: 'basic',
|
singleLayout: 'basic',
|
||||||
@ -571,7 +571,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
title: '分析页',
|
title: '分析页',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'icon-park-outline:analysis',
|
icon: 'icon-park-outline:analysis',
|
||||||
i18nTitle: 'message.routes.dashboard.analysis'
|
i18nTitle: 'routes.dashboard.analysis'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -582,7 +582,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
title: '工作台',
|
title: '工作台',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'icon-park-outline:workbench',
|
icon: 'icon-park-outline:workbench',
|
||||||
i18nTitle: 'message.routes.dashboard.workbench'
|
i18nTitle: 'routes.dashboard.workbench'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -590,7 +590,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
title: '仪表盘',
|
title: '仪表盘',
|
||||||
icon: 'mdi:monitor-dashboard',
|
icon: 'mdi:monitor-dashboard',
|
||||||
order: 1,
|
order: 1,
|
||||||
i18nTitle: 'message.routes.dashboard._value'
|
i18nTitle: 'routes.dashboard._value'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -604,7 +604,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'vue文档',
|
title: 'vue文档',
|
||||||
i18nTitle: 'message.routes.document.vue',
|
i18nTitle: 'routes.document.vue',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'logos:vue'
|
icon: 'logos:vue'
|
||||||
}
|
}
|
||||||
@ -615,7 +615,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'vite文档',
|
title: 'vite文档',
|
||||||
i18nTitle: 'message.routes.document.vite',
|
i18nTitle: 'routes.document.vite',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'logos:vitejs'
|
icon: 'logos:vitejs'
|
||||||
}
|
}
|
||||||
@ -626,7 +626,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'naive文档',
|
title: 'naive文档',
|
||||||
i18nTitle: 'message.routes.document.naive',
|
i18nTitle: 'routes.document.naive',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'logos:naiveui'
|
icon: 'logos:naiveui'
|
||||||
}
|
}
|
||||||
@ -637,7 +637,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '项目文档',
|
title: '项目文档',
|
||||||
i18nTitle: 'message.routes.document.project',
|
i18nTitle: 'routes.document.project',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
localIcon: 'logo'
|
localIcon: 'logo'
|
||||||
}
|
}
|
||||||
@ -647,7 +647,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
path: '/document/project-link',
|
path: '/document/project-link',
|
||||||
meta: {
|
meta: {
|
||||||
title: '项目文档(外链)',
|
title: '项目文档(外链)',
|
||||||
i18nTitle: 'message.routes.document.project-link',
|
i18nTitle: 'routes.document.project-link',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
localIcon: 'logo',
|
localIcon: 'logo',
|
||||||
href: 'https://docs.soybean.pro/'
|
href: 'https://docs.soybean.pro/'
|
||||||
@ -656,7 +656,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '文档',
|
title: '文档',
|
||||||
i18nTitle: 'message.routes.document._value',
|
i18nTitle: 'routes.document._value',
|
||||||
icon: 'mdi:file-document-multiple-outline',
|
icon: 'mdi:file-document-multiple-outline',
|
||||||
order: 2
|
order: 2
|
||||||
}
|
}
|
||||||
@ -672,7 +672,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '按钮',
|
title: '按钮',
|
||||||
i18nTitle: 'message.routes.component.button',
|
i18nTitle: 'routes.component.button',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:button-cursor'
|
icon: 'mdi:button-cursor'
|
||||||
}
|
}
|
||||||
@ -683,7 +683,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '卡片',
|
title: '卡片',
|
||||||
i18nTitle: 'message.routes.component.card',
|
i18nTitle: 'routes.component.card',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:card-outline'
|
icon: 'mdi:card-outline'
|
||||||
}
|
}
|
||||||
@ -694,7 +694,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '表格',
|
title: '表格',
|
||||||
i18nTitle: 'message.routes.component.table',
|
i18nTitle: 'routes.component.table',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:table-large'
|
icon: 'mdi:table-large'
|
||||||
}
|
}
|
||||||
@ -702,7 +702,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '组件示例',
|
title: '组件示例',
|
||||||
i18nTitle: 'message.routes.component._value',
|
i18nTitle: 'routes.component._value',
|
||||||
icon: 'cib:app-store',
|
icon: 'cib:app-store',
|
||||||
order: 3
|
order: 3
|
||||||
}
|
}
|
||||||
@ -723,7 +723,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'ECharts',
|
title: 'ECharts',
|
||||||
i18nTitle: 'message.routes.plugin.charts.echarts',
|
i18nTitle: 'routes.plugin.charts.echarts',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'simple-icons:apacheecharts'
|
icon: 'simple-icons:apacheecharts'
|
||||||
}
|
}
|
||||||
@ -734,7 +734,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'AntV',
|
title: 'AntV',
|
||||||
i18nTitle: 'message.routes.plugin.charts.antv',
|
i18nTitle: 'routes.plugin.charts.antv',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'simple-icons:antdesign'
|
icon: 'simple-icons:antdesign'
|
||||||
}
|
}
|
||||||
@ -742,7 +742,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '图表',
|
title: '图表',
|
||||||
i18nTitle: 'message.routes.plugin.charts._value',
|
i18nTitle: 'routes.plugin.charts._value',
|
||||||
icon: 'mdi:chart-areaspline'
|
icon: 'mdi:chart-areaspline'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -752,7 +752,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '地图',
|
title: '地图',
|
||||||
i18nTitle: 'message.routes.plugin.map',
|
i18nTitle: 'routes.plugin.map',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:map'
|
icon: 'mdi:map'
|
||||||
}
|
}
|
||||||
@ -763,7 +763,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '视频',
|
title: '视频',
|
||||||
i18nTitle: 'message.routes.plugin.video',
|
i18nTitle: 'routes.plugin.video',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:video'
|
icon: 'mdi:video'
|
||||||
}
|
}
|
||||||
@ -779,7 +779,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '富文本编辑器',
|
title: '富文本编辑器',
|
||||||
i18nTitle: 'message.routes.plugin.editor.quill',
|
i18nTitle: 'routes.plugin.editor.quill',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:file-document-edit-outline'
|
icon: 'mdi:file-document-edit-outline'
|
||||||
}
|
}
|
||||||
@ -790,7 +790,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'markdown编辑器',
|
title: 'markdown编辑器',
|
||||||
i18nTitle: 'message.routes.plugin.editor.markdown',
|
i18nTitle: 'routes.plugin.editor.markdown',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ri:markdown-line'
|
icon: 'ri:markdown-line'
|
||||||
}
|
}
|
||||||
@ -798,7 +798,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '编辑器',
|
title: '编辑器',
|
||||||
i18nTitle: 'message.routes.plugin.editor._value',
|
i18nTitle: 'routes.plugin.editor._value',
|
||||||
icon: 'icon-park-outline:editor'
|
icon: 'icon-park-outline:editor'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -808,7 +808,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Swiper插件',
|
title: 'Swiper插件',
|
||||||
i18nTitle: 'message.routes.plugin.swiper',
|
i18nTitle: 'routes.plugin.swiper',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'simple-icons:swiper'
|
icon: 'simple-icons:swiper'
|
||||||
}
|
}
|
||||||
@ -819,7 +819,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '剪贴板',
|
title: '剪贴板',
|
||||||
i18nTitle: 'message.routes.plugin.copy',
|
i18nTitle: 'routes.plugin.copy',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:clipboard-outline'
|
icon: 'mdi:clipboard-outline'
|
||||||
}
|
}
|
||||||
@ -830,7 +830,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '图标',
|
title: '图标',
|
||||||
i18nTitle: 'message.routes.plugin.icon',
|
i18nTitle: 'routes.plugin.icon',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
localIcon: 'custom-icon'
|
localIcon: 'custom-icon'
|
||||||
}
|
}
|
||||||
@ -841,7 +841,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '打印',
|
title: '打印',
|
||||||
i18nTitle: 'message.routes.plugin.print',
|
i18nTitle: 'routes.plugin.print',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:printer'
|
icon: 'mdi:printer'
|
||||||
}
|
}
|
||||||
@ -849,7 +849,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '插件示例',
|
title: '插件示例',
|
||||||
i18nTitle: 'message.routes.plugin._value',
|
i18nTitle: 'routes.plugin._value',
|
||||||
icon: 'clarity:plugin-line',
|
icon: 'clarity:plugin-line',
|
||||||
order: 4
|
order: 4
|
||||||
}
|
}
|
||||||
@ -865,7 +865,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限切换',
|
title: '权限切换',
|
||||||
i18nTitle: 'message.routes.auth-demo.permission',
|
i18nTitle: 'routes.auth-demo.permission',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-construction'
|
icon: 'ic:round-construction'
|
||||||
}
|
}
|
||||||
@ -876,7 +876,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '超级管理员可见',
|
title: '超级管理员可见',
|
||||||
i18nTitle: 'message.routes.auth-demo.super',
|
i18nTitle: 'routes.auth-demo.super',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-supervisor-account'
|
icon: 'ic:round-supervisor-account'
|
||||||
}
|
}
|
||||||
@ -884,7 +884,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限示例',
|
title: '权限示例',
|
||||||
i18nTitle: 'message.routes.auth-demo._value',
|
i18nTitle: 'routes.auth-demo._value',
|
||||||
icon: 'ic:baseline-security',
|
icon: 'ic:baseline-security',
|
||||||
order: 5
|
order: 5
|
||||||
}
|
}
|
||||||
@ -900,7 +900,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Tab',
|
title: 'Tab',
|
||||||
i18nTitle: 'message.routes.function.tab',
|
i18nTitle: 'routes.function.tab',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-tab'
|
icon: 'ic:round-tab'
|
||||||
}
|
}
|
||||||
@ -933,7 +933,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '功能',
|
title: '功能',
|
||||||
i18nTitle: 'message.routes.function._value',
|
i18nTitle: 'routes.function._value',
|
||||||
icon: 'icon-park-outline:all-application',
|
icon: 'icon-park-outline:all-application',
|
||||||
order: 6
|
order: 6
|
||||||
}
|
}
|
||||||
@ -949,7 +949,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '异常页403',
|
title: '异常页403',
|
||||||
i18nTitle: 'message.routes.exception.403',
|
i18nTitle: 'routes.exception.403',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-block'
|
icon: 'ic:baseline-block'
|
||||||
}
|
}
|
||||||
@ -960,7 +960,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '异常页404',
|
title: '异常页404',
|
||||||
i18nTitle: 'message.routes.exception.404',
|
i18nTitle: 'routes.exception.404',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-web-asset-off'
|
icon: 'ic:baseline-web-asset-off'
|
||||||
}
|
}
|
||||||
@ -971,14 +971,14 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '异常页500',
|
title: '异常页500',
|
||||||
i18nTitle: 'message.routes.exception.500',
|
i18nTitle: 'routes.exception.500',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-wifi-off'
|
icon: 'ic:baseline-wifi-off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
i18nTitle: 'message.routes.exception._value',
|
i18nTitle: 'routes.exception._value',
|
||||||
title: '异常页',
|
title: '异常页',
|
||||||
icon: 'ant-design:exception-outlined',
|
icon: 'ant-design:exception-outlined',
|
||||||
order: 7
|
order: 7
|
||||||
@ -1000,7 +1000,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '二级菜单',
|
title: '二级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second',
|
i18nTitle: 'routes.multi-menu.first.second',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
@ -1016,7 +1016,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '三级菜单',
|
title: '三级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second-new.third',
|
i18nTitle: 'routes.multi-menu.first.second-new.third',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
@ -1024,21 +1024,21 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '二级菜单(有子菜单)',
|
title: '二级菜单(有子菜单)',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second-new._value',
|
i18nTitle: 'routes.multi-menu.first.second-new._value',
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '一级菜单',
|
title: '一级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first._value',
|
i18nTitle: 'routes.multi-menu.first._value',
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '多级菜单',
|
title: '多级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu._value',
|
i18nTitle: 'routes.multi-menu._value',
|
||||||
icon: 'carbon:menu',
|
icon: 'carbon:menu',
|
||||||
order: 8
|
order: 8
|
||||||
}
|
}
|
||||||
@ -1054,7 +1054,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限管理',
|
title: '权限管理',
|
||||||
i18nTitle: 'message.routes.management.auth',
|
i18nTitle: 'routes.management.auth',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-security'
|
icon: 'ic:baseline-security'
|
||||||
}
|
}
|
||||||
@ -1065,7 +1065,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '角色管理',
|
title: '角色管理',
|
||||||
i18nTitle: 'message.routes.management.role',
|
i18nTitle: 'routes.management.role',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'carbon:user-role'
|
icon: 'carbon:user-role'
|
||||||
}
|
}
|
||||||
@ -1076,7 +1076,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '用户管理',
|
title: '用户管理',
|
||||||
i18nTitle: 'message.routes.management.user',
|
i18nTitle: 'routes.management.user',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-manage-accounts'
|
icon: 'ic:round-manage-accounts'
|
||||||
}
|
}
|
||||||
@ -1087,7 +1087,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '路由管理',
|
title: '路由管理',
|
||||||
i18nTitle: 'message.routes.management.route',
|
i18nTitle: 'routes.management.route',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'material-symbols:route'
|
icon: 'material-symbols:route'
|
||||||
}
|
}
|
||||||
@ -1095,7 +1095,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '系统管理',
|
title: '系统管理',
|
||||||
i18nTitle: 'message.routes.management._value',
|
i18nTitle: 'routes.management._value',
|
||||||
icon: 'carbon:cloud-service-management',
|
icon: 'carbon:cloud-service-management',
|
||||||
order: 9
|
order: 9
|
||||||
}
|
}
|
||||||
@ -1106,7 +1106,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '关于',
|
title: '关于',
|
||||||
i18nTitle: 'message.routes.about',
|
i18nTitle: 'routes.about',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
singleLayout: 'basic',
|
singleLayout: 'basic',
|
||||||
@ -1129,7 +1129,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
title: '分析页',
|
title: '分析页',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'icon-park-outline:analysis',
|
icon: 'icon-park-outline:analysis',
|
||||||
i18nTitle: 'message.routes.dashboard.analysis'
|
i18nTitle: 'routes.dashboard.analysis'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1140,7 +1140,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
title: '工作台',
|
title: '工作台',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'icon-park-outline:workbench',
|
icon: 'icon-park-outline:workbench',
|
||||||
i18nTitle: 'message.routes.dashboard.workbench'
|
i18nTitle: 'routes.dashboard.workbench'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -1148,7 +1148,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
title: '仪表盘',
|
title: '仪表盘',
|
||||||
icon: 'mdi:monitor-dashboard',
|
icon: 'mdi:monitor-dashboard',
|
||||||
order: 1,
|
order: 1,
|
||||||
i18nTitle: 'message.routes.dashboard._value'
|
i18nTitle: 'routes.dashboard._value'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1162,7 +1162,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限切换',
|
title: '权限切换',
|
||||||
i18nTitle: 'message.routes.auth-demo.permission',
|
i18nTitle: 'routes.auth-demo.permission',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-construction'
|
icon: 'ic:round-construction'
|
||||||
}
|
}
|
||||||
@ -1173,7 +1173,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '超级管理员可见',
|
title: '超级管理员可见',
|
||||||
i18nTitle: 'message.routes.auth-demo.super',
|
i18nTitle: 'routes.auth-demo.super',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-supervisor-account'
|
icon: 'ic:round-supervisor-account'
|
||||||
}
|
}
|
||||||
@ -1181,7 +1181,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限示例',
|
title: '权限示例',
|
||||||
i18nTitle: 'message.routes.auth-demo._value',
|
i18nTitle: 'routes.auth-demo._value',
|
||||||
icon: 'ic:baseline-security',
|
icon: 'ic:baseline-security',
|
||||||
order: 5
|
order: 5
|
||||||
}
|
}
|
||||||
@ -1202,7 +1202,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '二级菜单',
|
title: '二级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second',
|
i18nTitle: 'routes.multi-menu.first.second',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
@ -1218,7 +1218,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '三级菜单',
|
title: '三级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second-new.third',
|
i18nTitle: 'routes.multi-menu.first.second-new.third',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
@ -1226,21 +1226,21 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '二级菜单(有子菜单)',
|
title: '二级菜单(有子菜单)',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second-new._value',
|
i18nTitle: 'routes.multi-menu.first.second-new._value',
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '一级菜单',
|
title: '一级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first._value',
|
i18nTitle: 'routes.multi-menu.first._value',
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '多级菜单',
|
title: '多级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu._value',
|
i18nTitle: 'routes.multi-menu._value',
|
||||||
icon: 'carbon:menu',
|
icon: 'carbon:menu',
|
||||||
order: 8
|
order: 8
|
||||||
}
|
}
|
||||||
@ -1251,7 +1251,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '关于',
|
title: '关于',
|
||||||
i18nTitle: 'message.routes.about',
|
i18nTitle: 'routes.about',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
singleLayout: 'basic',
|
singleLayout: 'basic',
|
||||||
|
@ -11,17 +11,15 @@
|
|||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="text-28px font-500 text-#646464">{{ title }}</h2>
|
<h2 class="text-28px font-500 text-#646464">{{ $t('system.title') }}</h2>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAppInfo } from '@/composables';
|
|
||||||
import { sessionStg, getRgbOfColor } from '@/utils';
|
import { sessionStg, getRgbOfColor } from '@/utils';
|
||||||
|
import { $t } from '@/locales';
|
||||||
import themeSettings from '@/settings/theme.json';
|
import themeSettings from '@/settings/theme.json';
|
||||||
|
|
||||||
const { title } = useAppInfo();
|
|
||||||
|
|
||||||
const lodingClasses = [
|
const lodingClasses = [
|
||||||
'left-0 top-0',
|
'left-0 top-0',
|
||||||
'left-0 bottom-0 animate-delay-500',
|
'left-0 bottom-0 animate-delay-500',
|
||||||
|
@ -2,26 +2,6 @@ import UAParser from 'ua-parser-js';
|
|||||||
import { useAuthStore } from '@/store';
|
import { useAuthStore } from '@/store';
|
||||||
import { isArray, isString } from '@/utils';
|
import { isArray, isString } from '@/utils';
|
||||||
|
|
||||||
interface AppInfo {
|
|
||||||
/** 项目名称 */
|
|
||||||
name: string;
|
|
||||||
/** 项目标题 */
|
|
||||||
title: string;
|
|
||||||
/** 项目描述 */
|
|
||||||
desc: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 项目信息 */
|
|
||||||
export function useAppInfo(): AppInfo {
|
|
||||||
const { VITE_APP_NAME: name, VITE_APP_TITLE: title, VITE_APP_DESC: desc } = import.meta.env;
|
|
||||||
|
|
||||||
return {
|
|
||||||
name,
|
|
||||||
title,
|
|
||||||
desc
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 获取设备信息 */
|
/** 获取设备信息 */
|
||||||
export function useDeviceInfo() {
|
export function useDeviceInfo() {
|
||||||
const parser = new UAParser();
|
const parser = new UAParser();
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
|
import { $t } from '@/locales';
|
||||||
import { transformObjectToOption } from './_shared';
|
import { transformObjectToOption } from './_shared';
|
||||||
|
|
||||||
export const loginModuleLabels: Record<UnionKey.LoginModule, string> = {
|
export const loginModuleLabels: Record<UnionKey.LoginModule, string> = {
|
||||||
'pwd-login': '账密登录',
|
'pwd-login': $t('page.login.pwdLogin.title'),
|
||||||
'code-login': '手机验证码登录',
|
'code-login': $t('page.login.codeLogin.title'),
|
||||||
register: '注册',
|
register: $t('page.login.register.title'),
|
||||||
'reset-pwd': '重置密码',
|
'reset-pwd': $t('page.login.resetPwd.title'),
|
||||||
'bind-wechat': '微信绑定'
|
'bind-wechat': $t('page.login.bindWeChat.title')
|
||||||
};
|
};
|
||||||
|
|
||||||
export const userRoleLabels: Record<Auth.RoleType, string> = {
|
export const userRoleLabels: Record<Auth.RoleType, string> = {
|
||||||
super: '超级管理员',
|
super: $t('page.login.pwdLogin.superAdmin'),
|
||||||
admin: '管理员',
|
admin: $t('page.login.pwdLogin.admin'),
|
||||||
user: '普通用户'
|
user: $t('page.login.pwdLogin.user')
|
||||||
};
|
};
|
||||||
export const userRoleOptions = transformObjectToOption(userRoleLabels);
|
export const userRoleOptions = transformObjectToOption(userRoleLabels);
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ import { routePath } from '@/router';
|
|||||||
import { useRouteStore, useThemeStore } from '@/store';
|
import { useRouteStore, useThemeStore } from '@/store';
|
||||||
import { useRouterPush } from '@/composables';
|
import { useRouterPush } from '@/composables';
|
||||||
import { getBreadcrumbByRouteKey } from '@/utils';
|
import { getBreadcrumbByRouteKey } from '@/utils';
|
||||||
import { t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
defineOptions({ name: 'GlobalBreadcrumb' });
|
defineOptions({ name: 'GlobalBreadcrumb' });
|
||||||
|
|
||||||
@ -48,8 +48,8 @@ const breadcrumbs = computed(() =>
|
|||||||
getBreadcrumbByRouteKey(route.name as string, routeStore.menus as App.GlobalMenuOption[], routePath('root')).map(
|
getBreadcrumbByRouteKey(route.name as string, routeStore.menus as App.GlobalMenuOption[], routePath('root')).map(
|
||||||
item => ({
|
item => ({
|
||||||
...item,
|
...item,
|
||||||
label: item.i18nTitle ? t(item.i18nTitle) : item.label,
|
label: item.i18nTitle ? $t(item.i18nTitle) : item.label,
|
||||||
options: item.options?.map(oItem => ({ ...oItem, label: oItem.i18nTitle ? t(oItem.i18nTitle) : oItem.label }))
|
options: item.options?.map(oItem => ({ ...oItem, label: oItem.i18nTitle ? $t(oItem.i18nTitle) : oItem.label }))
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -15,7 +15,7 @@ import { localStg } from '@/utils';
|
|||||||
const theme = useThemeStore();
|
const theme = useThemeStore();
|
||||||
const { locale } = useI18n();
|
const { locale } = useI18n();
|
||||||
|
|
||||||
const language = ref<I18nType.langType>(localStg.get('lang') || 'zh-CN');
|
const language = ref<I18nType.LangType>(localStg.get('lang') || 'zh-CN');
|
||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
label: '中文',
|
label: '中文',
|
||||||
@ -31,9 +31,9 @@ const options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
const handleSelect = (key: string) => {
|
const handleSelect = (key: string) => {
|
||||||
language.value = key as I18nType.langType;
|
language.value = key as I18nType.LangType;
|
||||||
locale.value = key;
|
locale.value = key;
|
||||||
localStg.set('lang', key as I18nType.langType);
|
localStg.set('lang', key as I18nType.LangType);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
<router-link :to="routeHomePath" class="flex-center w-full nowrap-hidden">
|
<router-link :to="routeHomePath" class="flex-center w-full nowrap-hidden">
|
||||||
<system-logo class="text-32px text-primary" />
|
<system-logo class="text-32px text-primary" />
|
||||||
<h2 v-show="showTitle" class="pl-8px text-16px font-bold text-primary transition duration-300 ease-in-out">
|
<h2 v-show="showTitle" class="pl-8px text-16px font-bold text-primary transition duration-300 ease-in-out">
|
||||||
{{ t('message.system.title') }}
|
{{ $t('system.title') }}
|
||||||
</h2>
|
</h2>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { routePath } from '@/router';
|
import { routePath } from '@/router';
|
||||||
import { t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
defineOptions({ name: 'GlobalLogo' });
|
defineOptions({ name: 'GlobalLogo' });
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
:style="{ width: showDrawer ? theme.sider.mixChildMenuWidth + 'px' : '0px' }"
|
:style="{ width: showDrawer ? theme.sider.mixChildMenuWidth + 'px' : '0px' }"
|
||||||
>
|
>
|
||||||
<header class="header-height flex-y-center justify-between" :style="{ height: theme.header.height + 'px' }">
|
<header class="header-height flex-y-center justify-between" :style="{ height: theme.header.height + 'px' }">
|
||||||
<h2 class="text-primary pl-8px text-16px font-bold">{{ title }}</h2>
|
<h2 class="text-primary pl-8px text-16px font-bold">{{ $t('system.title') }}</h2>
|
||||||
<div class="px-8px text-16px text-gray-600 cursor-pointer" @click="app.toggleMixSiderFixed">
|
<div class="px-8px text-16px text-gray-600 cursor-pointer" @click="app.toggleMixSiderFixed">
|
||||||
<icon-mdi-pin-off v-if="app.mixSiderFixed" />
|
<icon-mdi-pin-off v-if="app.mixSiderFixed" />
|
||||||
<icon-mdi-pin v-else />
|
<icon-mdi-pin v-else />
|
||||||
@ -35,8 +35,9 @@ import { computed, ref, watch } from 'vue';
|
|||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import type { MenuOption } from 'naive-ui';
|
import type { MenuOption } from 'naive-ui';
|
||||||
import { useAppStore, useThemeStore } from '@/store';
|
import { useAppStore, useThemeStore } from '@/store';
|
||||||
import { useAppInfo, useRouterPush } from '@/composables';
|
import { useRouterPush } from '@/composables';
|
||||||
import { getActiveKeyPathsOfMenus } from '@/utils';
|
import { getActiveKeyPathsOfMenus } from '@/utils';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
defineOptions({ name: 'MixMenuDrawer' });
|
defineOptions({ name: 'MixMenuDrawer' });
|
||||||
|
|
||||||
@ -53,7 +54,6 @@ const route = useRoute();
|
|||||||
const app = useAppStore();
|
const app = useAppStore();
|
||||||
const theme = useThemeStore();
|
const theme = useThemeStore();
|
||||||
const { routerPush } = useRouterPush();
|
const { routerPush } = useRouterPush();
|
||||||
const { title } = useAppInfo();
|
|
||||||
|
|
||||||
const showDrawer = computed(() => (props.visible && props.menus.length) || app.mixSiderFixed);
|
const showDrawer = computed(() => (props.visible && props.menus.length) || app.mixSiderFixed);
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import { useRouterPush } from '@/composables';
|
|||||||
import { useBoolean } from '@/hooks';
|
import { useBoolean } from '@/hooks';
|
||||||
import { translateMenuLabel } from '@/utils';
|
import { translateMenuLabel } from '@/utils';
|
||||||
import { GlobalLogo } from '@/layouts/common';
|
import { GlobalLogo } from '@/layouts/common';
|
||||||
import { t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import { MixMenuCollapse, MixMenuDetail, MixMenuDrawer } from './components';
|
import { MixMenuCollapse, MixMenuDetail, MixMenuDrawer } from './components';
|
||||||
|
|
||||||
defineOptions({ name: 'VerticalMixSider' });
|
defineOptions({ name: 'VerticalMixSider' });
|
||||||
@ -53,7 +53,7 @@ const firstDegreeMenus = computed(() =>
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
routeName,
|
routeName,
|
||||||
label: i18nTitle ? t(i18nTitle) : label,
|
label: i18nTitle ? $t(i18nTitle) : label,
|
||||||
icon,
|
icon,
|
||||||
hasChildren
|
hasChildren
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
class="inline-block align-text-bottom text-16px"
|
class="inline-block align-text-bottom text-16px"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
{{ item.meta.i18nTitle ? t(item.meta.i18nTitle) : item.meta.title }}
|
{{ item.meta.i18nTitle ? $t(item.meta.i18nTitle) : item.meta.title }}
|
||||||
</PageTab>
|
</PageTab>
|
||||||
</div>
|
</div>
|
||||||
<context-menu
|
<context-menu
|
||||||
@ -36,7 +36,7 @@
|
|||||||
import { computed, nextTick, reactive, ref, watch } from 'vue';
|
import { computed, nextTick, reactive, ref, watch } from 'vue';
|
||||||
import { PageTab } from '@soybeanjs/vue-materials';
|
import { PageTab } from '@soybeanjs/vue-materials';
|
||||||
import { useTabStore, useThemeStore } from '@/store';
|
import { useTabStore, useThemeStore } from '@/store';
|
||||||
import { t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import { ContextMenu } from './components';
|
import { ContextMenu } from './components';
|
||||||
|
|
||||||
defineOptions({ name: 'TabDetail' });
|
defineOptions({ name: 'TabDetail' });
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-divider title-placement="center">主题模式</n-divider>
|
<n-divider title-placement="center">{{ $t('layout.settingDrawer.themeModeTitle') }}</n-divider>
|
||||||
<n-space vertical size="large">
|
<n-space vertical size="large">
|
||||||
<setting-menu label="深色主题">
|
<setting-menu :label="$t('layout.settingDrawer.darkMode')">
|
||||||
<n-switch :value="theme.darkMode" @update:value="theme.setDarkMode">
|
<n-switch :value="theme.darkMode" @update:value="theme.setDarkMode">
|
||||||
<template #checked>
|
<template #checked>
|
||||||
<icon-mdi-white-balance-sunny class="text-14px text-white" />
|
<icon-mdi-white-balance-sunny class="text-14px text-white" />
|
||||||
@ -11,7 +11,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</n-switch>
|
</n-switch>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="跟随系统">
|
<setting-menu :label="$t('layout.settingDrawer.followSystemTheme')">
|
||||||
<n-switch :value="theme.followSystemTheme" @update:value="theme.setFollowSystemTheme">
|
<n-switch :value="theme.followSystemTheme" @update:value="theme.setFollowSystemTheme">
|
||||||
<template #checked>
|
<template #checked>
|
||||||
<icon-ic-baseline-do-not-disturb class="text-14px text-white" />
|
<icon-ic-baseline-do-not-disturb class="text-14px text-white" />
|
||||||
@ -21,7 +21,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</n-switch>
|
</n-switch>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="自定义暗黑主题动画过渡">
|
<setting-menu :label="$t('layout.settingDrawer.isCustomizeDarkModeTransition')">
|
||||||
<n-switch :value="theme.isCustomizeDarkModeTransition" @update:value="theme.setIsCustomizeDarkModeTransition">
|
<n-switch :value="theme.isCustomizeDarkModeTransition" @update:value="theme.setIsCustomizeDarkModeTransition">
|
||||||
<template #checked>
|
<template #checked>
|
||||||
<icon-ic-baseline-do-not-disturb class="text-14px text-white" />
|
<icon-ic-baseline-do-not-disturb class="text-14px text-white" />
|
||||||
@ -31,13 +31,13 @@
|
|||||||
</template>
|
</template>
|
||||||
</n-switch>
|
</n-switch>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="侧边栏深色">
|
<setting-menu :label="$t('layout.settingDrawer.sider.inverted')">
|
||||||
<n-switch :value="theme.sider.inverted" @update:value="theme.setSiderInverted" />
|
<n-switch :value="theme.sider.inverted" @update:value="theme.setSiderInverted" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="头部深色">
|
<setting-menu :label="$t('layout.settingDrawer.header.inverted')">
|
||||||
<n-switch :value="theme.header.inverted" @update:value="theme.setHeaderInverted" />
|
<n-switch :value="theme.header.inverted" @update:value="theme.setHeaderInverted" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="底部深色">
|
<setting-menu :label="$t('layout.settingDrawer.footer.inverted')">
|
||||||
<n-switch :value="theme.footer.inverted" @update:value="theme.setFooterInverted" />
|
<n-switch :value="theme.footer.inverted" @update:value="theme.setFooterInverted" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
</n-space>
|
</n-space>
|
||||||
@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useThemeStore } from '@/store';
|
import { useThemeStore } from '@/store';
|
||||||
|
import { $t } from '@/locales';
|
||||||
import SettingMenu from '../setting-menu/index.vue';
|
import SettingMenu from '../setting-menu/index.vue';
|
||||||
|
|
||||||
defineOptions({ name: 'DarkMode' });
|
defineOptions({ name: 'DarkMode' });
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-divider title-placement="center">布局模式</n-divider>
|
<n-divider title-placement="center">{{ $t('layout.settingDrawer.layoutModelTitle') }}</n-divider>
|
||||||
<n-space justify="space-around" :wrap="true" :size="24" class="px-12px">
|
<n-space justify="space-around" :wrap="true" :size="24" class="px-12px">
|
||||||
<layout-card
|
<layout-card
|
||||||
v-for="item in theme.layout.modeList"
|
v-for="item in theme.layout.modeList"
|
||||||
@ -43,6 +43,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useThemeStore } from '@/store';
|
import { useThemeStore } from '@/store';
|
||||||
|
import { $t } from '@/locales';
|
||||||
import { LayoutCard } from './components';
|
import { LayoutCard } from './components';
|
||||||
|
|
||||||
defineOptions({ name: 'LayoutMode' });
|
defineOptions({ name: 'LayoutMode' });
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-divider title-placement="center">界面功能</n-divider>
|
<n-divider title-placement="center">{{ $t('layout.settingDrawer.pageFunctionsTitle') }}</n-divider>
|
||||||
<n-space vertical size="large">
|
<n-space vertical size="large">
|
||||||
<setting-menu label="滚动模式">
|
<setting-menu :label="$t('layout.settingDrawer.scrollMode')">
|
||||||
<n-select
|
<n-select
|
||||||
class="w-120px"
|
class="w-120px"
|
||||||
size="small"
|
size="small"
|
||||||
@ -10,10 +10,10 @@
|
|||||||
@update:value="theme.setScrollMode"
|
@update:value="theme.setScrollMode"
|
||||||
/>
|
/>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="固定头部和多页签">
|
<setting-menu :label="$t('layout.settingDrawer.fixedHeaderAndTab')">
|
||||||
<n-switch :value="theme.fixedHeaderAndTab" @update:value="theme.setIsFixedHeaderAndTab" />
|
<n-switch :value="theme.fixedHeaderAndTab" @update:value="theme.setIsFixedHeaderAndTab" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="顶部菜单位置">
|
<setting-menu :label="$t('layout.settingDrawer.menu.horizontalPosition')">
|
||||||
<n-select
|
<n-select
|
||||||
class="w-120px"
|
class="w-120px"
|
||||||
size="small"
|
size="small"
|
||||||
@ -22,7 +22,7 @@
|
|||||||
@update:value="theme.setHorizontalMenuPosition"
|
@update:value="theme.setHorizontalMenuPosition"
|
||||||
/>
|
/>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="头部高度">
|
<setting-menu :label="$t('layout.settingDrawer.header.height')">
|
||||||
<n-input-number
|
<n-input-number
|
||||||
class="w-120px"
|
class="w-120px"
|
||||||
size="small"
|
size="small"
|
||||||
@ -31,7 +31,7 @@
|
|||||||
@update:value="theme.setHeaderHeight"
|
@update:value="theme.setHeaderHeight"
|
||||||
/>
|
/>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="多页签高度">
|
<setting-menu :label="$t('layout.settingDrawer.tab.height')">
|
||||||
<n-input-number
|
<n-input-number
|
||||||
class="w-120px"
|
class="w-120px"
|
||||||
size="small"
|
size="small"
|
||||||
@ -40,10 +40,10 @@
|
|||||||
@update:value="theme.setTabHeight"
|
@update:value="theme.setTabHeight"
|
||||||
/>
|
/>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="多页签缓存">
|
<setting-menu :label="$t('layout.settingDrawer.tab.isCache')">
|
||||||
<n-switch :value="theme.tab.isCache" @update:value="theme.setTabIsCache" />
|
<n-switch :value="theme.tab.isCache" @update:value="theme.setTabIsCache" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="侧边栏展开宽度">
|
<setting-menu :label="$t('layout.settingDrawer.sider.width')">
|
||||||
<n-input-number
|
<n-input-number
|
||||||
class="w-120px"
|
class="w-120px"
|
||||||
size="small"
|
size="small"
|
||||||
@ -52,7 +52,7 @@
|
|||||||
@update:value="theme.setSiderWidth"
|
@update:value="theme.setSiderWidth"
|
||||||
/>
|
/>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="左侧混合侧边栏展开宽度">
|
<setting-menu :label="$t('layout.settingDrawer.sider.mixWidth')">
|
||||||
<n-input-number
|
<n-input-number
|
||||||
class="w-120px"
|
class="w-120px"
|
||||||
size="small"
|
size="small"
|
||||||
@ -61,13 +61,13 @@
|
|||||||
@update:value="theme.setMixSiderWidth"
|
@update:value="theme.setMixSiderWidth"
|
||||||
/>
|
/>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="显示底部">
|
<setting-menu :label="$t('layout.settingDrawer.footer.visible')">
|
||||||
<n-switch :value="theme.footer.visible" @update:value="theme.setFooterVisible" />
|
<n-switch :value="theme.footer.visible" @update:value="theme.setFooterVisible" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="固定底部">
|
<setting-menu :label="$t('layout.settingDrawer.footer.fixed')">
|
||||||
<n-switch :value="theme.footer.fixed" @update:value="theme.setFooterIsFixed" />
|
<n-switch :value="theme.footer.fixed" @update:value="theme.setFooterIsFixed" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="底部居右">
|
<setting-menu :label="$t('layout.settingDrawer.footer.right')">
|
||||||
<n-switch :value="theme.footer.right" @update:value="theme.setFooterIsRight" />
|
<n-switch :value="theme.footer.right" @update:value="theme.setFooterIsRight" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
</n-space>
|
</n-space>
|
||||||
@ -75,6 +75,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useThemeStore } from '@/store';
|
import { useThemeStore } from '@/store';
|
||||||
|
import { $t } from '@/locales';
|
||||||
import SettingMenu from '../setting-menu/index.vue';
|
import SettingMenu from '../setting-menu/index.vue';
|
||||||
|
|
||||||
defineOptions({ name: 'PageFunc' });
|
defineOptions({ name: 'PageFunc' });
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-divider title-placement="center">界面显示</n-divider>
|
<n-divider title-placement="center">{{ $t('layout.settingDrawer.pageViewTitle') }}</n-divider>
|
||||||
<n-space vertical size="large">
|
<n-space vertical size="large">
|
||||||
<setting-menu label="面包屑">
|
<setting-menu :label="$t('layout.settingDrawer.header.crumb.visible')">
|
||||||
<n-switch :value="theme.header.crumb.visible" @update:value="theme.setHeaderCrumbVisible" />
|
<n-switch :value="theme.header.crumb.visible" @update:value="theme.setHeaderCrumbVisible" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="面包屑图标">
|
<setting-menu :label="$t('layout.settingDrawer.header.crumb.icon')">
|
||||||
<n-switch :value="theme.header.crumb.showIcon" @update:value="theme.setHeaderCrumbIconVisible" />
|
<n-switch :value="theme.header.crumb.showIcon" @update:value="theme.setHeaderCrumbIconVisible" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="多页签">
|
<setting-menu :label="$t('layout.settingDrawer.tab.visible')">
|
||||||
<n-switch :value="theme.tab.visible" @update:value="theme.setTabVisible" />
|
<n-switch :value="theme.tab.visible" @update:value="theme.setTabVisible" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="多页签风格">
|
<setting-menu :label="$t('layout.settingDrawer.tab.modeList.mode')">
|
||||||
<n-select
|
<n-select
|
||||||
class="w-120px"
|
class="w-120px"
|
||||||
size="small"
|
size="small"
|
||||||
@ -19,10 +19,10 @@
|
|||||||
@update:value="theme.setTabMode"
|
@update:value="theme.setTabMode"
|
||||||
/>
|
/>
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="页面切换动画">
|
<setting-menu :label="$t('layout.settingDrawer.page.animate')">
|
||||||
<n-switch :value="theme.page.animate" @update:value="theme.setPageIsAnimate" />
|
<n-switch :value="theme.page.animate" @update:value="theme.setPageIsAnimate" />
|
||||||
</setting-menu>
|
</setting-menu>
|
||||||
<setting-menu label="页面切换动画类型">
|
<setting-menu :label="$t('layout.settingDrawer.page.animateMode')">
|
||||||
<n-select
|
<n-select
|
||||||
class="w-120px"
|
class="w-120px"
|
||||||
size="small"
|
size="small"
|
||||||
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useThemeStore } from '@/store';
|
import { useThemeStore } from '@/store';
|
||||||
|
import { $t } from '@/locales';
|
||||||
import SettingMenu from '../setting-menu/index.vue';
|
import SettingMenu from '../setting-menu/index.vue';
|
||||||
|
|
||||||
defineOptions({ name: 'PageView' });
|
defineOptions({ name: 'PageView' });
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-divider title-placement="center">系统主题</n-divider>
|
<n-divider title-placement="center">{{ $t('layout.settingDrawer.systemThemeTitle') }}</n-divider>
|
||||||
<n-grid :cols="8" :x-gap="8" :y-gap="12">
|
<n-grid :cols="8" :x-gap="8" :y-gap="12">
|
||||||
<n-grid-item v-for="color in theme.themeColorList" :key="color" class="flex-x-center">
|
<n-grid-item v-for="color in theme.themeColorList" :key="color" class="flex-x-center">
|
||||||
<color-checkbox :color="color" :checked="color === theme.themeColor" @click="theme.setThemeColor(color)" />
|
<color-checkbox :color="color" :checked="color === theme.themeColor" @click="theme.setThemeColor(color)" />
|
||||||
@ -7,7 +7,9 @@
|
|||||||
</n-grid>
|
</n-grid>
|
||||||
<n-space :vertical="true" class="pt-12px">
|
<n-space :vertical="true" class="pt-12px">
|
||||||
<n-color-picker :value="theme.themeColor" :show-alpha="false" @update-value="theme.setThemeColor" />
|
<n-color-picker :value="theme.themeColor" :show-alpha="false" @update-value="theme.setThemeColor" />
|
||||||
<n-button :block="true" :type="otherColorBtnType" @click="openModal">更多颜色</n-button>
|
<n-button :block="true" :type="otherColorBtnType" @click="openModal">
|
||||||
|
{{ $t('layout.settingDrawer.systemTheme.moreColors') }}
|
||||||
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
<color-modal :visible="visible" @close="closeModal" />
|
<color-modal :visible="visible" @close="closeModal" />
|
||||||
</template>
|
</template>
|
||||||
@ -17,6 +19,7 @@ import { computed } from 'vue';
|
|||||||
import { isInTraditionColors } from '@/settings';
|
import { isInTraditionColors } from '@/settings';
|
||||||
import { useThemeStore } from '@/store';
|
import { useThemeStore } from '@/store';
|
||||||
import { useBoolean } from '@/hooks';
|
import { useBoolean } from '@/hooks';
|
||||||
|
import { $t } from '@/locales';
|
||||||
import { ColorCheckbox, ColorModal } from './components';
|
import { ColorCheckbox, ColorModal } from './components';
|
||||||
|
|
||||||
defineOptions({ name: 'ThemeColorSelect' });
|
defineOptions({ name: 'ThemeColorSelect' });
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-divider title-placement="center">主题配置</n-divider>
|
<n-divider title-placement="center">{{ $t('layout.settingDrawer.themeConfiguration.title') }}</n-divider>
|
||||||
<textarea id="themeConfigCopyTarget" v-model="dataClipboardText" class="absolute opacity-0" />
|
<textarea id="themeConfigCopyTarget" v-model="dataClipboardText" class="absolute opacity-0" />
|
||||||
<n-space vertical>
|
<n-space vertical>
|
||||||
<div ref="copyRef" data-clipboard-target="#themeConfigCopyTarget">
|
<div ref="copyRef" data-clipboard-target="#themeConfigCopyTarget">
|
||||||
<n-button type="primary" :block="true">拷贝当前配置</n-button>
|
<n-button type="primary" :block="true">{{ $t('layout.settingDrawer.themeConfiguration.copy') }}</n-button>
|
||||||
</div>
|
</div>
|
||||||
<n-button type="warning" :block="true" @click="handleResetConfig">重置当前配置</n-button>
|
<n-button type="warning" :block="true" @click="handleResetConfig">
|
||||||
|
{{ $t('layout.settingDrawer.themeConfiguration.reset') }}
|
||||||
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -13,6 +15,7 @@
|
|||||||
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
||||||
import Clipboard from 'clipboard';
|
import Clipboard from 'clipboard';
|
||||||
import { useThemeStore } from '@/store';
|
import { useThemeStore } from '@/store';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
defineOptions({ name: 'ThemeConfig' });
|
defineOptions({ name: 'ThemeConfig' });
|
||||||
|
|
||||||
@ -28,7 +31,7 @@ function getClipboardText() {
|
|||||||
|
|
||||||
function handleResetConfig() {
|
function handleResetConfig() {
|
||||||
theme.resetThemeStore();
|
theme.resetThemeStore();
|
||||||
window.$message?.success('已重置配置,请重新拷贝!');
|
window.$message?.success($t('layout.settingDrawer.themeConfiguration.resetSuccess'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function clipboardEventListener() {
|
function clipboardEventListener() {
|
||||||
@ -36,9 +39,9 @@ function clipboardEventListener() {
|
|||||||
const copy = new Clipboard(copyRef.value);
|
const copy = new Clipboard(copyRef.value);
|
||||||
copy.on('success', () => {
|
copy.on('success', () => {
|
||||||
window.$dialog?.success({
|
window.$dialog?.success({
|
||||||
title: '操作成功',
|
title: $t('layout.settingDrawer.themeConfiguration.operateSuccess'),
|
||||||
content: '复制成功,请替换 src/settings/theme.json的内容!',
|
content: $t('layout.settingDrawer.themeConfiguration.copySuccess'),
|
||||||
positiveText: '确定'
|
positiveText: $t('layout.settingDrawer.themeConfiguration.confirmCopy')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-drawer :show="app.settingDrawerVisible" display-directive="show" :width="330" @mask-click="app.closeSettingDrawer">
|
<n-drawer :show="app.settingDrawerVisible" display-directive="show" :width="330" @mask-click="app.closeSettingDrawer">
|
||||||
<n-drawer-content title="主题配置" :native-scrollbar="false">
|
<n-drawer-content :title="$t('layout.settingDrawer.title')" :native-scrollbar="false">
|
||||||
<dark-mode />
|
<dark-mode />
|
||||||
<layout-mode />
|
<layout-mode />
|
||||||
<theme-color-select />
|
<theme-color-select />
|
||||||
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAppStore } from '@/store';
|
import { useAppStore } from '@/store';
|
||||||
|
import { $t } from '@/locales';
|
||||||
import { DarkMode, DrawerButton, LayoutMode, PageFunc, PageView, ThemeColorSelect, ThemeConfig } from './components';
|
import { DarkMode, DrawerButton, LayoutMode, PageFunc, PageView, ThemeColorSelect, ThemeConfig } from './components';
|
||||||
|
|
||||||
defineOptions({ name: 'SettingDrawer' });
|
defineOptions({ name: 'SettingDrawer' });
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
import { createI18n } from 'vue-i18n';
|
import { createI18n } from 'vue-i18n';
|
||||||
import { localStg } from '@/utils';
|
import type { TranslateOptions } from 'vue-i18n';
|
||||||
import messages from './lang';
|
import { localStg } from '@/utils/storage';
|
||||||
import type { LocaleKey } from './lang';
|
import messages from './locale';
|
||||||
|
|
||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
locale: localStg.get('lang') || 'zh-CN',
|
locale: localStg.get('lang') || 'zh-CN',
|
||||||
@ -15,10 +15,20 @@ export function setupI18n(app: App) {
|
|||||||
app.use(i18n);
|
app.use(i18n);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function t(key: string) {
|
interface T {
|
||||||
return i18n.global.t(key);
|
(key: I18nType.I18nKey): string;
|
||||||
|
(key: I18nType.I18nKey, plural: number, options?: TranslateOptions<I18nType.LangType>): string;
|
||||||
|
(key: I18nType.I18nKey, defaultMsg: string, options?: TranslateOptions<I18nType.I18nKey>): string;
|
||||||
|
(key: I18nType.I18nKey, list: unknown[], options?: TranslateOptions<I18nType.I18nKey>): string;
|
||||||
|
(key: I18nType.I18nKey, list: unknown[], plural: number): string;
|
||||||
|
(key: I18nType.I18nKey, list: unknown[], defaultMsg: string): string;
|
||||||
|
(key: I18nType.I18nKey, named: Record<string, unknown>, options?: TranslateOptions<I18nType.LangType>): string;
|
||||||
|
(key: I18nType.I18nKey, named: Record<string, unknown>, plural: number): string;
|
||||||
|
(key: I18nType.I18nKey, named: Record<string, unknown>, defaultMsg: string): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setLocale(locale: LocaleKey) {
|
export const $t = i18n.global.t as T;
|
||||||
|
|
||||||
|
export function setLocale(locale: I18nType.LangType) {
|
||||||
i18n.global.locale.value = locale;
|
i18n.global.locale.value = locale;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,20 @@
|
|||||||
import type { LocaleMessages } from 'vue-i18n';
|
const locale: I18nType.Schema = {
|
||||||
|
|
||||||
const locale: LocaleMessages<I18nType.Schema> = {
|
|
||||||
message: {
|
|
||||||
system: {
|
system: {
|
||||||
title: 'SoybeanAdmin'
|
title: 'SoybeanAdmin'
|
||||||
},
|
},
|
||||||
|
common: {
|
||||||
|
add: 'Add',
|
||||||
|
addSuccess: 'Add Success',
|
||||||
|
edit: 'Edit',
|
||||||
|
editSuccess: 'Edit Success',
|
||||||
|
delete: 'Delete',
|
||||||
|
deleteSuccess: 'Delete Success',
|
||||||
|
batchDelete: 'Batch Delete',
|
||||||
|
confirm: 'Confirm',
|
||||||
|
cancel: 'Cancel',
|
||||||
|
pleaseCheckValue: 'Please check the value is valid',
|
||||||
|
action: 'Action'
|
||||||
|
},
|
||||||
routes: {
|
routes: {
|
||||||
dashboard: {
|
dashboard: {
|
||||||
_value: 'Dashboard',
|
_value: 'Dashboard',
|
||||||
@ -78,6 +88,130 @@ const locale: LocaleMessages<I18nType.Schema> = {
|
|||||||
user: 'User'
|
user: 'User'
|
||||||
},
|
},
|
||||||
about: 'About'
|
about: 'About'
|
||||||
|
},
|
||||||
|
layout: {
|
||||||
|
settingDrawer: {
|
||||||
|
title: 'Theme configuration',
|
||||||
|
themeModeTitle: 'Theme mode',
|
||||||
|
darkMode: 'Dark mode',
|
||||||
|
layoutModelTitle: 'Layout mode',
|
||||||
|
systemThemeTitle: 'System theme',
|
||||||
|
pageFunctionsTitle: 'Page functions',
|
||||||
|
pageViewTitle: 'Page view',
|
||||||
|
followSystemTheme: 'Follow the system',
|
||||||
|
isCustomizeDarkModeTransition: 'Custom dark theme animation transition',
|
||||||
|
scrollMode: 'scrollMode',
|
||||||
|
scrollModeList: {
|
||||||
|
wrapper: 'Outer layer scroll',
|
||||||
|
content: 'Main body scroll'
|
||||||
|
},
|
||||||
|
fixedHeaderAndTab: 'Fixed header and multiple tabs',
|
||||||
|
header: {
|
||||||
|
inverted: 'darkHead',
|
||||||
|
height: 'Head Height',
|
||||||
|
crumb: {
|
||||||
|
visible: 'Crumb',
|
||||||
|
icon: 'Crumb icon'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tab: {
|
||||||
|
visible: 'Multi-page tab',
|
||||||
|
height: 'Multiple tab height',
|
||||||
|
modeList: {
|
||||||
|
mode: 'Multi-tab style',
|
||||||
|
chrome: 'Google style',
|
||||||
|
button: 'Button style'
|
||||||
|
},
|
||||||
|
isCache: 'Multiple tab caching'
|
||||||
|
},
|
||||||
|
sider: {
|
||||||
|
inverted: 'Dark sidebar',
|
||||||
|
width: 'Sidebar expanded width',
|
||||||
|
mixWidth: 'Left hybrid sidebar expanded width'
|
||||||
|
},
|
||||||
|
menu: {
|
||||||
|
horizontalPosition: 'Top menu position',
|
||||||
|
horizontalPositionList: {
|
||||||
|
flexStart: 'Right',
|
||||||
|
center: 'center',
|
||||||
|
flexEnd: 'Left'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
footer: {
|
||||||
|
inverted: 'Dark bottom',
|
||||||
|
visible: 'Show bottom',
|
||||||
|
fixed: 'Fixed bottom',
|
||||||
|
right: 'Bottom to the right'
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
animate: 'switch animation',
|
||||||
|
animateMode: 'switch animation type',
|
||||||
|
animateModeList: {
|
||||||
|
zoomFade: 'Gradual change',
|
||||||
|
zoomOut: 'Flash',
|
||||||
|
fadeSlide: 'Slide',
|
||||||
|
fade: 'Fade away',
|
||||||
|
fadeBottom: 'Bottom fade',
|
||||||
|
fadeScale: 'Resizing fade away'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
systemTheme: {
|
||||||
|
moreColors: 'More colors'
|
||||||
|
},
|
||||||
|
themeConfiguration: {
|
||||||
|
title: 'Theme configuration',
|
||||||
|
copy: 'Copy the current configuration',
|
||||||
|
reset: 'Reset the current configuration',
|
||||||
|
resetSuccess: 'The configuration has been reset, please copy it again!',
|
||||||
|
operateSuccess: 'Successful operation',
|
||||||
|
copySuccess: 'Copy success, please replace the content of src/settings/theme.json!',
|
||||||
|
confirmCopy: 'Confirm'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
login: {
|
||||||
|
common: {
|
||||||
|
userNamePlaceholder: 'Please enter user name',
|
||||||
|
phonePlaceholder: 'Please enter phone number',
|
||||||
|
codePlaceholder: 'Please enter verification code',
|
||||||
|
passwordPlaceholder: 'Please enter password',
|
||||||
|
confirmPasswordPlaceholder: 'Please enter password again',
|
||||||
|
codeLogin: 'Verification code login',
|
||||||
|
confirm: 'Confirm',
|
||||||
|
back: 'Back',
|
||||||
|
validateSuccess: 'Verification passed',
|
||||||
|
loginSuccess: 'Login success',
|
||||||
|
welcomeBack: 'Welcome back, {userName}!'
|
||||||
|
},
|
||||||
|
pwdLogin: {
|
||||||
|
title: 'Password Login',
|
||||||
|
rememberMe: 'Remember me',
|
||||||
|
forgetPassword: 'Forget password?',
|
||||||
|
register: 'Register account',
|
||||||
|
otherAccountLogin: 'Other Account Login',
|
||||||
|
otherLoginMode: 'Other Login Mode',
|
||||||
|
superAdmin: 'Super Administrator',
|
||||||
|
admin: 'Administrator',
|
||||||
|
user: 'Ordinary User'
|
||||||
|
},
|
||||||
|
codeLogin: {
|
||||||
|
title: 'Verification Code Login',
|
||||||
|
getCode: 'Get verification code',
|
||||||
|
imageCodePlaceholder: 'Please enter image verification code'
|
||||||
|
},
|
||||||
|
register: {
|
||||||
|
title: 'Register Account',
|
||||||
|
agreement: 'I have read and agree to',
|
||||||
|
protocol: '《User Agreement》',
|
||||||
|
policy: '《Privacy Policy》'
|
||||||
|
},
|
||||||
|
resetPwd: {
|
||||||
|
title: 'Reset Password'
|
||||||
|
},
|
||||||
|
bindWeChat: {
|
||||||
|
title: 'Bind WeChat'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import zhCN from './zh-cn';
|
|
||||||
import en from './en';
|
|
||||||
import kmKH from './km-KH';
|
|
||||||
|
|
||||||
const locales = {
|
|
||||||
'zh-CN': zhCN,
|
|
||||||
en,
|
|
||||||
'km-KH': kmKH
|
|
||||||
};
|
|
||||||
|
|
||||||
export type LocaleKey = keyof typeof locales;
|
|
||||||
|
|
||||||
export default locales;
|
|
@ -1,10 +1,20 @@
|
|||||||
import type { LocaleMessages } from 'vue-i18n';
|
const locale: I18nType.Schema = {
|
||||||
|
|
||||||
const locale: LocaleMessages<I18nType.Schema> = {
|
|
||||||
message: {
|
|
||||||
system: {
|
system: {
|
||||||
title: 'ប្រព័ន្ធគ្រប់គ្រង'
|
title: 'ប្រព័ន្ធគ្រប់គ្រង'
|
||||||
},
|
},
|
||||||
|
common: {
|
||||||
|
add: 'បន្ថែម',
|
||||||
|
addSuccess: 'បន្ថែមជោគជ័យ',
|
||||||
|
edit: 'កែប្រែ',
|
||||||
|
editSuccess: 'កែប្រែជោគជ័យ',
|
||||||
|
delete: 'លុប',
|
||||||
|
deleteSuccess: 'លុបជោគជ័យ',
|
||||||
|
batchDelete: 'លុបច្រើន',
|
||||||
|
confirm: 'យល់ព្រម',
|
||||||
|
cancel: 'បោះបង់',
|
||||||
|
pleaseCheckValue: 'សូមពិនិត្យមើលតម្លៃដែលបានបញ្ចូលដើម្បីបញ្ជាក់ថាត្រូវប្រើប្រាស់បាន',
|
||||||
|
action: 'សកម្មភាព'
|
||||||
|
},
|
||||||
routes: {
|
routes: {
|
||||||
dashboard: {
|
dashboard: {
|
||||||
_value: 'ផ្ទាំងទិន្នន័យ',
|
_value: 'ផ្ទាំងទិន្នន័យ',
|
||||||
@ -78,6 +88,130 @@ const locale: LocaleMessages<I18nType.Schema> = {
|
|||||||
user: 'អ្នកប្រើប្រាស់'
|
user: 'អ្នកប្រើប្រាស់'
|
||||||
},
|
},
|
||||||
about: 'អំពីប្រព័ន្ធ'
|
about: 'អំពីប្រព័ន្ធ'
|
||||||
|
},
|
||||||
|
layout: {
|
||||||
|
settingDrawer: {
|
||||||
|
title: 'ការកំណត់ស្បែក',
|
||||||
|
themeModeTitle: 'ស្បែករបស់របស់អ្នក',
|
||||||
|
darkMode: 'របៀបងារស្បែកងងឹត',
|
||||||
|
layoutModelTitle: 'របៀបប្រើប្រាស់របស់អ្នក',
|
||||||
|
systemThemeTitle: 'ស្បែករបស់ប្រព័ន្ធគ្រប់គ្រង',
|
||||||
|
pageFunctionsTitle: 'មុខងារទំនាក់ទំនងរបស់ទំព័រ',
|
||||||
|
pageViewTitle: 'ទំព័រទស្សន៍ទាយ',
|
||||||
|
followSystemTheme: 'តាមដានស្បែកប្រព័ន្ធគ្រប់គ្រង',
|
||||||
|
isCustomizeDarkModeTransition: 'ប្រើប្រាស់របៀបងារស្បែកងងឹតផ្ទាល់ខ្លួន',
|
||||||
|
scrollMode: 'របៀបរុករក',
|
||||||
|
scrollModeList: {
|
||||||
|
wrapper: 'រុករកជាក់លាក់',
|
||||||
|
content: 'រុករកមានមុខងារ'
|
||||||
|
},
|
||||||
|
fixedHeaderAndTab: 'បិទការរុករកជាក់លាក់និងរុករកមានមុខងារ',
|
||||||
|
header: {
|
||||||
|
inverted: 'បង្កើតការរុករកជាក់លាក់',
|
||||||
|
height: 'កម្ពស់',
|
||||||
|
crumb: {
|
||||||
|
visible: 'បង្ហាញរុករកជាក់លាក់',
|
||||||
|
icon: 'រុករកជាក់លាក់រូបតំណាង'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tab: {
|
||||||
|
visible: 'បង្ហាញរុករកជាក់លាក់',
|
||||||
|
height: 'កម្ពស់',
|
||||||
|
modeList: {
|
||||||
|
mode: 'របៀប',
|
||||||
|
chrome: 'ក្រុមហ៊ុន',
|
||||||
|
button: 'ប៊ូតុង'
|
||||||
|
},
|
||||||
|
isCache: 'រក្សាទុកការរុករកជាក់លាក់'
|
||||||
|
},
|
||||||
|
sider: {
|
||||||
|
inverted: 'បង្កើតការរុករកជាក់លាក់',
|
||||||
|
width: 'ទទឹង',
|
||||||
|
mixWidth: 'ទទឹងបញ្ចូល'
|
||||||
|
},
|
||||||
|
menu: {
|
||||||
|
horizontalPosition: 'ទីតាំងផ្ដេក',
|
||||||
|
horizontalPositionList: {
|
||||||
|
flexStart: 'ចាប់ផ្ដើមឈុត',
|
||||||
|
center: 'កណ្តាល',
|
||||||
|
flexEnd: 'ចាប់ផ្ដើមចុងក្រោយ'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
footer: {
|
||||||
|
inverted: 'បង្កើតការរុករកជាក់លាក់',
|
||||||
|
visible: 'បង្ហាញការរុករកជាក់លាក់',
|
||||||
|
fixed: 'ការរុករកជាក់លាក់',
|
||||||
|
right: 'ត្រឡប់ទៅស្តាំ'
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
animate: 'ការផ្លាស់ប្តូរ',
|
||||||
|
animateMode: 'របៀបផ្លាស់ប្តូរ',
|
||||||
|
animateModeList: {
|
||||||
|
zoomFade: 'ពង្រីកបង្ហាញនិងលាស់ប្តូរ',
|
||||||
|
zoomOut: 'ពង្រីកបង្ហាញនិងលាស់ប្តូរ',
|
||||||
|
fadeSlide: 'ពង្រីកបង្ហាញនិងលាស់ប្តូរ',
|
||||||
|
fade: 'ពង្រីកបង្ហាញនិងលាស់ប្តូរ',
|
||||||
|
fadeBottom: 'ពង្រីកបង្ហាញនិងលាស់ប្តូរ',
|
||||||
|
fadeScale: 'ពង្រីកបង្ហាញនិងលាស់ប្តូរ'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
systemTheme: {
|
||||||
|
moreColors: 'ពន្លឺច្រើនទៀត'
|
||||||
|
},
|
||||||
|
themeConfiguration: {
|
||||||
|
title: 'ការកំណត់ស្បែក',
|
||||||
|
copy: 'ចម្លង',
|
||||||
|
reset: 'កំណត់ឡើងវិញ',
|
||||||
|
resetSuccess: 'កំណត់ឡើងវិញជោគជ័យ, សូមចម្លងឯកសារស្បែកឡើងវិញ!',
|
||||||
|
operateSuccess: 'សម្រាប់ការប្រើប្រាស់ជោគជ័យ',
|
||||||
|
copySuccess: 'ចម្លងជោគជ័យ, សូមជោគជ័យឯកសារ src/settings/theme.json!',
|
||||||
|
confirmCopy: 'យល់ព្រម'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
login: {
|
||||||
|
common: {
|
||||||
|
userNamePlaceholder: 'ឈ្មោះអ្នកប្រើប្រាស់',
|
||||||
|
phonePlaceholder: 'លេខទូរស័ព្ទ',
|
||||||
|
codePlaceholder: 'លេខកូដ',
|
||||||
|
passwordPlaceholder: 'លេខសម្ងាត់',
|
||||||
|
confirmPasswordPlaceholder: 'បញ្ជាក់លេខសម្ងាត់',
|
||||||
|
codeLogin: 'ចូលតាមលេខកូដ',
|
||||||
|
confirm: 'យល់ព្រម',
|
||||||
|
back: 'ត្រឡប់ក្រោយ',
|
||||||
|
validateSuccess: 'បញ្ជាក់ជោគជ័យ',
|
||||||
|
loginSuccess: 'ចូលជោគជ័យ',
|
||||||
|
welcomeBack: 'សូមស្វាគមន៍ម្តងទៀត, {userName}!'
|
||||||
|
},
|
||||||
|
pwdLogin: {
|
||||||
|
title: 'ចូលគណនី',
|
||||||
|
rememberMe: 'ចងចាំខ្ញុំ',
|
||||||
|
forgetPassword: 'ភ្លេចលេខសម្ងាត់',
|
||||||
|
register: 'ចុះឈ្មោះ',
|
||||||
|
otherAccountLogin: 'ចូលតាមគណនីផ្សេងទៀត',
|
||||||
|
otherLoginMode: 'របៀបចូលគណនីផ្សេងទៀត',
|
||||||
|
superAdmin: 'អ្នកគ្រប់គ្រងសុវត្ថិភាព',
|
||||||
|
admin: 'អ្នកគ្រប់គ្រង',
|
||||||
|
user: 'អ្នកប្រើប្រាស់'
|
||||||
|
},
|
||||||
|
codeLogin: {
|
||||||
|
title: 'ចូលតាមលេខកូដ',
|
||||||
|
getCode: 'ទទួលលេខកូដ',
|
||||||
|
imageCodePlaceholder: 'លេខកូដរូបភាព'
|
||||||
|
},
|
||||||
|
register: {
|
||||||
|
title: 'ចុះឈ្មោះ',
|
||||||
|
agreement: 'យល់ព្រមនឹង',
|
||||||
|
protocol: 'សម្រាប់ការប្រើប្រាស់',
|
||||||
|
policy: 'គោលការណ៍ផ្សេងៗ'
|
||||||
|
},
|
||||||
|
resetPwd: {
|
||||||
|
title: 'កំណត់លេខសម្ងាត់ថ្មី'
|
||||||
|
},
|
||||||
|
bindWeChat: {
|
||||||
|
title: 'ភ្ជាប់គណនីរបស់អ្នកជាមួយគណនីរបស់អ្នក'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
import type { LocaleMessages } from 'vue-i18n';
|
|
||||||
|
|
||||||
const locale: LocaleMessages<I18nType.Schema> = {
|
|
||||||
message: {
|
|
||||||
system: {
|
|
||||||
title: 'Soybean管理系统'
|
|
||||||
},
|
|
||||||
routes: {
|
|
||||||
dashboard: {
|
|
||||||
_value: '仪表盘',
|
|
||||||
analysis: '分析页',
|
|
||||||
workbench: '工作台'
|
|
||||||
},
|
|
||||||
document: {
|
|
||||||
_value: '文档',
|
|
||||||
vue: 'Vue文档',
|
|
||||||
vite: 'Vite文档',
|
|
||||||
naive: 'NaiveUI文档',
|
|
||||||
project: '项目文档',
|
|
||||||
'project-link': '项目文档(外链)'
|
|
||||||
},
|
|
||||||
component: {
|
|
||||||
_value: '组件示例',
|
|
||||||
button: '按钮',
|
|
||||||
card: '卡片',
|
|
||||||
table: '表格'
|
|
||||||
},
|
|
||||||
plugin: {
|
|
||||||
_value: '插件示例',
|
|
||||||
charts: {
|
|
||||||
_value: '图表',
|
|
||||||
echarts: 'ECharts',
|
|
||||||
antv: 'AntV'
|
|
||||||
},
|
|
||||||
copy: '剪贴板',
|
|
||||||
editor: {
|
|
||||||
_value: '编辑器',
|
|
||||||
quill: '富文本',
|
|
||||||
markdown: 'Markdown'
|
|
||||||
},
|
|
||||||
icon: '图标',
|
|
||||||
map: '地图',
|
|
||||||
print: '打印',
|
|
||||||
swiper: 'Swiper',
|
|
||||||
video: '视频'
|
|
||||||
},
|
|
||||||
'auth-demo': {
|
|
||||||
_value: '权限示例',
|
|
||||||
permission: '切换权限',
|
|
||||||
super: '超级管理员可见'
|
|
||||||
},
|
|
||||||
function: {
|
|
||||||
_value: '功能',
|
|
||||||
tab: 'Tab页签'
|
|
||||||
},
|
|
||||||
exception: {
|
|
||||||
_value: '异常页',
|
|
||||||
403: '403',
|
|
||||||
404: '404',
|
|
||||||
500: '500'
|
|
||||||
},
|
|
||||||
'multi-menu': {
|
|
||||||
_value: '多级菜单',
|
|
||||||
first: {
|
|
||||||
_value: '一级菜单',
|
|
||||||
second: '二级菜单',
|
|
||||||
'second-new': {
|
|
||||||
_value: '二级菜单(有子菜单)',
|
|
||||||
third: '三级菜单'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
management: {
|
|
||||||
_value: '系统管理',
|
|
||||||
auth: '权限管理',
|
|
||||||
role: '角色管理',
|
|
||||||
route: '路由管理',
|
|
||||||
user: '用户管理'
|
|
||||||
},
|
|
||||||
about: '关于'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default locale;
|
|
219
src/locales/lang/zhCN.ts
Normal file
219
src/locales/lang/zhCN.ts
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
const locale: I18nType.Schema = {
|
||||||
|
system: {
|
||||||
|
title: 'Soybean管理系统'
|
||||||
|
},
|
||||||
|
common: {
|
||||||
|
add: '添加',
|
||||||
|
addSuccess: '添加成功',
|
||||||
|
edit: '修改',
|
||||||
|
editSuccess: '修改成功',
|
||||||
|
delete: '删除',
|
||||||
|
deleteSuccess: '删除成功',
|
||||||
|
batchDelete: '批量删除',
|
||||||
|
confirm: '确认',
|
||||||
|
cancel: '取消',
|
||||||
|
pleaseCheckValue: '请检查输入的值是否合法',
|
||||||
|
action: '操作'
|
||||||
|
},
|
||||||
|
routes: {
|
||||||
|
dashboard: {
|
||||||
|
_value: '仪表盘',
|
||||||
|
analysis: '分析页',
|
||||||
|
workbench: '工作台'
|
||||||
|
},
|
||||||
|
document: {
|
||||||
|
_value: '文档',
|
||||||
|
vue: 'Vue文档',
|
||||||
|
vite: 'Vite文档',
|
||||||
|
naive: 'NaiveUI文档',
|
||||||
|
project: '项目文档',
|
||||||
|
'project-link': '项目文档(外链)'
|
||||||
|
},
|
||||||
|
component: {
|
||||||
|
_value: '组件示例',
|
||||||
|
button: '按钮',
|
||||||
|
card: '卡片',
|
||||||
|
table: '表格'
|
||||||
|
},
|
||||||
|
plugin: {
|
||||||
|
_value: '插件示例',
|
||||||
|
charts: {
|
||||||
|
_value: '图表',
|
||||||
|
echarts: 'ECharts',
|
||||||
|
antv: 'AntV'
|
||||||
|
},
|
||||||
|
copy: '剪贴板',
|
||||||
|
editor: {
|
||||||
|
_value: '编辑器',
|
||||||
|
quill: '富文本',
|
||||||
|
markdown: 'Markdown'
|
||||||
|
},
|
||||||
|
icon: '图标',
|
||||||
|
map: '地图',
|
||||||
|
print: '打印',
|
||||||
|
swiper: 'Swiper',
|
||||||
|
video: '视频'
|
||||||
|
},
|
||||||
|
'auth-demo': {
|
||||||
|
_value: '权限示例',
|
||||||
|
permission: '切换权限',
|
||||||
|
super: '超级管理员可见'
|
||||||
|
},
|
||||||
|
function: {
|
||||||
|
_value: '功能',
|
||||||
|
tab: 'Tab页签'
|
||||||
|
},
|
||||||
|
exception: {
|
||||||
|
_value: '异常页',
|
||||||
|
403: '403',
|
||||||
|
404: '404',
|
||||||
|
500: '500'
|
||||||
|
},
|
||||||
|
'multi-menu': {
|
||||||
|
_value: '多级菜单',
|
||||||
|
first: {
|
||||||
|
_value: '一级菜单',
|
||||||
|
second: '二级菜单',
|
||||||
|
'second-new': {
|
||||||
|
_value: '二级菜单(有子菜单)',
|
||||||
|
third: '三级菜单'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
management: {
|
||||||
|
_value: '系统管理',
|
||||||
|
auth: '权限管理',
|
||||||
|
role: '角色管理',
|
||||||
|
route: '路由管理',
|
||||||
|
user: '用户管理'
|
||||||
|
},
|
||||||
|
about: '关于'
|
||||||
|
},
|
||||||
|
layout: {
|
||||||
|
settingDrawer: {
|
||||||
|
title: '主题配置',
|
||||||
|
themeModeTitle: '主题模式',
|
||||||
|
darkMode: '深色主题',
|
||||||
|
layoutModelTitle: '布局模式',
|
||||||
|
systemThemeTitle: '系统主题',
|
||||||
|
pageFunctionsTitle: '界面功能',
|
||||||
|
pageViewTitle: '界面显示',
|
||||||
|
followSystemTheme: '跟随系统',
|
||||||
|
isCustomizeDarkModeTransition: '自定义暗黑主题动画过渡',
|
||||||
|
scrollMode: '滚动模式',
|
||||||
|
scrollModeList: {
|
||||||
|
wrapper: '外层滚动',
|
||||||
|
content: '主体滚动'
|
||||||
|
},
|
||||||
|
fixedHeaderAndTab: '固定头部和多页签',
|
||||||
|
header: {
|
||||||
|
inverted: '头部深色',
|
||||||
|
height: '头部高度',
|
||||||
|
crumb: {
|
||||||
|
visible: '面包屑',
|
||||||
|
icon: '面包屑图标'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tab: {
|
||||||
|
visible: '多页签',
|
||||||
|
height: '多页签高度',
|
||||||
|
modeList: {
|
||||||
|
mode: '多页签风格',
|
||||||
|
chrome: '谷歌风格',
|
||||||
|
button: '按钮风格'
|
||||||
|
},
|
||||||
|
isCache: '多页签缓存'
|
||||||
|
},
|
||||||
|
sider: {
|
||||||
|
inverted: '侧边栏深色',
|
||||||
|
width: '侧边栏展开宽度',
|
||||||
|
mixWidth: '左侧混合侧边栏展开宽度'
|
||||||
|
},
|
||||||
|
menu: {
|
||||||
|
horizontalPosition: '顶部菜单位置',
|
||||||
|
horizontalPositionList: {
|
||||||
|
flexStart: '居左',
|
||||||
|
center: '居中',
|
||||||
|
flexEnd: '居右'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
footer: {
|
||||||
|
inverted: '底部深色',
|
||||||
|
visible: '显示底部',
|
||||||
|
fixed: '固定底部',
|
||||||
|
right: '底部居右'
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
animate: '页面切换动画',
|
||||||
|
animateMode: '页面切换动画类型',
|
||||||
|
animateModeList: {
|
||||||
|
zoomFade: '渐变',
|
||||||
|
zoomOut: '闪现',
|
||||||
|
fadeSlide: '滑动',
|
||||||
|
fade: '消退',
|
||||||
|
fadeBottom: '底部消退',
|
||||||
|
fadeScale: '缩放消退'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
systemTheme: {
|
||||||
|
moreColors: '更多颜色'
|
||||||
|
},
|
||||||
|
themeConfiguration: {
|
||||||
|
title: '主题配置',
|
||||||
|
copy: '拷贝当前配置',
|
||||||
|
reset: '重置当前配置',
|
||||||
|
resetSuccess: '已重置配置,请重新拷贝!',
|
||||||
|
operateSuccess: '操作成功',
|
||||||
|
copySuccess: '复制成功,请替换 src/settings/theme.json的内容!',
|
||||||
|
confirmCopy: '确认'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
login: {
|
||||||
|
common: {
|
||||||
|
userNamePlaceholder: '请输入用户名',
|
||||||
|
phonePlaceholder: '请输入手机号',
|
||||||
|
codePlaceholder: '请输入验证码',
|
||||||
|
passwordPlaceholder: '请输入密码',
|
||||||
|
confirmPasswordPlaceholder: '请再次输入密码',
|
||||||
|
codeLogin: '验证码登录',
|
||||||
|
confirm: '确定',
|
||||||
|
back: '返回',
|
||||||
|
validateSuccess: '验证成功',
|
||||||
|
loginSuccess: '登录成功',
|
||||||
|
welcomeBack: '欢迎回来,{userName}!'
|
||||||
|
},
|
||||||
|
pwdLogin: {
|
||||||
|
title: '密码登录',
|
||||||
|
rememberMe: '记住我',
|
||||||
|
forgetPassword: '忘记密码?',
|
||||||
|
register: '注册账号',
|
||||||
|
otherAccountLogin: '其他账号登录',
|
||||||
|
otherLoginMode: '其他登录方式',
|
||||||
|
superAdmin: '超级管理员',
|
||||||
|
admin: '管理员',
|
||||||
|
user: '普通用户'
|
||||||
|
},
|
||||||
|
codeLogin: {
|
||||||
|
title: '验证码登录',
|
||||||
|
getCode: '获取验证码',
|
||||||
|
imageCodePlaceholder: '请输入图片验证码'
|
||||||
|
},
|
||||||
|
register: {
|
||||||
|
title: '注册账号',
|
||||||
|
agreement: '我已经仔细阅读并接受',
|
||||||
|
protocol: '《用户协议》',
|
||||||
|
policy: '《隐私权政策》'
|
||||||
|
},
|
||||||
|
resetPwd: {
|
||||||
|
title: '重置密码'
|
||||||
|
},
|
||||||
|
bindWeChat: {
|
||||||
|
title: '绑定微信'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default locale;
|
11
src/locales/locale.ts
Normal file
11
src/locales/locale.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import zhCN from './lang/zhCN';
|
||||||
|
import en from './lang/en';
|
||||||
|
import kmKH from './lang/km-KH';
|
||||||
|
|
||||||
|
const locales: Record<I18nType.LangType, I18nType.Schema> = {
|
||||||
|
'zh-CN': zhCN,
|
||||||
|
en,
|
||||||
|
'km-KH': kmKH
|
||||||
|
};
|
||||||
|
|
||||||
|
export default locales;
|
@ -1,6 +1,6 @@
|
|||||||
import type { Router } from 'vue-router';
|
import type { Router } from 'vue-router';
|
||||||
import { useTitle } from '@vueuse/core';
|
import { useTitle } from '@vueuse/core';
|
||||||
import { t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import { createPermissionGuard } from './permission';
|
import { createPermissionGuard } from './permission';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,7 +16,7 @@ export function createRouterGuard(router: Router) {
|
|||||||
});
|
});
|
||||||
router.afterEach(to => {
|
router.afterEach(to => {
|
||||||
// 设置document title
|
// 设置document title
|
||||||
useTitle(to.meta.i18nTitle ? t(to.meta.i18nTitle) : to.meta.title);
|
useTitle(to.meta.i18nTitle ? $t(to.meta.i18nTitle) : to.meta.title);
|
||||||
// 结束 loadingBar
|
// 结束 loadingBar
|
||||||
window.$loadingBar?.finish();
|
window.$loadingBar?.finish();
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
const about1: AuthRoute.Route = {
|
const about: AuthRoute.Route = {
|
||||||
name: 'about',
|
name: 'about',
|
||||||
path: '/about',
|
path: '/about',
|
||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '关于',
|
title: '关于',
|
||||||
i18nTitle: 'message.routes.about',
|
i18nTitle: 'routes.about',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
singleLayout: 'basic',
|
singleLayout: 'basic',
|
||||||
@ -14,4 +14,4 @@ const about1: AuthRoute.Route = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default about1;
|
export default about;
|
||||||
|
@ -9,7 +9,7 @@ const authDemo: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限切换',
|
title: '权限切换',
|
||||||
i18nTitle: 'message.routes.auth-demo.permission',
|
i18nTitle: 'routes.auth-demo.permission',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-construction'
|
icon: 'ic:round-construction'
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ const authDemo: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '超级管理员可见',
|
title: '超级管理员可见',
|
||||||
i18nTitle: 'message.routes.auth-demo.super',
|
i18nTitle: 'routes.auth-demo.super',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
permissions: ['super'],
|
permissions: ['super'],
|
||||||
icon: 'ic:round-supervisor-account'
|
icon: 'ic:round-supervisor-account'
|
||||||
@ -29,7 +29,7 @@ const authDemo: AuthRoute.Route = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限示例',
|
title: '权限示例',
|
||||||
i18nTitle: 'message.routes.auth-demo._value',
|
i18nTitle: 'routes.auth-demo._value',
|
||||||
icon: 'ic:baseline-security',
|
icon: 'ic:baseline-security',
|
||||||
order: 5
|
order: 5
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ const component: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '按钮',
|
title: '按钮',
|
||||||
i18nTitle: 'message.routes.component.button',
|
i18nTitle: 'routes.component.button',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:button-cursor'
|
icon: 'mdi:button-cursor'
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ const component: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '卡片',
|
title: '卡片',
|
||||||
i18nTitle: 'message.routes.component.card',
|
i18nTitle: 'routes.component.card',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:card-outline'
|
icon: 'mdi:card-outline'
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ const component: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '表格',
|
title: '表格',
|
||||||
i18nTitle: 'message.routes.component.table',
|
i18nTitle: 'routes.component.table',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:table-large'
|
icon: 'mdi:table-large'
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@ const component: AuthRoute.Route = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '组件示例',
|
title: '组件示例',
|
||||||
i18nTitle: 'message.routes.component._value',
|
i18nTitle: 'routes.component._value',
|
||||||
icon: 'cib:app-store',
|
icon: 'cib:app-store',
|
||||||
order: 3
|
order: 3
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ const dashboard: AuthRoute.Route = {
|
|||||||
title: '分析页',
|
title: '分析页',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'icon-park-outline:analysis',
|
icon: 'icon-park-outline:analysis',
|
||||||
i18nTitle: 'message.routes.dashboard.analysis'
|
i18nTitle: 'routes.dashboard.analysis'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -22,7 +22,7 @@ const dashboard: AuthRoute.Route = {
|
|||||||
title: '工作台',
|
title: '工作台',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'icon-park-outline:workbench',
|
icon: 'icon-park-outline:workbench',
|
||||||
i18nTitle: 'message.routes.dashboard.workbench'
|
i18nTitle: 'routes.dashboard.workbench'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -30,7 +30,7 @@ const dashboard: AuthRoute.Route = {
|
|||||||
title: '仪表盘',
|
title: '仪表盘',
|
||||||
icon: 'mdi:monitor-dashboard',
|
icon: 'mdi:monitor-dashboard',
|
||||||
order: 1,
|
order: 1,
|
||||||
i18nTitle: 'message.routes.dashboard._value'
|
i18nTitle: 'routes.dashboard._value'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ const document: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'vue文档',
|
title: 'vue文档',
|
||||||
i18nTitle: 'message.routes.document.vue',
|
i18nTitle: 'routes.document.vue',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'logos:vue'
|
icon: 'logos:vue'
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ const document: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'vite文档',
|
title: 'vite文档',
|
||||||
i18nTitle: 'message.routes.document.vite',
|
i18nTitle: 'routes.document.vite',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'logos:vitejs'
|
icon: 'logos:vitejs'
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ const document: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'naive文档',
|
title: 'naive文档',
|
||||||
i18nTitle: 'message.routes.document.naive',
|
i18nTitle: 'routes.document.naive',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'logos:naiveui'
|
icon: 'logos:naiveui'
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ const document: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '项目文档',
|
title: '项目文档',
|
||||||
i18nTitle: 'message.routes.document.project',
|
i18nTitle: 'routes.document.project',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
localIcon: 'logo'
|
localIcon: 'logo'
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ const document: AuthRoute.Route = {
|
|||||||
path: '/document/project-link',
|
path: '/document/project-link',
|
||||||
meta: {
|
meta: {
|
||||||
title: '项目文档(外链)',
|
title: '项目文档(外链)',
|
||||||
i18nTitle: 'message.routes.document.project-link',
|
i18nTitle: 'routes.document.project-link',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
localIcon: 'logo',
|
localIcon: 'logo',
|
||||||
href: 'https://docs.soybean.pro/'
|
href: 'https://docs.soybean.pro/'
|
||||||
@ -61,7 +61,7 @@ const document: AuthRoute.Route = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '文档',
|
title: '文档',
|
||||||
i18nTitle: 'message.routes.document._value',
|
i18nTitle: 'routes.document._value',
|
||||||
icon: 'mdi:file-document-multiple-outline',
|
icon: 'mdi:file-document-multiple-outline',
|
||||||
order: 2
|
order: 2
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ const exception: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '异常页403',
|
title: '异常页403',
|
||||||
i18nTitle: 'message.routes.exception.403',
|
i18nTitle: 'routes.exception.403',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-block'
|
icon: 'ic:baseline-block'
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ const exception: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '异常页404',
|
title: '异常页404',
|
||||||
i18nTitle: 'message.routes.exception.404',
|
i18nTitle: 'routes.exception.404',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-web-asset-off'
|
icon: 'ic:baseline-web-asset-off'
|
||||||
}
|
}
|
||||||
@ -31,14 +31,14 @@ const exception: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '异常页500',
|
title: '异常页500',
|
||||||
i18nTitle: 'message.routes.exception.500',
|
i18nTitle: 'routes.exception.500',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-wifi-off'
|
icon: 'ic:baseline-wifi-off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
i18nTitle: 'message.routes.exception._value',
|
i18nTitle: 'routes.exception._value',
|
||||||
title: '异常页',
|
title: '异常页',
|
||||||
icon: 'ant-design:exception-outlined',
|
icon: 'ant-design:exception-outlined',
|
||||||
order: 7
|
order: 7
|
||||||
|
@ -9,7 +9,7 @@ const functionRoute: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Tab',
|
title: 'Tab',
|
||||||
i18nTitle: 'message.routes.function.tab',
|
i18nTitle: 'routes.function.tab',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-tab'
|
icon: 'ic:round-tab'
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ const functionRoute: AuthRoute.Route = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '功能',
|
title: '功能',
|
||||||
i18nTitle: 'message.routes.function._value',
|
i18nTitle: 'routes.function._value',
|
||||||
icon: 'icon-park-outline:all-application',
|
icon: 'icon-park-outline:all-application',
|
||||||
order: 6
|
order: 6
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ const management: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '权限管理',
|
title: '权限管理',
|
||||||
i18nTitle: 'message.routes.management.auth',
|
i18nTitle: 'routes.management.auth',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:baseline-security'
|
icon: 'ic:baseline-security'
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ const management: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '角色管理',
|
title: '角色管理',
|
||||||
i18nTitle: 'message.routes.management.role',
|
i18nTitle: 'routes.management.role',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'carbon:user-role'
|
icon: 'carbon:user-role'
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ const management: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '用户管理',
|
title: '用户管理',
|
||||||
i18nTitle: 'message.routes.management.user',
|
i18nTitle: 'routes.management.user',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ic:round-manage-accounts'
|
icon: 'ic:round-manage-accounts'
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ const management: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '路由管理',
|
title: '路由管理',
|
||||||
i18nTitle: 'message.routes.management.route',
|
i18nTitle: 'routes.management.route',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'material-symbols:route'
|
icon: 'material-symbols:route'
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ const management: AuthRoute.Route = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '系统管理',
|
title: '系统管理',
|
||||||
i18nTitle: 'message.routes.management._value',
|
i18nTitle: 'routes.management._value',
|
||||||
icon: 'carbon:cloud-service-management',
|
icon: 'carbon:cloud-service-management',
|
||||||
order: 9
|
order: 9
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ const multiMenu: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '二级菜单',
|
title: '二级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second',
|
i18nTitle: 'routes.multi-menu.first.second',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ const multiMenu: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '三级菜单',
|
title: '三级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second-new.third',
|
i18nTitle: 'routes.multi-menu.first.second-new.third',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
@ -38,21 +38,21 @@ const multiMenu: AuthRoute.Route = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '二级菜单(有子菜单)',
|
title: '二级菜单(有子菜单)',
|
||||||
i18nTitle: 'message.routes.multi-menu.first.second-new._value',
|
i18nTitle: 'routes.multi-menu.first.second-new._value',
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '一级菜单',
|
title: '一级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu.first._value',
|
i18nTitle: 'routes.multi-menu.first._value',
|
||||||
icon: 'mdi:menu'
|
icon: 'mdi:menu'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '多级菜单',
|
title: '多级菜单',
|
||||||
i18nTitle: 'message.routes.multi-menu._value',
|
i18nTitle: 'routes.multi-menu._value',
|
||||||
icon: 'carbon:menu',
|
icon: 'carbon:menu',
|
||||||
order: 8
|
order: 8
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'ECharts',
|
title: 'ECharts',
|
||||||
i18nTitle: 'message.routes.plugin.charts.echarts',
|
i18nTitle: 'routes.plugin.charts.echarts',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'simple-icons:apacheecharts'
|
icon: 'simple-icons:apacheecharts'
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'AntV',
|
title: 'AntV',
|
||||||
i18nTitle: 'message.routes.plugin.charts.antv',
|
i18nTitle: 'routes.plugin.charts.antv',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'simple-icons:antdesign'
|
icon: 'simple-icons:antdesign'
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '图表',
|
title: '图表',
|
||||||
i18nTitle: 'message.routes.plugin.charts._value',
|
i18nTitle: 'routes.plugin.charts._value',
|
||||||
icon: 'mdi:chart-areaspline'
|
icon: 'mdi:chart-areaspline'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -43,7 +43,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '地图',
|
title: '地图',
|
||||||
i18nTitle: 'message.routes.plugin.map',
|
i18nTitle: 'routes.plugin.map',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:map'
|
icon: 'mdi:map'
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '视频',
|
title: '视频',
|
||||||
i18nTitle: 'message.routes.plugin.video',
|
i18nTitle: 'routes.plugin.video',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:video'
|
icon: 'mdi:video'
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '富文本编辑器',
|
title: '富文本编辑器',
|
||||||
i18nTitle: 'message.routes.plugin.editor.quill',
|
i18nTitle: 'routes.plugin.editor.quill',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:file-document-edit-outline'
|
icon: 'mdi:file-document-edit-outline'
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'markdown编辑器',
|
title: 'markdown编辑器',
|
||||||
i18nTitle: 'message.routes.plugin.editor.markdown',
|
i18nTitle: 'routes.plugin.editor.markdown',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'ri:markdown-line'
|
icon: 'ri:markdown-line'
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '编辑器',
|
title: '编辑器',
|
||||||
i18nTitle: 'message.routes.plugin.editor._value',
|
i18nTitle: 'routes.plugin.editor._value',
|
||||||
icon: 'icon-park-outline:editor'
|
icon: 'icon-park-outline:editor'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -99,7 +99,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Swiper插件',
|
title: 'Swiper插件',
|
||||||
i18nTitle: 'message.routes.plugin.swiper',
|
i18nTitle: 'routes.plugin.swiper',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'simple-icons:swiper'
|
icon: 'simple-icons:swiper'
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '剪贴板',
|
title: '剪贴板',
|
||||||
i18nTitle: 'message.routes.plugin.copy',
|
i18nTitle: 'routes.plugin.copy',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:clipboard-outline'
|
icon: 'mdi:clipboard-outline'
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '图标',
|
title: '图标',
|
||||||
i18nTitle: 'message.routes.plugin.icon',
|
i18nTitle: 'routes.plugin.icon',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
localIcon: 'custom-icon'
|
localIcon: 'custom-icon'
|
||||||
}
|
}
|
||||||
@ -132,7 +132,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
component: 'self',
|
component: 'self',
|
||||||
meta: {
|
meta: {
|
||||||
title: '打印',
|
title: '打印',
|
||||||
i18nTitle: 'message.routes.plugin.print',
|
i18nTitle: 'routes.plugin.print',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
icon: 'mdi:printer'
|
icon: 'mdi:printer'
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ const plugin: AuthRoute.Route = {
|
|||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
title: '插件示例',
|
title: '插件示例',
|
||||||
i18nTitle: 'message.routes.plugin._value',
|
i18nTitle: 'routes.plugin._value',
|
||||||
icon: 'clarity:plugin-line',
|
icon: 'clarity:plugin-line',
|
||||||
order: 4
|
order: 4
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { router } from '@/router';
|
|||||||
import { fetchLogin, fetchUserInfo } from '@/service';
|
import { fetchLogin, fetchUserInfo } from '@/service';
|
||||||
import { useRouterPush } from '@/composables';
|
import { useRouterPush } from '@/composables';
|
||||||
import { localStg } from '@/utils';
|
import { localStg } from '@/utils';
|
||||||
|
import { $t } from '@/locales';
|
||||||
import { useTabStore } from '../tab';
|
import { useTabStore } from '../tab';
|
||||||
import { useRouteStore } from '../route';
|
import { useRouteStore } from '../route';
|
||||||
import { getToken, getUserInfo, clearAuthStorage } from './helpers';
|
import { getToken, getUserInfo, clearAuthStorage } from './helpers';
|
||||||
@ -68,8 +69,8 @@ export const useAuthStore = defineStore('auth-store', {
|
|||||||
// 登录成功弹出欢迎提示
|
// 登录成功弹出欢迎提示
|
||||||
if (route.isInitAuthRoute) {
|
if (route.isInitAuthRoute) {
|
||||||
window.$notification?.success({
|
window.$notification?.success({
|
||||||
title: '登录成功!',
|
title: $t('page.login.common.loginSuccess'),
|
||||||
content: `欢迎回来,${this.userInfo.userName}!`,
|
content: $t('page.login.common.welcomeBack', { userName: this.userInfo.userName }),
|
||||||
duration: 3000
|
duration: 3000
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ export const useTabStore = defineStore('tab-store', {
|
|||||||
const item = this.tabs.find(tab => tab.fullPath === this.activeTab);
|
const item = this.tabs.find(tab => tab.fullPath === this.activeTab);
|
||||||
if (item) {
|
if (item) {
|
||||||
if (item.meta.i18nTitle) {
|
if (item.meta.i18nTitle) {
|
||||||
item.meta.i18nTitle = title;
|
item.meta.i18nTitle = title as I18nType.I18nKey;
|
||||||
} else {
|
} else {
|
||||||
item.meta.title = title;
|
item.meta.title = title;
|
||||||
}
|
}
|
||||||
|
2
src/typings/route.d.ts
vendored
2
src/typings/route.d.ts
vendored
@ -32,7 +32,7 @@ declare namespace AuthRoute {
|
|||||||
/** 路由标题(可用来作document.title或者菜单的名称) */
|
/** 路由标题(可用来作document.title或者菜单的名称) */
|
||||||
title: string;
|
title: string;
|
||||||
/** 用来支持多国语言 如果i18nTitle和title同时存在优先使用i18nTitle */
|
/** 用来支持多国语言 如果i18nTitle和title同时存在优先使用i18nTitle */
|
||||||
i18nTitle?: string;
|
i18nTitle?: I18nType.I18nKey;
|
||||||
/** 路由的动态路径(需要动态路径的页面需要将path添加进范型参数) */
|
/** 路由的动态路径(需要动态路径的页面需要将path添加进范型参数) */
|
||||||
dynamicPath?: AuthRouteUtils.GetDynamicPath<K>;
|
dynamicPath?: AuthRouteUtils.GetDynamicPath<K>;
|
||||||
/** 作为单级路由的父级路由布局组件 */
|
/** 作为单级路由的父级路由布局组件 */
|
||||||
|
164
src/typings/system.d.ts
vendored
164
src/typings/system.d.ts
vendored
@ -244,7 +244,7 @@ declare namespace App {
|
|||||||
routePath: string;
|
routePath: string;
|
||||||
icon?: () => import('vue').VNodeChild;
|
icon?: () => import('vue').VNodeChild;
|
||||||
children?: GlobalMenuOption[];
|
children?: GlobalMenuOption[];
|
||||||
i18nTitle?: string;
|
i18nTitle?: I18nType.I18nKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 面包屑 */
|
/** 面包屑 */
|
||||||
@ -255,8 +255,8 @@ declare namespace App {
|
|||||||
routeName: string;
|
routeName: string;
|
||||||
hasChildren: boolean;
|
hasChildren: boolean;
|
||||||
icon?: import('vue').Component;
|
icon?: import('vue').Component;
|
||||||
i18nTitle?: string;
|
i18nTitle?: I18nType.I18nKey;
|
||||||
options?: (import('naive-ui/es/dropdown/src/interface').DropdownMixedOption & { i18nTitle?: string })[];
|
options?: (import('naive-ui/es/dropdown/src/interface').DropdownMixedOption & { i18nTitle?: I18nType.I18nKey })[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 多页签Tab的路由 */
|
/** 多页签Tab的路由 */
|
||||||
@ -304,12 +304,25 @@ declare namespace App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare namespace I18nType {
|
declare namespace I18nType {
|
||||||
type langType = 'en' | 'zh-CN' | 'km-KH';
|
type LangType = 'en' | 'zh-CN' | 'km-KH';
|
||||||
|
|
||||||
interface Schema {
|
type Schema = {
|
||||||
system: {
|
system: {
|
||||||
title: string;
|
title: string;
|
||||||
};
|
};
|
||||||
|
common: {
|
||||||
|
add: string;
|
||||||
|
addSuccess: string;
|
||||||
|
edit: string;
|
||||||
|
editSuccess: string;
|
||||||
|
delete: string;
|
||||||
|
deleteSuccess: string;
|
||||||
|
batchDelete: string;
|
||||||
|
confirm: string;
|
||||||
|
cancel: string;
|
||||||
|
pleaseCheckValue: string;
|
||||||
|
action: string;
|
||||||
|
};
|
||||||
routes: {
|
routes: {
|
||||||
dashboard: {
|
dashboard: {
|
||||||
_value: string;
|
_value: string;
|
||||||
@ -360,9 +373,9 @@ declare namespace I18nType {
|
|||||||
};
|
};
|
||||||
exception: {
|
exception: {
|
||||||
_value: string;
|
_value: string;
|
||||||
403: string;
|
'403': string;
|
||||||
404: string;
|
'404': string;
|
||||||
500: string;
|
'500': string;
|
||||||
};
|
};
|
||||||
'multi-menu': {
|
'multi-menu': {
|
||||||
_value: string;
|
_value: string;
|
||||||
@ -384,5 +397,138 @@ declare namespace I18nType {
|
|||||||
};
|
};
|
||||||
about: string;
|
about: string;
|
||||||
};
|
};
|
||||||
}
|
layout: {
|
||||||
|
settingDrawer: {
|
||||||
|
title: string;
|
||||||
|
themeModeTitle: string;
|
||||||
|
darkMode: string;
|
||||||
|
layoutModelTitle: string;
|
||||||
|
systemThemeTitle: string;
|
||||||
|
pageFunctionsTitle: string;
|
||||||
|
pageViewTitle: string;
|
||||||
|
followSystemTheme: string;
|
||||||
|
isCustomizeDarkModeTransition: string;
|
||||||
|
scrollMode: string;
|
||||||
|
scrollModeList: {
|
||||||
|
wrapper: string;
|
||||||
|
content: string;
|
||||||
|
};
|
||||||
|
fixedHeaderAndTab: string;
|
||||||
|
header: {
|
||||||
|
inverted: string;
|
||||||
|
height: string;
|
||||||
|
crumb: {
|
||||||
|
visible: string;
|
||||||
|
icon: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
tab: {
|
||||||
|
visible: string;
|
||||||
|
height: string;
|
||||||
|
modeList: {
|
||||||
|
mode: string;
|
||||||
|
chrome: string;
|
||||||
|
button: string;
|
||||||
|
};
|
||||||
|
isCache: string;
|
||||||
|
};
|
||||||
|
sider: {
|
||||||
|
inverted: string;
|
||||||
|
width: string;
|
||||||
|
mixWidth: string;
|
||||||
|
};
|
||||||
|
menu: {
|
||||||
|
horizontalPosition: string;
|
||||||
|
horizontalPositionList: {
|
||||||
|
flexStart: string;
|
||||||
|
center: string;
|
||||||
|
flexEnd: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
footer: {
|
||||||
|
inverted: string;
|
||||||
|
visible: string;
|
||||||
|
fixed: string;
|
||||||
|
right: string;
|
||||||
|
};
|
||||||
|
page: {
|
||||||
|
animate: string;
|
||||||
|
animateMode: string;
|
||||||
|
animateModeList: {
|
||||||
|
zoomFade: string;
|
||||||
|
zoomOut: string;
|
||||||
|
fadeSlide: string;
|
||||||
|
fade: string;
|
||||||
|
fadeBottom: string;
|
||||||
|
fadeScale: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemTheme: {
|
||||||
|
moreColors: string;
|
||||||
|
};
|
||||||
|
themeConfiguration: {
|
||||||
|
title: string;
|
||||||
|
copy: string;
|
||||||
|
reset: string;
|
||||||
|
resetSuccess: string;
|
||||||
|
operateSuccess: string;
|
||||||
|
copySuccess: string;
|
||||||
|
confirmCopy: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
page: {
|
||||||
|
login: {
|
||||||
|
common: {
|
||||||
|
userNamePlaceholder: string;
|
||||||
|
phonePlaceholder: string;
|
||||||
|
codePlaceholder: string;
|
||||||
|
passwordPlaceholder: string;
|
||||||
|
confirmPasswordPlaceholder: string;
|
||||||
|
codeLogin: string;
|
||||||
|
confirm: string;
|
||||||
|
back: string;
|
||||||
|
validateSuccess: string;
|
||||||
|
loginSuccess: string;
|
||||||
|
welcomeBack: string;
|
||||||
|
};
|
||||||
|
pwdLogin: {
|
||||||
|
title: string;
|
||||||
|
rememberMe: string;
|
||||||
|
forgetPassword: string;
|
||||||
|
register: string;
|
||||||
|
otherAccountLogin: string;
|
||||||
|
otherLoginMode: string;
|
||||||
|
superAdmin: string;
|
||||||
|
admin: string;
|
||||||
|
user: string;
|
||||||
|
};
|
||||||
|
codeLogin: {
|
||||||
|
title: string;
|
||||||
|
getCode: string;
|
||||||
|
imageCodePlaceholder: string;
|
||||||
|
};
|
||||||
|
register: {
|
||||||
|
title: string;
|
||||||
|
agreement: string;
|
||||||
|
protocol: string;
|
||||||
|
policy: string;
|
||||||
|
};
|
||||||
|
resetPwd: {
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
bindWeChat: {
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type GetI18nKey<T extends Record<string, unknown>, K extends keyof T = keyof T> = K extends string
|
||||||
|
? T[K] extends Record<string, unknown>
|
||||||
|
? `${K}.${GetI18nKey<T[K]>}`
|
||||||
|
: K
|
||||||
|
: never;
|
||||||
|
|
||||||
|
type I18nKey = GetI18nKey<Schema>;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useIconRender } from '@/composables';
|
import { useIconRender } from '@/composables';
|
||||||
import { t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将权限路由转换成菜单
|
* 将权限路由转换成菜单
|
||||||
@ -50,7 +50,7 @@ export function translateMenuLabel(menus: App.GlobalMenuOption[]): App.GlobalMen
|
|||||||
const menuItem: App.GlobalMenuOption = {
|
const menuItem: App.GlobalMenuOption = {
|
||||||
...menu,
|
...menu,
|
||||||
children: menuChildren,
|
children: menuChildren,
|
||||||
label: menu.i18nTitle ? t(menu.i18nTitle) : menu.label
|
label: menu.i18nTitle ? $t(menu.i18nTitle) : menu.label
|
||||||
};
|
};
|
||||||
globalMenu.push(menuItem);
|
globalMenu.push(menuItem);
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
<n-form-item path="phone">
|
<n-form-item path="phone">
|
||||||
<n-input v-model:value="model.phone" placeholder="手机号码" />
|
<n-input v-model:value="model.phone" :placeholder="$t('page.login.common.phonePlaceholder')" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="code">
|
<n-form-item path="code">
|
||||||
<div class="flex-y-center w-full">
|
<div class="flex-y-center w-full">
|
||||||
<n-input v-model:value="model.code" placeholder="验证码" />
|
<n-input v-model:value="model.code" :placeholder="$t('page.login.common.codePlaceholder')" />
|
||||||
<div class="w-18px"></div>
|
<div class="w-18px"></div>
|
||||||
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
||||||
{{ label }}
|
{{ label }}
|
||||||
@ -13,8 +13,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-space :vertical="true" size="large">
|
<n-space :vertical="true" size="large">
|
||||||
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">确定</n-button>
|
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">
|
||||||
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">返回</n-button>
|
{{ $t('page.login.common.confirm') }}
|
||||||
|
</n-button>
|
||||||
|
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">
|
||||||
|
{{ $t('page.login.common.back') }}
|
||||||
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
</n-form>
|
</n-form>
|
||||||
</template>
|
</template>
|
||||||
@ -25,6 +29,7 @@ import type { FormInst } from 'naive-ui';
|
|||||||
import { useRouterPush } from '@/composables';
|
import { useRouterPush } from '@/composables';
|
||||||
import { useSmsCode } from '@/hooks';
|
import { useSmsCode } from '@/hooks';
|
||||||
import { formRules } from '@/utils';
|
import { formRules } from '@/utils';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
const { toLoginModule } = useRouterPush();
|
const { toLoginModule } = useRouterPush();
|
||||||
const { label, isCounting, loading: smsLoading, getSmsCode } = useSmsCode();
|
const { label, isCounting, loading: smsLoading, getSmsCode } = useSmsCode();
|
||||||
@ -48,7 +53,7 @@ function handleSmsCode() {
|
|||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
await formRef.value?.validate();
|
await formRef.value?.validate();
|
||||||
window.$message?.success('验证成功!');
|
window.$message?.success($t('page.login.common.validateSuccess'));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
<n-form-item path="phone">
|
<n-form-item path="phone">
|
||||||
<n-input v-model:value="model.phone" placeholder="手机号码" />
|
<n-input v-model:value="model.phone" :placeholder="$t('page.login.common.phonePlaceholder')" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="code">
|
<n-form-item path="code">
|
||||||
<div class="flex-y-center w-full">
|
<div class="flex-y-center w-full">
|
||||||
<n-input v-model:value="model.code" placeholder="验证码" />
|
<n-input v-model:value="model.code" :placeholder="$t('page.login.common.codePlaceholder')" />
|
||||||
<div class="w-18px"></div>
|
<div class="w-18px"></div>
|
||||||
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
||||||
{{ label }}
|
{{ label }}
|
||||||
@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="imgCode">
|
<n-form-item path="imgCode">
|
||||||
<n-input v-model:value="model.imgCode" placeholder="验证码,点击图片刷新" />
|
<n-input v-model:value="model.imgCode" :placeholder="$t('page.login.codeLogin.imageCodePlaceholder')" />
|
||||||
<div class="pl-8px">
|
<div class="pl-8px">
|
||||||
<image-verify v-model:code="imgCode" />
|
<image-verify v-model:code="imgCode" />
|
||||||
</div>
|
</div>
|
||||||
@ -27,9 +27,11 @@
|
|||||||
:loading="auth.loginLoading"
|
:loading="auth.loginLoading"
|
||||||
@click="handleSubmit"
|
@click="handleSubmit"
|
||||||
>
|
>
|
||||||
确定
|
{{ $t('page.login.common.confirm') }}
|
||||||
|
</n-button>
|
||||||
|
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">
|
||||||
|
{{ $t('page.login.common.back') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">返回</n-button>
|
|
||||||
</n-space>
|
</n-space>
|
||||||
</n-form>
|
</n-form>
|
||||||
</template>
|
</template>
|
||||||
@ -41,6 +43,7 @@ import { useAuthStore } from '@/store';
|
|||||||
import { useRouterPush } from '@/composables';
|
import { useRouterPush } from '@/composables';
|
||||||
import { useSmsCode } from '@/hooks';
|
import { useSmsCode } from '@/hooks';
|
||||||
import { formRules, getImgCodeRule } from '@/utils';
|
import { formRules, getImgCodeRule } from '@/utils';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
const auth = useAuthStore();
|
const auth = useAuthStore();
|
||||||
const { toLoginModule } = useRouterPush();
|
const { toLoginModule } = useRouterPush();
|
||||||
@ -68,7 +71,7 @@ function handleSmsCode() {
|
|||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
await formRef.value?.validate();
|
await formRef.value?.validate();
|
||||||
window.$message?.success('验证成功!');
|
window.$message?.success($t('page.login.common.validateSuccess'));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-space :vertical="true">
|
<n-space :vertical="true">
|
||||||
<n-divider class="!mb-0 text-14px text-#666">其他账户登录</n-divider>
|
<n-divider class="!mb-0 text-14px text-#666">{{ $t('page.login.pwdLogin.otherAccountLogin') }}</n-divider>
|
||||||
<n-space justify="center">
|
<n-space justify="center">
|
||||||
<n-button
|
<n-button
|
||||||
v-for="item in accounts"
|
v-for="item in accounts"
|
||||||
@ -15,25 +15,38 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { userRoleLabels } from '@/constants';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
(e: 'login', param: { userName: string; password: string }): void;
|
(e: 'login', param: { userName: string; password: string }): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
const accounts = [
|
interface Account {
|
||||||
|
key: Auth.RoleType;
|
||||||
|
label: string;
|
||||||
|
userName: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const accounts: Account[] = [
|
||||||
{
|
{
|
||||||
label: '超级管理员',
|
key: 'super',
|
||||||
|
label: userRoleLabels.super,
|
||||||
userName: 'Super',
|
userName: 'Super',
|
||||||
password: 'super123'
|
password: 'super123'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '管理员',
|
key: 'admin',
|
||||||
|
label: userRoleLabels.admin,
|
||||||
userName: 'Admin',
|
userName: 'Admin',
|
||||||
password: 'admin123'
|
password: 'admin123'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '普通用户',
|
key: 'user',
|
||||||
|
label: userRoleLabels.user,
|
||||||
userName: 'User01',
|
userName: 'User01',
|
||||||
password: 'user01123'
|
password: 'user01123'
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-space :vertical="true">
|
<n-space :vertical="true">
|
||||||
<n-divider class="!mb-0 text-14px text-#666">其他登录方式</n-divider>
|
<n-divider class="!mb-0 text-14px text-#666">{{ $t('page.login.pwdLogin.otherLoginMode') }}</n-divider>
|
||||||
<div class="flex-center">
|
<div class="flex-center">
|
||||||
<n-button :text="true">
|
<n-button :text="true">
|
||||||
<icon-mdi-wechat class="text-22px text-#888 hover:text-#52BF5E" />
|
<icon-mdi-wechat class="text-22px text-#888 hover:text-#52BF5E" />
|
||||||
@ -9,6 +9,8 @@
|
|||||||
</n-space>
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@ -1,15 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
<n-form-item path="userName">
|
<n-form-item path="userName">
|
||||||
<n-input v-model:value="model.userName" placeholder="请输入用户名" />
|
<n-input v-model:value="model.userName" :placeholder="$t('page.login.common.userNamePlaceholder')" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="password">
|
<n-form-item path="password">
|
||||||
<n-input v-model:value="model.password" type="password" show-password-on="click" placeholder="请输入密码" />
|
<n-input
|
||||||
|
v-model:value="model.password"
|
||||||
|
type="password"
|
||||||
|
show-password-on="click"
|
||||||
|
:placeholder="$t('page.login.common.passwordPlaceholder')"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-space :vertical="true" :size="24">
|
<n-space :vertical="true" :size="24">
|
||||||
<div class="flex-y-center justify-between">
|
<div class="flex-y-center justify-between">
|
||||||
<n-checkbox v-model:checked="rememberMe">记住我</n-checkbox>
|
<n-checkbox v-model:checked="rememberMe">{{ $t('page.login.pwdLogin.rememberMe') }}</n-checkbox>
|
||||||
<n-button :text="true" @click="toLoginModule('reset-pwd')">忘记密码?</n-button>
|
<n-button :text="true" @click="toLoginModule('reset-pwd')">
|
||||||
|
{{ $t('page.login.pwdLogin.forgetPassword') }}
|
||||||
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
<n-button
|
<n-button
|
||||||
type="primary"
|
type="primary"
|
||||||
@ -19,7 +26,7 @@
|
|||||||
:loading="auth.loginLoading"
|
:loading="auth.loginLoading"
|
||||||
@click="handleSubmit"
|
@click="handleSubmit"
|
||||||
>
|
>
|
||||||
确定
|
{{ $t('page.login.common.confirm') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
<div class="flex-y-center justify-between">
|
<div class="flex-y-center justify-between">
|
||||||
<n-button class="flex-1" :block="true" @click="toLoginModule('code-login')">
|
<n-button class="flex-1" :block="true" @click="toLoginModule('code-login')">
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
<n-form-item path="phone">
|
<n-form-item path="phone">
|
||||||
<n-input v-model:value="model.phone" placeholder="手机号码" />
|
<n-input v-model:value="model.phone" :placeholder="$t('page.login.common.phonePlaceholder')" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="code">
|
<n-form-item path="code">
|
||||||
<div class="flex-y-center w-full">
|
<div class="flex-y-center w-full">
|
||||||
<n-input v-model:value="model.code" placeholder="验证码" />
|
<n-input v-model:value="model.code" :placeholder="$t('page.login.common.codePlaceholder')" />
|
||||||
<div class="w-18px"></div>
|
<div class="w-18px"></div>
|
||||||
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
||||||
{{ label }}
|
{{ label }}
|
||||||
@ -13,15 +13,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="pwd">
|
<n-form-item path="pwd">
|
||||||
<n-input v-model:value="model.pwd" type="password" show-password-on="click" placeholder="密码" />
|
<n-input
|
||||||
|
v-model:value="model.pwd"
|
||||||
|
type="password"
|
||||||
|
show-password-on="click"
|
||||||
|
:placeholder="$t('page.login.common.passwordPlaceholder')"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="confirmPwd">
|
<n-form-item path="confirmPwd">
|
||||||
<n-input v-model:value="model.confirmPwd" type="password" show-password-on="click" placeholder="确认密码" />
|
<n-input
|
||||||
|
v-model:value="model.confirmPwd"
|
||||||
|
type="password"
|
||||||
|
show-password-on="click"
|
||||||
|
:placeholder="$t('page.login.common.confirmPasswordPlaceholder')"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-space :vertical="true" :size="18">
|
<n-space :vertical="true" :size="18">
|
||||||
<login-agreement v-model:value="agreement" />
|
<login-agreement v-model:value="agreement" />
|
||||||
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">确定</n-button>
|
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">
|
||||||
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">返回</n-button>
|
{{ $t('page.login.common.confirm') }}
|
||||||
|
</n-button>
|
||||||
|
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">
|
||||||
|
{{ $t('page.login.common.back') }}
|
||||||
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
</n-form>
|
</n-form>
|
||||||
</template>
|
</template>
|
||||||
@ -32,6 +46,7 @@ import type { FormInst, FormRules } from 'naive-ui';
|
|||||||
import { useRouterPush } from '@/composables';
|
import { useRouterPush } from '@/composables';
|
||||||
import { useSmsCode } from '@/hooks';
|
import { useSmsCode } from '@/hooks';
|
||||||
import { formRules, getConfirmPwdRule } from '@/utils';
|
import { formRules, getConfirmPwdRule } from '@/utils';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
const { toLoginModule } = useRouterPush();
|
const { toLoginModule } = useRouterPush();
|
||||||
const { label, isCounting, loading: smsLoading, start } = useSmsCode();
|
const { label, isCounting, loading: smsLoading, start } = useSmsCode();
|
||||||
@ -60,7 +75,7 @@ function handleSmsCode() {
|
|||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
await formRef.value?.validate();
|
await formRef.value?.validate();
|
||||||
window.$message?.success('验证成功!');
|
window.$message?.success($t('page.login.common.validateSuccess'));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
<n-form-item path="phone">
|
<n-form-item path="phone">
|
||||||
<n-input v-model:value="model.phone" placeholder="手机号码" />
|
<n-input v-model:value="model.phone" :placeholder="$t('page.login.common.phonePlaceholder')" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="code">
|
<n-form-item path="code">
|
||||||
<div class="flex-y-center w-full">
|
<div class="flex-y-center w-full">
|
||||||
<n-input v-model:value="model.code" placeholder="验证码" />
|
<n-input v-model:value="model.code" :placeholder="$t('page.login.common.codePlaceholder')" />
|
||||||
<div class="w-18px"></div>
|
<div class="w-18px"></div>
|
||||||
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
||||||
{{ label }}
|
{{ label }}
|
||||||
@ -13,14 +13,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="pwd">
|
<n-form-item path="pwd">
|
||||||
<n-input v-model:value="model.pwd" type="password" show-password-on="click" placeholder="密码" />
|
<n-input
|
||||||
|
v-model:value="model.pwd"
|
||||||
|
type="password"
|
||||||
|
show-password-on="click"
|
||||||
|
:placeholder="$t('page.login.common.passwordPlaceholder')"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="confirmPwd">
|
<n-form-item path="confirmPwd">
|
||||||
<n-input v-model:value="model.confirmPwd" type="password" show-password-on="click" placeholder="确认密码" />
|
<n-input
|
||||||
|
v-model:value="model.confirmPwd"
|
||||||
|
type="password"
|
||||||
|
show-password-on="click"
|
||||||
|
:placeholder="$t('page.login.common.confirmPasswordPlaceholder')"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-space :vertical="true" size="large">
|
<n-space :vertical="true" size="large">
|
||||||
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">确定</n-button>
|
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">
|
||||||
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">返回</n-button>
|
{{ $t('page.login.common.confirm') }}
|
||||||
|
</n-button>
|
||||||
|
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">
|
||||||
|
{{ $t('page.login.common.back') }}
|
||||||
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
</n-form>
|
</n-form>
|
||||||
</template>
|
</template>
|
||||||
@ -31,6 +45,7 @@ import type { FormInst, FormRules } from 'naive-ui';
|
|||||||
import { useRouterPush } from '@/composables';
|
import { useRouterPush } from '@/composables';
|
||||||
import { useSmsCode } from '@/hooks';
|
import { useSmsCode } from '@/hooks';
|
||||||
import { formRules, getConfirmPwdRule } from '@/utils';
|
import { formRules, getConfirmPwdRule } from '@/utils';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
const { toLoginModule } = useRouterPush();
|
const { toLoginModule } = useRouterPush();
|
||||||
const { label, isCounting, loading: smsLoading, start } = useSmsCode();
|
const { label, isCounting, loading: smsLoading, start } = useSmsCode();
|
||||||
@ -57,7 +72,7 @@ function handleSmsCode() {
|
|||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
await formRef.value?.validate();
|
await formRef.value?.validate();
|
||||||
window.$message?.success('验证成功!');
|
window.$message?.success($t('page.login.common.validateSuccess'));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<div class="w-300px sm:w-360px">
|
<div class="w-300px sm:w-360px">
|
||||||
<header class="flex-y-center justify-between">
|
<header class="flex-y-center justify-between">
|
||||||
<system-logo class="text-64px text-primary" />
|
<system-logo class="text-64px text-primary" />
|
||||||
<n-gradient-text type="primary" :size="28">{{ title }}</n-gradient-text>
|
<n-gradient-text type="primary" :size="28">{{ $t('system.title') }}</n-gradient-text>
|
||||||
</header>
|
</header>
|
||||||
<main class="pt-24px">
|
<main class="pt-24px">
|
||||||
<h3 class="text-18px text-primary font-medium">{{ activeModule.label }}</h3>
|
<h3 class="text-18px text-primary font-medium">{{ activeModule.label }}</h3>
|
||||||
@ -30,8 +30,8 @@ import { computed } from 'vue';
|
|||||||
import type { Component } from 'vue';
|
import type { Component } from 'vue';
|
||||||
import { loginModuleLabels } from '@/constants';
|
import { loginModuleLabels } from '@/constants';
|
||||||
import { useThemeStore } from '@/store';
|
import { useThemeStore } from '@/store';
|
||||||
import { useAppInfo } from '@/composables';
|
|
||||||
import { getColorPalette, mixColor } from '@/utils';
|
import { getColorPalette, mixColor } from '@/utils';
|
||||||
|
import { $t } from '@/locales';
|
||||||
import { BindWechat, CodeLogin, LoginBg, PwdLogin, Register, ResetPwd } from './components';
|
import { BindWechat, CodeLogin, LoginBg, PwdLogin, Register, ResetPwd } from './components';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -42,7 +42,6 @@ interface Props {
|
|||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
const theme = useThemeStore();
|
const theme = useThemeStore();
|
||||||
const { title } = useAppInfo();
|
|
||||||
|
|
||||||
interface LoginModule {
|
interface LoginModule {
|
||||||
key: UnionKey.LoginModule;
|
key: UnionKey.LoginModule;
|
||||||
|
Loading…
Reference in New Issue
Block a user