mirror of
https://github.com/chansee97/nova-admin.git
synced 2025-09-17 19:29:58 +08:00
refactor: 整理代码组织
This commit is contained in:
parent
d54810ab02
commit
34f0dda267
2
.env
2
.env
@ -11,7 +11,7 @@ VITE_ROUTE_MODE = web
|
||||
VITE_ROUTE_LOAD_MODE = static
|
||||
|
||||
# 设置登陆后跳转地址
|
||||
VITE_HOME_PATH = /dashboard/workbench
|
||||
VITE_HOME_PATH = /home
|
||||
|
||||
# 本地存储前缀
|
||||
VITE_STORAGE_PREFIX =
|
||||
|
@ -90,20 +90,18 @@
|
||||
},
|
||||
"route": {
|
||||
"appRoot": "Home",
|
||||
"home": "Overview",
|
||||
"cardList": "Card list",
|
||||
"draggableList": "Draggable list",
|
||||
"commonList": "Common list",
|
||||
"dashboard": "Dashboard",
|
||||
"demo": "Function example",
|
||||
"fetch": "Request example",
|
||||
"list": "List",
|
||||
"monitor": "Monitoring",
|
||||
"multi": "Multi-level menu",
|
||||
"multi2": "Multi-level menu subpage",
|
||||
"multi2Detail": "Details page of multi-level menu",
|
||||
"multi3": "multi-level menu",
|
||||
"multi4": "Multi-level menu 3-1",
|
||||
"workbench": "Workbench",
|
||||
"QRCode": "QR code",
|
||||
"about": "About",
|
||||
"clipboard": "Clipboard",
|
||||
|
@ -119,9 +119,7 @@
|
||||
},
|
||||
"route": {
|
||||
"appRoot": "首页",
|
||||
"dashboard": "仪表盘",
|
||||
"workbench": "工作台",
|
||||
"monitor": "监控页",
|
||||
"home": "概览",
|
||||
"multi": "多级菜单演示",
|
||||
"multi2": "多级菜单子页",
|
||||
"multi2Detail": "多级菜单的详情页",
|
||||
|
@ -40,6 +40,10 @@ const naiveLocale = computed(() => {
|
||||
})
|
||||
|
||||
const propOverrides = {
|
||||
ProSearchForm: {
|
||||
labelPlacement: 'left',
|
||||
cols: 4,
|
||||
},
|
||||
ProModalForm: {
|
||||
labelWidth: 120,
|
||||
labelPlacement: 'left',
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { request } from '../http'
|
||||
import { request } from '../utils/alova'
|
||||
|
||||
/* 示例列表接口 */
|
||||
export function fetchUserList() {
|
7
src/api/index.ts
Normal file
7
src/api/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export * from './login'
|
||||
export * from './demo'
|
||||
export * from './test'
|
||||
export * from './system/user'
|
||||
export * from './system/menu'
|
||||
export * from './system/role'
|
||||
export * from './system/dict'
|
@ -1,4 +1,4 @@
|
||||
import { request } from '../http'
|
||||
import { request } from '../utils/alova'
|
||||
|
||||
interface LoginParams {
|
||||
userName: string
|
@ -1,4 +1,4 @@
|
||||
import { request } from '../../http'
|
||||
import { request } from '../../utils/alova'
|
||||
|
||||
// 字典类型查询参数接口
|
||||
interface DictTypeQueryParams {
|
@ -1,4 +1,4 @@
|
||||
import { request } from '../../http'
|
||||
import { request } from '../../utils/alova'
|
||||
|
||||
/**
|
||||
* 创建菜单
|
@ -1,4 +1,4 @@
|
||||
import { request } from '../../http'
|
||||
import { request } from '../../utils/alova'
|
||||
|
||||
// 角色查询参数接口
|
||||
interface RoleQueryParams {
|
@ -1,4 +1,4 @@
|
||||
import { request } from '../../http'
|
||||
import { request } from '../../utils/alova'
|
||||
|
||||
// 用户查询参数接口
|
||||
interface UserQueryParams {
|
@ -1,4 +1,4 @@
|
||||
import { blankInstance, request } from '../http'
|
||||
import { blankInstance, request } from '@/utils/alova'
|
||||
|
||||
/* get方法测试 */
|
||||
export function fetchGet(params?: any) {
|
14
src/modules/navie-pro.ts
Normal file
14
src/modules/navie-pro.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import {
|
||||
create,
|
||||
ProInput,
|
||||
ProSelect,
|
||||
} from 'pro-naive-ui'
|
||||
import type { App } from 'vue'
|
||||
|
||||
const proNaive = create({
|
||||
components: [ProInput, ProSelect],
|
||||
})
|
||||
|
||||
export function install(app: App) {
|
||||
app.use(proNaive)
|
||||
}
|
@ -1,37 +1,14 @@
|
||||
export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
{
|
||||
name: 'dashboard',
|
||||
path: '/dashboard',
|
||||
title: '仪表盘',
|
||||
requiresAuth: true,
|
||||
name: 'home',
|
||||
path: '/home',
|
||||
title: '概览',
|
||||
icon: 'icon-park-outline:analysis',
|
||||
menuType: 'dir',
|
||||
componentPath: null,
|
||||
id: 1,
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
name: 'workbench',
|
||||
path: '/dashboard/workbench',
|
||||
title: '工作台',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:alarm',
|
||||
pinTab: true,
|
||||
menuType: 'page',
|
||||
componentPath: '/dashboard/workbench/index.vue',
|
||||
id: 101,
|
||||
parentId: 1,
|
||||
},
|
||||
{
|
||||
name: 'monitor',
|
||||
path: '/dashboard/monitor',
|
||||
title: '监控页',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:anchor',
|
||||
menuType: 'page',
|
||||
componentPath: '/dashboard/monitor/index.vue',
|
||||
id: 102,
|
||||
parentId: 1,
|
||||
component: '/build-in/home/index.vue',
|
||||
id: 1,
|
||||
parentId: 0,
|
||||
},
|
||||
{
|
||||
name: 'multi',
|
||||
@ -40,7 +17,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:list',
|
||||
menuType: 'dir',
|
||||
componentPath: null,
|
||||
component: null,
|
||||
id: 2,
|
||||
parentId: null,
|
||||
},
|
||||
@ -51,7 +28,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:list',
|
||||
menuType: 'page',
|
||||
componentPath: '/demo/multi/multi-2/index.vue',
|
||||
component: '/demo/multi/multi-2/index.vue',
|
||||
id: 201,
|
||||
parentId: 2,
|
||||
},
|
||||
@ -64,7 +41,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
hide: true,
|
||||
activeMenu: '/multi/multi-2',
|
||||
menuType: 'page',
|
||||
componentPath: '/demo/multi/multi-2/detail/index.vue',
|
||||
component: '/demo/multi/multi-2/detail/index.vue',
|
||||
id: 20101,
|
||||
parentId: 2,
|
||||
},
|
||||
@ -75,7 +52,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:list',
|
||||
menuType: 'dir',
|
||||
componentPath: null,
|
||||
component: null,
|
||||
id: 202,
|
||||
parentId: 2,
|
||||
},
|
||||
@ -85,7 +62,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '多级菜单3-1',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:list',
|
||||
componentPath: '/demo/multi/multi-3/multi-4/index.vue',
|
||||
component: '/demo/multi/multi-3/multi-4/index.vue',
|
||||
id: 20201,
|
||||
parentId: 202,
|
||||
},
|
||||
@ -96,7 +73,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:list-two',
|
||||
menuType: 'dir',
|
||||
componentPath: null,
|
||||
component: null,
|
||||
id: 3,
|
||||
parentId: null,
|
||||
},
|
||||
@ -106,7 +83,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '常用列表',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:list-view',
|
||||
componentPath: '/demo/list/common-list/index.vue',
|
||||
component: '/demo/list/common-list/index.vue',
|
||||
id: 301,
|
||||
parentId: 3,
|
||||
},
|
||||
@ -116,7 +93,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '卡片列表',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:view-grid-list',
|
||||
componentPath: '/demo/list/card-list/index.vue',
|
||||
component: '/demo/list/card-list/index.vue',
|
||||
id: 302,
|
||||
parentId: 3,
|
||||
},
|
||||
@ -126,7 +103,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '拖拽列表',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:menu-fold',
|
||||
componentPath: '/demo/list/draggable-list/index.vue',
|
||||
component: '/demo/list/draggable-list/index.vue',
|
||||
id: 303,
|
||||
parentId: 3,
|
||||
},
|
||||
@ -137,7 +114,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:application-one',
|
||||
menuType: 'dir',
|
||||
componentPath: null,
|
||||
component: null,
|
||||
id: 4,
|
||||
parentId: null,
|
||||
},
|
||||
@ -147,7 +124,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '请求示例',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:international',
|
||||
componentPath: '/demo/fetch/index.vue',
|
||||
component: '/demo/fetch/index.vue',
|
||||
id: 401,
|
||||
parentId: 4,
|
||||
},
|
||||
@ -157,7 +134,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: 'ECharts',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:chart-proportion',
|
||||
componentPath: '/demo/echarts/index.vue',
|
||||
component: '/demo/echarts/index.vue',
|
||||
id: 402,
|
||||
parentId: 4,
|
||||
},
|
||||
@ -168,7 +145,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'carbon:map',
|
||||
keepAlive: true,
|
||||
componentPath: '/demo/map/index.vue',
|
||||
component: '/demo/map/index.vue',
|
||||
id: 403,
|
||||
parentId: 4,
|
||||
},
|
||||
@ -179,7 +156,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:editor',
|
||||
menuType: 'dir',
|
||||
componentPath: null,
|
||||
component: null,
|
||||
id: 404,
|
||||
parentId: 4,
|
||||
},
|
||||
@ -189,7 +166,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: 'MarkDown',
|
||||
requiresAuth: true,
|
||||
icon: 'ri:markdown-line',
|
||||
componentPath: '/demo/editor/md/index.vue',
|
||||
component: '/demo/editor/md/index.vue',
|
||||
id: 40401,
|
||||
parentId: 404,
|
||||
},
|
||||
@ -199,7 +176,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '富文本',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:edit-one',
|
||||
componentPath: '/demo/editor/rich/index.vue',
|
||||
component: '/demo/editor/rich/index.vue',
|
||||
id: 40402,
|
||||
parentId: 404,
|
||||
},
|
||||
@ -209,7 +186,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '剪贴板',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:clipboard',
|
||||
componentPath: '/demo/clipboard/index.vue',
|
||||
component: '/demo/clipboard/index.vue',
|
||||
id: 405,
|
||||
parentId: 4,
|
||||
},
|
||||
@ -219,7 +196,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '图标',
|
||||
requiresAuth: true,
|
||||
icon: 'local:cool',
|
||||
componentPath: '/demo/icons/index.vue',
|
||||
component: '/demo/icons/index.vue',
|
||||
id: 406,
|
||||
parentId: 4,
|
||||
},
|
||||
@ -229,7 +206,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '二维码',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:two-dimensional-code',
|
||||
componentPath: '/demo/qr-code/index.vue',
|
||||
component: '/demo/qr-code/index.vue',
|
||||
id: 407,
|
||||
parentId: 4,
|
||||
},
|
||||
@ -239,7 +216,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '省市区联动',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:add-subset',
|
||||
componentPath: '/demo/cascader/index.vue',
|
||||
component: '/demo/cascader/index.vue',
|
||||
id: 408,
|
||||
parentId: 4,
|
||||
},
|
||||
@ -249,7 +226,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '字典示例',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:book-one',
|
||||
componentPath: '/demo/dict/index.vue',
|
||||
component: '/demo/dict/index.vue',
|
||||
id: 409,
|
||||
parentId: 4,
|
||||
},
|
||||
@ -260,7 +237,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:file-doc',
|
||||
menuType: 'dir',
|
||||
componentPath: null,
|
||||
component: null,
|
||||
id: 5,
|
||||
parentId: null,
|
||||
},
|
||||
@ -270,7 +247,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: 'Vue',
|
||||
requiresAuth: true,
|
||||
icon: 'logos:vue',
|
||||
componentPath: '/demo/documents/vue/index.vue',
|
||||
component: '/demo/documents/vue/index.vue',
|
||||
id: 501,
|
||||
parentId: 5,
|
||||
},
|
||||
@ -280,7 +257,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: 'Vite',
|
||||
requiresAuth: true,
|
||||
icon: 'logos:vitejs',
|
||||
componentPath: '/demo/documents/vite/index.vue',
|
||||
component: '/demo/documents/vite/index.vue',
|
||||
id: 502,
|
||||
parentId: 5,
|
||||
},
|
||||
@ -291,7 +268,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'logos:vueuse',
|
||||
href: 'https://vueuse.org/guide/',
|
||||
componentPath: 'null',
|
||||
component: 'null',
|
||||
id: 503,
|
||||
parentId: 5,
|
||||
},
|
||||
@ -303,7 +280,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'local:logo',
|
||||
href: 'https://nova-admin-docs.netlify.app/',
|
||||
componentPath: '2333333',
|
||||
component: '2333333',
|
||||
id: 504,
|
||||
parentId: 5,
|
||||
},
|
||||
@ -314,7 +291,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'local:logo',
|
||||
href: '/public',
|
||||
componentPath: 'null',
|
||||
component: 'null',
|
||||
id: 505,
|
||||
parentId: 5,
|
||||
},
|
||||
@ -325,7 +302,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:people-safe',
|
||||
menuType: 'dir',
|
||||
componentPath: null,
|
||||
component: null,
|
||||
id: 6,
|
||||
parentId: null,
|
||||
},
|
||||
@ -335,7 +312,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '权限示例',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:right-user',
|
||||
componentPath: '/demo/permission/permission/index.vue',
|
||||
component: '/demo/permission/permission/index.vue',
|
||||
id: 601,
|
||||
parentId: 6,
|
||||
},
|
||||
@ -348,7 +325,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
'super',
|
||||
],
|
||||
icon: 'icon-park-outline:wrong-user',
|
||||
componentPath: '/demo/permission/just-super/index.vue',
|
||||
component: '/demo/permission/just-super/index.vue',
|
||||
id: 602,
|
||||
parentId: 6,
|
||||
},
|
||||
@ -359,27 +336,27 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:setting',
|
||||
menuType: 'dir',
|
||||
componentPath: null,
|
||||
component: null,
|
||||
id: 7,
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
name: 'accountSetting',
|
||||
path: '/setting/account',
|
||||
path: '/setting/user',
|
||||
title: '用户设置',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:every-user',
|
||||
componentPath: '/setting/account/index.vue',
|
||||
component: '/setting/user/index.vue',
|
||||
id: 701,
|
||||
parentId: 7,
|
||||
},
|
||||
{
|
||||
name: 'dictionarySetting',
|
||||
path: '/setting/dictionary',
|
||||
path: '/setting/dict',
|
||||
title: '字典设置',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:book-one',
|
||||
componentPath: '/setting/dictionary/index.vue',
|
||||
component: '/setting/dict/index.vue',
|
||||
id: 702,
|
||||
parentId: 7,
|
||||
},
|
||||
@ -389,7 +366,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '菜单设置',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:application-menu',
|
||||
componentPath: '/setting/menu/index.vue',
|
||||
component: '/setting/menu/index.vue',
|
||||
id: 703,
|
||||
parentId: 7,
|
||||
},
|
||||
@ -399,7 +376,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
title: '关于',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-park-outline:info',
|
||||
componentPath: '/demo/about/index.vue',
|
||||
component: '/demo/about/index.vue',
|
||||
id: 8,
|
||||
parentId: null,
|
||||
},
|
||||
@ -410,7 +387,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
|
||||
requiresAuth: true,
|
||||
hide: true,
|
||||
icon: 'carbon:user-avatar-filled-alt',
|
||||
componentPath: '/build-in/user-center/index.vue',
|
||||
component: '/build-in/user-center/index.vue',
|
||||
id: 999,
|
||||
parentId: null,
|
||||
},
|
||||
|
@ -1,7 +0,0 @@
|
||||
export * from './api/login'
|
||||
export * from './api/demo'
|
||||
export * from './api/test'
|
||||
export * from './api/system/user'
|
||||
export * from './api/system/menu'
|
||||
export * from './api/system/role'
|
||||
export * from './api/system/dict'
|
@ -1,16 +1,16 @@
|
||||
import { router } from '@/router'
|
||||
import { fetchLogin, fetchUserInfo } from '@/service'
|
||||
import { fetchLogin, fetchUserInfo } from '@/api'
|
||||
import { local } from '@/utils'
|
||||
import { useRouteStore } from './router'
|
||||
import { useTabStore } from './tab'
|
||||
|
||||
interface AuthStatus {
|
||||
userInfo: Entity.User | null
|
||||
userInfo: Entity.User | Record<string, any>
|
||||
}
|
||||
export const useAuthStore = defineStore('auth-store', {
|
||||
state: (): AuthStatus => {
|
||||
return {
|
||||
userInfo: null,
|
||||
userInfo: {},
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { fetchDictList } from '@/service'
|
||||
import { fetchDictList } from '@/api'
|
||||
import { session } from '@/utils'
|
||||
|
||||
export const useDictStore = defineStore('dict-store', {
|
||||
|
@ -31,15 +31,14 @@ export function createRoutes(routes: AppRoute.RowRoute[]) {
|
||||
// Generate routes, no need to import files for those with redirect
|
||||
const modules = import.meta.glob('@/views/**/*.vue')
|
||||
resultRouter = resultRouter.map((item: AppRoute.Route) => {
|
||||
if (item.componentPath && !item.redirect)
|
||||
item.component = modules[`/src/views${item.componentPath}`]
|
||||
if (item.component && !item.redirect)
|
||||
item.component = modules[`/src/views${item.component}`]
|
||||
return item
|
||||
})
|
||||
|
||||
// Generate route tree
|
||||
resultRouter = arrayToTree(resultRouter, {
|
||||
parentProperty: 'parentId',
|
||||
customID: 'id',
|
||||
}) as AppRoute.Route[]
|
||||
|
||||
const appRootRoute: RouteRecordRaw = {
|
||||
@ -104,7 +103,6 @@ export function createMenus(userRoutes: AppRoute.RowRoute[]) {
|
||||
// generate side menu
|
||||
return arrayToTree(transformAuthRoutesToMenus(visibleMenus), {
|
||||
parentProperty: 'parentId',
|
||||
customID: 'id',
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { MenuOption } from 'naive-ui'
|
||||
import { router } from '@/router'
|
||||
import { staticRoutes } from '@/router/routes.static'
|
||||
import { fetchUserRoutes } from '@/service'
|
||||
import { fetchUserRoutes } from '@/api'
|
||||
import { $t } from '@/utils'
|
||||
import { createMenus, createRoutes, generateCacheRoutes } from './helper'
|
||||
|
||||
|
2
src/typings/entities/menu.d.ts
vendored
2
src/typings/entities/menu.d.ts
vendored
@ -5,7 +5,7 @@ namespace Entity {
|
||||
type MenuType = 'directory' | 'page' | 'permission'
|
||||
|
||||
interface Menu {
|
||||
menuId: number
|
||||
id: number
|
||||
/**
|
||||
* 组件路径
|
||||
*/
|
||||
|
2
src/typings/route.d.ts
vendored
2
src/typings/route.d.ts
vendored
@ -39,7 +39,7 @@ declare namespace AppRoute {
|
||||
/** 路由重定向 */
|
||||
redirect?: string
|
||||
/* 页面组件地址 */
|
||||
componentPath?: string | null
|
||||
component?: string | null
|
||||
/* 路由id */
|
||||
id: number
|
||||
/* 父级路由id,顶级页面为null */
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { fetchRefreshToken } from '@/service'
|
||||
import { fetchRefreshToken } from '@/api'
|
||||
import { useAuthStore } from '@/store'
|
||||
import { local } from '@/utils'
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInst } from 'naive-ui'
|
||||
import { useAuthStore } from '@/store'
|
||||
import { fetchCaptchaImage } from '@/service'
|
||||
import { fetchCaptchaImage } from '@/api'
|
||||
import { local } from '@/utils'
|
||||
import { useBoolean } from '@/hooks'
|
||||
|
||||
|
@ -1,130 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useEcharts } from '@/hooks'
|
||||
import type { ECOption } from '@/hooks'
|
||||
import { graphic } from 'echarts'
|
||||
|
||||
const lineOptions = ref<ECOption>({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
grid: {
|
||||
left: '2%',
|
||||
right: '2%',
|
||||
bottom: '0%',
|
||||
top: '0%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: ['10:00', '10:10', '10:10', '10:30', '10:40', '10:50'],
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
series: [{
|
||||
name: '2',
|
||||
type: 'line',
|
||||
z: 3,
|
||||
showSymbol: false,
|
||||
smoothMonotone: 'x',
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0,
|
||||
color: 'rgba(59,102,246)', // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1,
|
||||
color: 'rgba(118,237,252)', // 100% 处的颜色
|
||||
}],
|
||||
},
|
||||
shadowBlur: 4,
|
||||
shadowColor: 'rgba(69,126,247,.2)',
|
||||
shadowOffsetY: 4,
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0,
|
||||
color: 'rgba(227,233,250,.9)', // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1,
|
||||
color: 'rgba(248,251,252,.3)', // 100% 处的颜色
|
||||
}],
|
||||
},
|
||||
},
|
||||
smooth: true,
|
||||
data: [20, 56, 17, 40, 68, 42],
|
||||
}, {
|
||||
name: '1',
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
smoothMonotone: 'x',
|
||||
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: new graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(255,84,108)',
|
||||
}, {
|
||||
offset: 1,
|
||||
color: 'rgba(252,140,118)',
|
||||
}], false),
|
||||
shadowBlur: 4,
|
||||
shadowColor: 'rgba(253,121,128,.2)',
|
||||
shadowOffsetY: 4,
|
||||
},
|
||||
areaStyle: {
|
||||
color: new graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(255,84,108,.15)',
|
||||
}, {
|
||||
offset: 1,
|
||||
color: 'rgba(252,140,118,0)',
|
||||
}], false),
|
||||
},
|
||||
smooth: true,
|
||||
data: [20, 71, 8, 50, 57, 32],
|
||||
}],
|
||||
}) as Ref<ECOption>
|
||||
|
||||
useEcharts('lineRef', lineOptions)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
ref="lineRef"
|
||||
class="h-400px"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,107 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useEcharts } from '@/hooks'
|
||||
import type { ECOption } from '@/hooks'
|
||||
import { graphic } from 'echarts'
|
||||
|
||||
const chartData = [
|
||||
{ name: '1', value: 300 },
|
||||
{ name: '2', value: 400 },
|
||||
{ name: '3', value: 452 },
|
||||
{ name: '4', value: 770 },
|
||||
{ name: '5', value: 650 },
|
||||
{ name: '6', value: 256 },
|
||||
{ name: '7', value: 350 },
|
||||
{ name: '8', value: 422 },
|
||||
{ name: '9', value: 235 },
|
||||
{ name: '10', value: 658 },
|
||||
{ name: '11', value: 600 },
|
||||
{ name: '12', value: 400 },
|
||||
{ name: '13', value: 523 },
|
||||
{ name: '14', value: 482 },
|
||||
{ name: '15', value: 423 },
|
||||
]
|
||||
|
||||
const xData = chartData.map(v => v.name)
|
||||
const sData = chartData.map(v => v.value)
|
||||
|
||||
const option = ref<ECOption>({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
grid: {
|
||||
left: '2%',
|
||||
right: '2%',
|
||||
bottom: '0%',
|
||||
top: '0%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: xData,
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(151,151,151,0.5)',
|
||||
type: 'dashed',
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
margin: 10,
|
||||
color: '#666',
|
||||
fontSize: 14,
|
||||
},
|
||||
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(151,151,151,0.5)',
|
||||
type: 'dashed',
|
||||
},
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(151,151,151,0.5)',
|
||||
type: 'dashed',
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
series: [{
|
||||
type: 'bar',
|
||||
barWidth: '20px',
|
||||
data: sData,
|
||||
itemStyle: {
|
||||
color: new graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: '#00BD89', // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1,
|
||||
color: '#C9F9E1', // 100% 处的颜色
|
||||
}], false),
|
||||
},
|
||||
}],
|
||||
}) as Ref<ECOption>
|
||||
|
||||
useEcharts('lineRef', option)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
ref="lineRef"
|
||||
class="h-400px"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,60 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useEcharts } from '@/hooks'
|
||||
import type { ECOption } from '@/hooks'
|
||||
|
||||
const option = ref<ECOption>({
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b} : {d}%',
|
||||
},
|
||||
legend: {
|
||||
orient: 'horizontal',
|
||||
top: 30,
|
||||
padding: 5,
|
||||
itemWidth: 20,
|
||||
itemHeight: 12,
|
||||
textStyle: {
|
||||
color: '#777',
|
||||
},
|
||||
},
|
||||
series: [{
|
||||
type: 'pie',
|
||||
radius: ['45%', '60%'],
|
||||
center: ['50%', '50%'],
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b} : {d}%',
|
||||
color: '#777',
|
||||
},
|
||||
labelLine: {
|
||||
show: true,
|
||||
length2: 10,
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: 335,
|
||||
name: '直接访问',
|
||||
},
|
||||
{
|
||||
value: 77,
|
||||
name: 'Bilibili',
|
||||
},
|
||||
{
|
||||
value: 82,
|
||||
name: '知乎',
|
||||
},
|
||||
{
|
||||
value: 421,
|
||||
name: '小红书',
|
||||
},
|
||||
],
|
||||
}],
|
||||
}) as Ref<ECOption>
|
||||
useEcharts('lineRef', option)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="lineRef" class="h-400px" />
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@ -1,258 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useAppStore } from '@/store'
|
||||
import Chart from './components/chart.vue'
|
||||
import Chart2 from './components/chart2.vue'
|
||||
import Chart3 from './components/chart3.vue'
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
id: 0,
|
||||
name: '商品名称1',
|
||||
start: '2022-02-02',
|
||||
end: '2022-02-02',
|
||||
prograss: '100',
|
||||
status: '已完成',
|
||||
},
|
||||
{
|
||||
id: 0,
|
||||
name: '商品名称2',
|
||||
start: '2022-02-02',
|
||||
end: '2022-02-02',
|
||||
prograss: '50',
|
||||
status: '交易中',
|
||||
},
|
||||
{
|
||||
id: 0,
|
||||
name: '商品名称3',
|
||||
start: '2022-02-02',
|
||||
end: '2022-02-02',
|
||||
prograss: '100',
|
||||
status: '已完成',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-grid
|
||||
:x-gap="16"
|
||||
:y-gap="16"
|
||||
:cols="12"
|
||||
item-responsive
|
||||
responsive="screen"
|
||||
>
|
||||
<!-- 统计卡片 - 移动端每行2个,桌面端每行4个 -->
|
||||
<n-gi span="6 m:3">
|
||||
<n-card>
|
||||
<n-space
|
||||
justify="space-between"
|
||||
align="center"
|
||||
>
|
||||
<n-statistic label="访问量">
|
||||
<n-number-animation
|
||||
:from="0"
|
||||
:to="12039"
|
||||
show-separator
|
||||
/>
|
||||
</n-statistic>
|
||||
<n-icon
|
||||
color="#de4307"
|
||||
size="42"
|
||||
>
|
||||
<icon-park-outline-chart-histogram />
|
||||
</n-icon>
|
||||
</n-space>
|
||||
<template #footer>
|
||||
<n-space justify="space-between">
|
||||
<span>累计访问数</span>
|
||||
<span><n-number-animation
|
||||
:from="0"
|
||||
:to="322039"
|
||||
show-separator
|
||||
/></span>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi span="6 m:3">
|
||||
<n-card>
|
||||
<n-space
|
||||
justify="space-between"
|
||||
align="center"
|
||||
>
|
||||
<n-statistic label="下载量">
|
||||
<n-number-animation
|
||||
:from="0"
|
||||
:to="12039"
|
||||
show-separator
|
||||
/>
|
||||
</n-statistic>
|
||||
<n-icon
|
||||
color="#ffb549"
|
||||
size="42"
|
||||
>
|
||||
<icon-park-outline-chart-graph />
|
||||
</n-icon>
|
||||
</n-space>
|
||||
<template #footer>
|
||||
<n-space justify="space-between">
|
||||
<span>累计下载量</span>
|
||||
<span><n-number-animation
|
||||
:from="0"
|
||||
:to="322039"
|
||||
show-separator
|
||||
/></span>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi span="6 m:3">
|
||||
<n-card>
|
||||
<n-space
|
||||
justify="space-between"
|
||||
align="center"
|
||||
>
|
||||
<n-statistic label="浏览量">
|
||||
<n-number-animation
|
||||
:from="0"
|
||||
:to="12039"
|
||||
show-separator
|
||||
/>
|
||||
</n-statistic>
|
||||
<n-icon
|
||||
color="#1687a7"
|
||||
size="42"
|
||||
>
|
||||
<icon-park-outline-average />
|
||||
</n-icon>
|
||||
</n-space>
|
||||
<template #footer>
|
||||
<n-space justify="space-between">
|
||||
<span>累计浏览量</span>
|
||||
<span><n-number-animation
|
||||
:from="0"
|
||||
:to="322039"
|
||||
show-separator
|
||||
/></span>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi span="6 m:3">
|
||||
<n-card>
|
||||
<n-space
|
||||
justify="space-between"
|
||||
align="center"
|
||||
>
|
||||
<n-statistic label="注册量">
|
||||
<n-number-animation
|
||||
:from="0"
|
||||
:to="12039"
|
||||
show-separator
|
||||
/>
|
||||
</n-statistic>
|
||||
<n-icon
|
||||
color="#42218E"
|
||||
size="42"
|
||||
>
|
||||
<icon-park-outline-chart-pie />
|
||||
</n-icon>
|
||||
</n-space>
|
||||
<template #footer>
|
||||
<n-space justify="space-between">
|
||||
<span>累计注册量</span>
|
||||
<span><n-number-animation
|
||||
:from="0"
|
||||
:to="322039"
|
||||
show-separator
|
||||
/></span>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<!-- 图表区域 - 全宽显示 -->
|
||||
<n-gi :span="12">
|
||||
<n-card content-style="padding: 0;">
|
||||
<n-tabs
|
||||
type="line"
|
||||
size="large"
|
||||
:tabs-padding="20"
|
||||
pane-style="padding: 20px;"
|
||||
>
|
||||
<n-tab-pane name="流量趋势">
|
||||
<Chart />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="访问量趋势">
|
||||
<Chart2 />
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
|
||||
<!-- 访问来源 - 移动端全宽,桌面端1/3宽 -->
|
||||
<n-gi span="12 m:4">
|
||||
<n-card
|
||||
title="访问来源"
|
||||
:segmented="{
|
||||
content: true,
|
||||
}"
|
||||
>
|
||||
<Chart3 />
|
||||
</n-card>
|
||||
</n-gi>
|
||||
|
||||
<!-- 成交记录 - 移动端全宽,桌面端2/3宽 -->
|
||||
<n-gi span="12 m:8">
|
||||
<n-card
|
||||
title="成交记录"
|
||||
:segmented="{
|
||||
content: true,
|
||||
}"
|
||||
>
|
||||
<template #header-extra>
|
||||
<n-button
|
||||
type="primary"
|
||||
quaternary
|
||||
>
|
||||
更多
|
||||
</n-button>
|
||||
</template>
|
||||
<n-table
|
||||
:bordered="false"
|
||||
:single-line="false"
|
||||
:scroll-x="appStore.isMobile ? 600 : undefined"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>交易名称</th>
|
||||
<th>开始时间</th>
|
||||
<th>结束时间</th>
|
||||
<th>进度</th>
|
||||
<th>状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="item in tableData"
|
||||
:key="item.id"
|
||||
>
|
||||
<td>{{ item.name }}</td>
|
||||
<td>{{ item.start }}</td>
|
||||
<td>{{ item.end }}</td>
|
||||
<td>{{ item.prograss }}%</td>
|
||||
<td>
|
||||
<n-tag
|
||||
:bordered="false"
|
||||
type="info"
|
||||
>
|
||||
{{ item.status }}
|
||||
</n-tag>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</template>
|
@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { fetchDictList } from '@/service'
|
||||
import { fetchDictList } from '@/api'
|
||||
import { useDictStore } from '@/store'
|
||||
|
||||
const { dict } = useDictStore()
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
fetchDelete,
|
||||
} from '@/service'
|
||||
} from '@/api'
|
||||
|
||||
const emit = defineEmits<{
|
||||
update: [data: any] // 具名元组语法
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
getBlob,
|
||||
} from '@/service'
|
||||
} from '@/api'
|
||||
|
||||
const emit = defineEmits<{
|
||||
update: [data: any]
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
downloadFile,
|
||||
} from '@/service'
|
||||
} from '@/api'
|
||||
import { useRequest } from 'alova/client'
|
||||
import { normalizeSizeUnits } from '@/utils'
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
FailedRequest,
|
||||
} from '@/service'
|
||||
} from '@/api'
|
||||
|
||||
const emit = defineEmits<{
|
||||
update: [data: any] // 具名元组语法
|
||||
|
@ -1,164 +0,0 @@
|
||||
<script setup lang="tsx">
|
||||
import type { FormInst } from 'naive-ui'
|
||||
import { useBoolean } from '@/hooks'
|
||||
import { deleteUser, getUserList, updateUser } from '@/service'
|
||||
import { createUserColumns } from './columns'
|
||||
import TableModal from './components/TableModal.vue'
|
||||
|
||||
const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
|
||||
|
||||
const initialModel = {
|
||||
condition_1: '',
|
||||
condition_2: '',
|
||||
}
|
||||
const model = ref({ ...initialModel })
|
||||
function handleResetSearch() {
|
||||
model.value = { ...initialModel }
|
||||
}
|
||||
|
||||
const formRef = ref<FormInst | null>()
|
||||
const modalRef = ref()
|
||||
|
||||
async function delteteUser(id: number) {
|
||||
try {
|
||||
await deleteUser(id)
|
||||
window.$message.success('用户删除成功')
|
||||
getUserPageList() // 重新加载列表
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
|
||||
// 用户管理columns配置
|
||||
const columns = createUserColumns({
|
||||
onEdit: row => modalRef.value?.openModal('edit', row),
|
||||
onDelete: delteteUser,
|
||||
onStatusChange: handleUpdateDisabled,
|
||||
})
|
||||
|
||||
const count = ref(0)
|
||||
const listData = ref<Entity.User[]>([])
|
||||
async function handleUpdateDisabled(value: 0 | 1, id: number) {
|
||||
try {
|
||||
// 使用updateUser接口更新用户状态
|
||||
await updateUser(id, { userStatus: value })
|
||||
const index = listData.value.findIndex(item => item.userId === id)
|
||||
if (index > -1) {
|
||||
listData.value[index].userStatus = value
|
||||
}
|
||||
window.$message.success('用户状态更新成功')
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
|
||||
async function getUserPageList() {
|
||||
startLoading()
|
||||
try {
|
||||
const res = await getUserList({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
username: model.value.condition_1,
|
||||
gender: model.value.condition_2 as any,
|
||||
})
|
||||
listData.value = res.data.list
|
||||
count.value = res.data.total
|
||||
}
|
||||
finally {
|
||||
endLoading()
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getUserPageList()
|
||||
})
|
||||
|
||||
function changePage(page: number, size: number) {
|
||||
window.$message.success(`分页器:${page},${size}`)
|
||||
}
|
||||
|
||||
const treeData = ref([
|
||||
{
|
||||
id: '1',
|
||||
label: '安徽总公司',
|
||||
children: [
|
||||
{
|
||||
id: '2',
|
||||
label: '合肥分公司',
|
||||
children: [
|
||||
{
|
||||
id: '4',
|
||||
label: '财务部门',
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
label: '采购部门',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
label: '芜湖分公司',
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-flex>
|
||||
<n-card class="w-70">
|
||||
<n-tree
|
||||
block-line
|
||||
:data="treeData"
|
||||
key-field="id"
|
||||
/>
|
||||
</n-card>
|
||||
|
||||
<NSpace vertical class="flex-1">
|
||||
<n-card>
|
||||
<n-form ref="formRef" :model="model" label-placement="left" inline :show-feedback="false">
|
||||
<n-flex>
|
||||
<n-form-item label="姓名" path="condition_1">
|
||||
<n-input v-model:value="model.condition_1" placeholder="请输入" />
|
||||
</n-form-item>
|
||||
<n-form-item label="性别" path="condition_2">
|
||||
<n-input v-model:value="model.condition_2" placeholder="请输入" />
|
||||
</n-form-item>
|
||||
<n-flex class="ml-auto">
|
||||
<NButton type="primary" @click="getUserPageList">
|
||||
<template #icon>
|
||||
<icon-park-outline-search />
|
||||
</template>
|
||||
搜索
|
||||
</NButton>
|
||||
<NButton strong secondary @click="handleResetSearch">
|
||||
<template #icon>
|
||||
<icon-park-outline-redo />
|
||||
</template>
|
||||
重置
|
||||
</NButton>
|
||||
</n-flex>
|
||||
</n-flex>
|
||||
</n-form>
|
||||
</n-card>
|
||||
|
||||
<n-card class="flex-1">
|
||||
<template #header>
|
||||
<NButton type="primary" @click="modalRef.openModal('add')">
|
||||
<template #icon>
|
||||
<icon-park-outline-add-one />
|
||||
</template>
|
||||
新建用户
|
||||
</NButton>
|
||||
</template>
|
||||
<NSpace vertical>
|
||||
<n-data-table :columns="columns" :data="listData" :loading="loading" />
|
||||
<Pagination :count="count" @change="changePage" />
|
||||
</NSpace>
|
||||
|
||||
<TableModal ref="modalRef" modal-name="用户" @success="getUserPageList" />
|
||||
</n-card>
|
||||
</NSpace>
|
||||
</n-flex>
|
||||
</template>
|
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormRules } from 'naive-ui'
|
||||
import { useBoolean } from '@/hooks'
|
||||
import { createDictData, createDictType, updateDictData, updateDictType } from '@/service'
|
||||
import { createDictData, createDictType, updateDictData, updateDictType } from '@/api'
|
||||
|
||||
interface Props {
|
||||
modalName?: string
|
@ -1,6 +1,6 @@
|
||||
<script setup lang="tsx">
|
||||
import { useBoolean } from '@/hooks'
|
||||
import { deleteDictData, deleteDictType, getDictDataByType, getDictTypeList } from '@/service'
|
||||
import { deleteDictData, deleteDictType, getDictDataByType, getDictTypeList } from '@/api'
|
||||
import { createDictDataColumns, createDictTypeColumns } from './columns'
|
||||
import DictModal from './components/DictModal.vue'
|
||||
|
@ -95,7 +95,7 @@ export function createMenuColumns(actions: MenuColumnActions): DataTableColumns<
|
||||
>
|
||||
编辑
|
||||
</NButton>
|
||||
<NPopconfirm onPositiveClick={() => onDelete(row.menuId)}>
|
||||
<NPopconfirm onPositiveClick={() => onDelete(row.id)}>
|
||||
{{
|
||||
default: () => '确认删除',
|
||||
trigger: () => <NButton text type="error">删除</NButton>,
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { useBoolean } from '@/hooks'
|
||||
import { createMenu, getMenuById, selectMenuTree, updateMenu } from '@/service'
|
||||
import { createMenu, getMenuById, selectMenuTree, updateMenu } from '@/api'
|
||||
import { createProModalForm } from 'pro-naive-ui'
|
||||
import DirectoryForm from './DirectoryForm.vue'
|
||||
import PageForm from './PageForm.vue'
|
||||
@ -72,14 +72,14 @@ async function openModal(type: ModalType = 'add', data?: Partial<Entity.Menu>) {
|
||||
const handlers = {
|
||||
async add() {
|
||||
// 如果新建传入了menuId,设置为父级菜单
|
||||
if (data?.menuId) {
|
||||
modalForm.values.value.parentId = data.menuId
|
||||
if (data?.id) {
|
||||
modalForm.values.value.parentId = data.id
|
||||
}
|
||||
},
|
||||
async edit() {
|
||||
if (!data?.menuId)
|
||||
if (!data?.id)
|
||||
return
|
||||
const response = await getMenuById(data.menuId)
|
||||
const response = await getMenuById(data.id)
|
||||
modalForm.values.value = response.data
|
||||
},
|
||||
}
|
||||
@ -99,7 +99,7 @@ async function submitModal(filedValues: Partial<Entity.Menu>) {
|
||||
},
|
||||
async edit() {
|
||||
try {
|
||||
await updateMenu(modalForm.values.value.menuId!, filedValues)
|
||||
await updateMenu(modalForm.values.value.id!, filedValues)
|
||||
window.$message.success('菜单更新成功')
|
||||
}
|
||||
catch (error) {
|
||||
@ -157,10 +157,7 @@ defineExpose({
|
||||
title="标题"
|
||||
path="title"
|
||||
/>
|
||||
<component
|
||||
:is="currentFormComponent"
|
||||
:tree-data="treeData"
|
||||
/>
|
||||
<component :is="currentFormComponent" />
|
||||
<pro-textarea
|
||||
title="备注"
|
||||
path="remark"
|
||||
|
@ -1,12 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { useBoolean } from '@/hooks'
|
||||
import { deleteMenu, getMenuList } from '@/service'
|
||||
import { deleteMenu, getMenuList } from '@/api'
|
||||
import { createMenuColumns } from './columns'
|
||||
import MenuModal from './components/MenuModal.vue'
|
||||
import arrayToTree from 'array-to-tree'
|
||||
|
||||
const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
|
||||
|
||||
const menuModalRef = ref()
|
||||
|
||||
// 菜单管理columns配置
|
||||
const columns = createMenuColumns({
|
||||
onEdit: row => menuModalRef.value.openModal('edit', row),
|
||||
onDelete: deleteData,
|
||||
onAdd: row => menuModalRef.value.openModal('add', row),
|
||||
})
|
||||
|
||||
async function deleteData(id: number) {
|
||||
try {
|
||||
await deleteMenu(id)
|
||||
@ -18,17 +27,6 @@ async function deleteData(id: number) {
|
||||
}
|
||||
}
|
||||
|
||||
const menuModalRef = ref()
|
||||
|
||||
// 菜单管理columns配置
|
||||
const columns = createMenuColumns({
|
||||
onEdit: row => menuModalRef.value.openModal('edit', row),
|
||||
onDelete: deleteData,
|
||||
onAdd: row => menuModalRef.value.openModal('add', row),
|
||||
})
|
||||
|
||||
const tableData = ref<Entity.Menu[]>([])
|
||||
|
||||
// 递归排序菜单树结构
|
||||
function sortMenuTree(menus: Entity.Menu[]): Entity.Menu[] {
|
||||
// 对当前级别的菜单按sort值排序(升序)
|
||||
@ -45,13 +43,13 @@ function sortMenuTree(menus: Entity.Menu[]): Entity.Menu[] {
|
||||
}))
|
||||
}
|
||||
|
||||
const tableData = ref<Entity.Menu[]>([])
|
||||
async function getAllRoutes() {
|
||||
startLoading()
|
||||
try {
|
||||
const { data } = await getMenuList()
|
||||
const treeData = arrayToTree(data, {
|
||||
parentProperty: 'parentId',
|
||||
customID: 'menuId',
|
||||
})
|
||||
|
||||
// 对树形结构按sort值排序
|
||||
|
@ -1,6 +1,36 @@
|
||||
import type { DataTableColumns } from 'naive-ui'
|
||||
import { NButton, NPopconfirm, NSpace, NSwitch, NTag } from 'naive-ui'
|
||||
import CopyText from '@/components/custom/CopyText.vue'
|
||||
import type { ProSearchFormColumns } from 'pro-naive-ui'
|
||||
import { renderProCopyableText, renderProDateText } from 'pro-naive-ui'
|
||||
|
||||
export const searchColumns: ProSearchFormColumns<Entity.User> = [
|
||||
{
|
||||
title: '用户名',
|
||||
path: 'username',
|
||||
},
|
||||
{
|
||||
title: '手机号',
|
||||
path: 'phone',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
path: 'userStatus',
|
||||
field: 'select',
|
||||
fieldProps: {
|
||||
options: [
|
||||
{
|
||||
label: '启用',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '禁用',
|
||||
value: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
// 用户管理columns配置函数
|
||||
interface UserColumnActions {
|
||||
@ -11,12 +41,6 @@ interface UserColumnActions {
|
||||
|
||||
export function createUserColumns(actions: UserColumnActions): DataTableColumns<Entity.User> {
|
||||
return [
|
||||
{
|
||||
title: 'ID',
|
||||
align: 'center',
|
||||
key: 'userId',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '用户名',
|
||||
align: 'center',
|
||||
@ -53,9 +77,7 @@ export function createUserColumns(actions: UserColumnActions): DataTableColumns<
|
||||
title: '手机号',
|
||||
align: 'center',
|
||||
key: 'phone',
|
||||
render: (row) => {
|
||||
return row.phone ? <CopyText value={row.phone} /> : '-'
|
||||
},
|
||||
render: row => renderProCopyableText(row.phone),
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
@ -65,8 +87,8 @@ export function createUserColumns(actions: UserColumnActions): DataTableColumns<
|
||||
return (
|
||||
<NSwitch
|
||||
value={row.userStatus}
|
||||
checked-value={1}
|
||||
unchecked-value={0}
|
||||
checked-value={0}
|
||||
unchecked-value={1}
|
||||
onUpdateValue={(value: 0 | 1) =>
|
||||
actions.onStatusChange(value, row.userId)}
|
||||
>
|
||||
@ -79,9 +101,9 @@ export function createUserColumns(actions: UserColumnActions): DataTableColumns<
|
||||
title: '创建时间',
|
||||
align: 'center',
|
||||
key: 'createTime',
|
||||
render: (row) => {
|
||||
return row.createTime ? new Date(row.createTime).toLocaleDateString() : '-'
|
||||
},
|
||||
render: row => renderProDateText(row.createTime, {
|
||||
pattern: 'datetime',
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
@ -91,7 +113,7 @@ export function createUserColumns(actions: UserColumnActions): DataTableColumns<
|
||||
return (
|
||||
<NSpace justify="center">
|
||||
<NButton
|
||||
size="small"
|
||||
text
|
||||
onClick={() => actions.onEdit(row)}
|
||||
>
|
||||
编辑
|
||||
@ -99,7 +121,7 @@ export function createUserColumns(actions: UserColumnActions): DataTableColumns<
|
||||
<NPopconfirm onPositiveClick={() => actions.onDelete(row.userId)}>
|
||||
{{
|
||||
default: () => '确认删除',
|
||||
trigger: () => <NButton size="small" type="error">删除</NButton>,
|
||||
trigger: () => <NButton text type="error">删除</NButton>,
|
||||
}}
|
||||
</NPopconfirm>
|
||||
</NSpace>
|
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { useBoolean } from '@/hooks'
|
||||
import { createUser, fetchRoleList, updateUser } from '@/service'
|
||||
import { createUser, fetchRoleList, updateUser } from '@/api'
|
||||
|
||||
interface Props {
|
||||
modalName?: string
|
126
src/views/setting/user/index.vue
Normal file
126
src/views/setting/user/index.vue
Normal file
@ -0,0 +1,126 @@
|
||||
<script setup lang="tsx">
|
||||
import { createProSearchForm, useNDataTable } from 'pro-naive-ui'
|
||||
import { deleteUser, getUserList } from '@/api'
|
||||
import { createUserColumns, searchColumns } from './columns'
|
||||
import TableModal from './components/TableModal.vue'
|
||||
|
||||
const searchForm = createProSearchForm({
|
||||
initialValues: {
|
||||
},
|
||||
})
|
||||
|
||||
const {
|
||||
table: {
|
||||
tableProps,
|
||||
},
|
||||
search: {
|
||||
proSearchFormProps,
|
||||
},
|
||||
refresh,
|
||||
} = useNDataTable(getUserPage, {
|
||||
form: searchForm,
|
||||
})
|
||||
|
||||
const modalRef = ref()
|
||||
|
||||
async function delteteUser(id: number) {
|
||||
try {
|
||||
await deleteUser(id)
|
||||
window.$message.success('用户删除成功')
|
||||
refresh() // 重新加载列表
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
|
||||
const tablecolumns = createUserColumns({
|
||||
onEdit: row => modalRef.value?.openModal('edit', row),
|
||||
onDelete: delteteUser,
|
||||
onStatusChange: () => {},
|
||||
})
|
||||
|
||||
async function getUserPage({ curent, pageSize }, formData) {
|
||||
try {
|
||||
const { data } = await getUserList({
|
||||
...formData,
|
||||
pageNum: curent,
|
||||
pageSize,
|
||||
})
|
||||
return {
|
||||
list: data.list,
|
||||
total: data.total,
|
||||
}
|
||||
}
|
||||
catch {
|
||||
return {
|
||||
list: [],
|
||||
total: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const treeData = ref([
|
||||
{
|
||||
id: '1',
|
||||
label: '安徽总公司',
|
||||
children: [
|
||||
{
|
||||
id: '2',
|
||||
label: '合肥分公司',
|
||||
children: [
|
||||
{
|
||||
id: '4',
|
||||
label: '财务部门',
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
label: '采购部门',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
label: '芜湖分公司',
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-flex>
|
||||
<n-card class="w-70">
|
||||
<n-tree
|
||||
block-line
|
||||
:data="treeData"
|
||||
key-field="id"
|
||||
/>
|
||||
</n-card>
|
||||
|
||||
<n-space vertical class="flex-1">
|
||||
<n-card>
|
||||
<pro-search-form
|
||||
:form="searchForm"
|
||||
:columns="searchColumns"
|
||||
v-bind="proSearchFormProps"
|
||||
:collapse-button-props="false"
|
||||
/>
|
||||
</n-card>
|
||||
|
||||
<pro-data-table
|
||||
:columns="tablecolumns"
|
||||
v-bind="tableProps"
|
||||
>
|
||||
<template #title>
|
||||
<n-button type="primary" @click="modalRef.openModal('add')">
|
||||
<template #icon>
|
||||
<icon-park-outline-plus />
|
||||
</template>
|
||||
新建用户
|
||||
</n-button>
|
||||
</template>
|
||||
</pro-data-table>
|
||||
</n-space>
|
||||
<TableModal ref="modalRef" modal-name="用户" @success="refresh" />
|
||||
</n-flex>
|
||||
</template>
|
Loading…
x
Reference in New Issue
Block a user