feat: 🎸 权限管理开发中
parent
8edb2a3493
commit
6d7ea6694d
@ -1,8 +0,0 @@
|
||||
module.exports = {
|
||||
'*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
|
||||
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
|
||||
'package.json': ['prettier --write'],
|
||||
'*.vue': ['prettier --write', 'stylelint --fix'],
|
||||
'*.{scss,less,styl,css,html}': ['stylelint --fix', 'prettier --write'],
|
||||
'*.md': ['prettier --write']
|
||||
}
|
||||
@ -0,0 +1,420 @@
|
||||
export const checkedNodes = [{
|
||||
'path': '/components-demo',
|
||||
'title': '功能组件',
|
||||
'name': 'ComponentsDemo',
|
||||
'children': [{
|
||||
'path': '/components-demo/echarts',
|
||||
'title': '图表',
|
||||
'name': 'EchartsDemo'
|
||||
}, {
|
||||
'path': '/components-demo/preview',
|
||||
'title': '图片预览',
|
||||
'name': 'PreviewDemo'
|
||||
}, {
|
||||
'path': '/components-demo/button',
|
||||
'title': '按钮',
|
||||
'name': 'ButtonDemo'
|
||||
}, {
|
||||
'path': '/components-demo/message',
|
||||
'title': '消息提示',
|
||||
'name': 'MessageDemo'
|
||||
}, {
|
||||
'path': '/components-demo/count-to',
|
||||
'title': '数字动画',
|
||||
'name': 'CountToDemo'
|
||||
}, {
|
||||
'path': '/components-demo/search',
|
||||
'title': '查询',
|
||||
'name': 'SearchDemo'
|
||||
}, {
|
||||
'path': '/components-demo/editor',
|
||||
'title': '富文本编辑器',
|
||||
'name': 'EditorDemo'
|
||||
}, {
|
||||
'path': '/components-demo/markdown',
|
||||
'title': 'markdown编辑器',
|
||||
'name': 'MarkdownDemo'
|
||||
}, {
|
||||
'path': '/components-demo/dialog',
|
||||
'title': '弹窗',
|
||||
'name': 'DialogDemo'
|
||||
}, {
|
||||
'path': '/components-demo/more',
|
||||
'title': '显示更多',
|
||||
'name': 'MoreDemo'
|
||||
}, {
|
||||
'path': '/components-demo/detail',
|
||||
'title': '详情组件',
|
||||
'name': 'DetailDemo'
|
||||
}]
|
||||
}, {
|
||||
'path': '/components-demo/echarts',
|
||||
'title': '图表',
|
||||
'name': 'EchartsDemo'
|
||||
}, {
|
||||
'path': '/components-demo/preview',
|
||||
'title': '图片预览',
|
||||
'name': 'PreviewDemo'
|
||||
}, {
|
||||
'path': '/components-demo/button',
|
||||
'title': '按钮',
|
||||
'name': 'ButtonDemo'
|
||||
}, {
|
||||
'path': '/components-demo/message',
|
||||
'title': '消息提示',
|
||||
'name': 'MessageDemo'
|
||||
}, {
|
||||
'path': '/components-demo/count-to',
|
||||
'title': '数字动画',
|
||||
'name': 'CountToDemo'
|
||||
}, {
|
||||
'path': '/components-demo/search',
|
||||
'title': '查询',
|
||||
'name': 'SearchDemo'
|
||||
}, {
|
||||
'path': '/components-demo/editor',
|
||||
'title': '富文本编辑器',
|
||||
'name': 'EditorDemo'
|
||||
}, {
|
||||
'path': '/components-demo/markdown',
|
||||
'title': 'markdown编辑器',
|
||||
'name': 'MarkdownDemo'
|
||||
}, {
|
||||
'path': '/components-demo/dialog',
|
||||
'title': '弹窗',
|
||||
'name': 'DialogDemo'
|
||||
}, {
|
||||
'path': '/components-demo/more',
|
||||
'title': '显示更多',
|
||||
'name': 'MoreDemo'
|
||||
}, {
|
||||
'path': '/components-demo/detail',
|
||||
'title': '详情组件',
|
||||
'name': 'DetailDemo'
|
||||
}, {
|
||||
'path': '/table-demo',
|
||||
'title': '表格',
|
||||
'name': 'TableDemo',
|
||||
'children': [{
|
||||
'path': '/table-demo/basic-table',
|
||||
'title': '基础表格',
|
||||
'name': 'BasicTable'
|
||||
}, {
|
||||
'path': '/table-demo/page-table',
|
||||
'title': '分页表格',
|
||||
'name': 'PageTable'
|
||||
}, {
|
||||
'path': '/table-demo/stripe-table',
|
||||
'title': '带斑马纹表格',
|
||||
'name': 'StripeTable'
|
||||
}, {
|
||||
'path': '/table-demo/border-table',
|
||||
'title': '带边框表格',
|
||||
'name': 'BorderTable'
|
||||
}, {
|
||||
'path': '/table-demo/state-table',
|
||||
'title': '带状态表格',
|
||||
'name': 'StateTable'
|
||||
}, {
|
||||
'path': '/table-demo/fixed-header',
|
||||
'title': '固定表头',
|
||||
'name': 'FixedHeader'
|
||||
}, {
|
||||
'path': '/table-demo/fixed-column',
|
||||
'title': '固定列',
|
||||
'name': 'FixedColumn'
|
||||
}, {
|
||||
'path': '/table-demo/fixed-column-header',
|
||||
'title': '固定列和表头',
|
||||
'name': 'FixedColumnHeader'
|
||||
}, {
|
||||
'path': '/table-demo/fluid-height',
|
||||
'title': '流体高度',
|
||||
'name': 'FluidHeight'
|
||||
}, {
|
||||
'path': '/table-demo/multi-header',
|
||||
'title': '多级表头',
|
||||
'name': 'MultiHeader'
|
||||
}, {
|
||||
'path': '/table-demo/single-choice',
|
||||
'title': '单选',
|
||||
'name': 'SingleChoice'
|
||||
}, {
|
||||
'path': '/table-demo/multiple-choice',
|
||||
'title': '多选',
|
||||
'name': 'MultipleChoice'
|
||||
}, {
|
||||
'path': '/table-demo/sort-table',
|
||||
'title': '排序',
|
||||
'name': 'SortTable'
|
||||
}, {
|
||||
'path': '/table-demo/screen-table',
|
||||
'title': '筛选',
|
||||
'name': 'ScreenTable'
|
||||
}, {
|
||||
'path': '/table-demo/expand-row',
|
||||
'title': '展开行',
|
||||
'name': 'ExpandRow'
|
||||
}, {
|
||||
'path': '/table-demo/tree-and-load',
|
||||
'title': '树形数据与懒加载',
|
||||
'name': 'TreeAndLoad'
|
||||
}, {
|
||||
'path': '/table-demo/custom-header',
|
||||
'title': '自定义表头',
|
||||
'name': 'CustomHeader'
|
||||
}, {
|
||||
'path': '/table-demo/total-table',
|
||||
'title': '表尾合计行',
|
||||
'name': 'TotalTable'
|
||||
}, {
|
||||
'path': '/table-demo/merge-table',
|
||||
'title': '合并行或列',
|
||||
'name': 'MergeTable'
|
||||
}, {
|
||||
'path': '/table-demo/custom-index',
|
||||
'title': '自定义索引',
|
||||
'name': 'CustomIndex'
|
||||
}]
|
||||
}, {
|
||||
'path': '/table-demo/basic-table',
|
||||
'title': '基础表格',
|
||||
'name': 'BasicTable'
|
||||
}, {
|
||||
'path': '/table-demo/page-table',
|
||||
'title': '分页表格',
|
||||
'name': 'PageTable'
|
||||
}, {
|
||||
'path': '/table-demo/stripe-table',
|
||||
'title': '带斑马纹表格',
|
||||
'name': 'StripeTable'
|
||||
}, {
|
||||
'path': '/table-demo/border-table',
|
||||
'title': '带边框表格',
|
||||
'name': 'BorderTable'
|
||||
}, {
|
||||
'path': '/table-demo/state-table',
|
||||
'title': '带状态表格',
|
||||
'name': 'StateTable'
|
||||
}, {
|
||||
'path': '/table-demo/fixed-header',
|
||||
'title': '固定表头',
|
||||
'name': 'FixedHeader'
|
||||
}, {
|
||||
'path': '/table-demo/fixed-column',
|
||||
'title': '固定列',
|
||||
'name': 'FixedColumn'
|
||||
}, {
|
||||
'path': '/table-demo/fixed-column-header',
|
||||
'title': '固定列和表头',
|
||||
'name': 'FixedColumnHeader'
|
||||
}, {
|
||||
'path': '/table-demo/fluid-height',
|
||||
'title': '流体高度',
|
||||
'name': 'FluidHeight'
|
||||
}, {
|
||||
'path': '/table-demo/multi-header',
|
||||
'title': '多级表头',
|
||||
'name': 'MultiHeader'
|
||||
}, {
|
||||
'path': '/table-demo/single-choice',
|
||||
'title': '单选',
|
||||
'name': 'SingleChoice'
|
||||
}, {
|
||||
'path': '/table-demo/multiple-choice',
|
||||
'title': '多选',
|
||||
'name': 'MultipleChoice'
|
||||
}, {
|
||||
'path': '/table-demo/sort-table',
|
||||
'title': '排序',
|
||||
'name': 'SortTable'
|
||||
}, {
|
||||
'path': '/table-demo/screen-table',
|
||||
'title': '筛选',
|
||||
'name': 'ScreenTable'
|
||||
}, {
|
||||
'path': '/table-demo/expand-row',
|
||||
'title': '展开行',
|
||||
'name': 'ExpandRow'
|
||||
}, {
|
||||
'path': '/table-demo/tree-and-load',
|
||||
'title': '树形数据与懒加载',
|
||||
'name': 'TreeAndLoad'
|
||||
}, {
|
||||
'path': '/table-demo/custom-header',
|
||||
'title': '自定义表头',
|
||||
'name': 'CustomHeader'
|
||||
}, {
|
||||
'path': '/table-demo/total-table',
|
||||
'title': '表尾合计行',
|
||||
'name': 'TotalTable'
|
||||
}, {
|
||||
'path': '/table-demo/merge-table',
|
||||
'title': '合并行或列',
|
||||
'name': 'MergeTable'
|
||||
}, {
|
||||
'path': '/table-demo/custom-index',
|
||||
'title': '自定义索引',
|
||||
'name': 'CustomIndex'
|
||||
}, {
|
||||
'path': '/directives-demo',
|
||||
'title': '自定义指令',
|
||||
'name': 'DirectivesDemo',
|
||||
'children': [{
|
||||
'path': '/directives-demo/clipboard',
|
||||
'title': 'Clipboard',
|
||||
'name': 'ClipboardDemo'
|
||||
}]
|
||||
}, {
|
||||
'path': '/directives-demo/clipboard',
|
||||
'title': 'Clipboard',
|
||||
'name': 'ClipboardDemo'
|
||||
}, {
|
||||
'path': '/hooks-demo',
|
||||
'title': 'Hooks',
|
||||
'name': 'HooksDemo',
|
||||
'children': [{
|
||||
'path': '/hooks-demo/watermark',
|
||||
'title': 'UseWaterMark',
|
||||
'name': 'UseWatermarkDemo'
|
||||
}, {
|
||||
'path': '/hooks-demo/useScrollTo',
|
||||
'title': 'UseScrollTo',
|
||||
'name': 'UseScrollToDemo'
|
||||
}]
|
||||
}, {
|
||||
'path': '/hooks-demo/watermark',
|
||||
'title': 'UseWaterMark',
|
||||
'name': 'UseWatermarkDemo'
|
||||
}, {
|
||||
'path': '/hooks-demo/useScrollTo',
|
||||
'title': 'UseScrollTo',
|
||||
'name': 'UseScrollToDemo'
|
||||
}, {
|
||||
'path': '/icon/index',
|
||||
'title': '图标',
|
||||
'name': 'Icons'
|
||||
}, {
|
||||
'path': '/level',
|
||||
'title': '多级菜单缓存',
|
||||
'name': 'Level',
|
||||
'children': [{
|
||||
'path': '/level/menu1',
|
||||
'title': 'Menu1',
|
||||
'name': 'Menu1Demo',
|
||||
'children': [{
|
||||
'path': '/level/menu1/menu1-1',
|
||||
'title': 'Menu1-1',
|
||||
'name': 'Menu11Demo',
|
||||
'children': [{
|
||||
'path': '/level/menu1/menu1-1/menu1-1-1',
|
||||
'title': 'Menu1-1-1',
|
||||
'name': 'Menu111Demo'
|
||||
}]
|
||||
}, {
|
||||
'path': '/level/menu1/menu1-2',
|
||||
'title': 'Menu1-2',
|
||||
'name': 'Menu12Demo'
|
||||
}]
|
||||
}, {
|
||||
'path': '/level/menu2',
|
||||
'title': 'Menu2',
|
||||
'name': 'Menu2Demo'
|
||||
}]
|
||||
}, {
|
||||
'path': '/level/menu1',
|
||||
'title': 'Menu1',
|
||||
'name': 'Menu1Demo',
|
||||
'children': [{
|
||||
'path': '/level/menu1/menu1-1',
|
||||
'title': 'Menu1-1',
|
||||
'name': 'Menu11Demo',
|
||||
'children': [{
|
||||
'path': '/level/menu1/menu1-1/menu1-1-1',
|
||||
'title': 'Menu1-1-1',
|
||||
'name': 'Menu111Demo'
|
||||
}]
|
||||
}, {
|
||||
'path': '/level/menu1/menu1-2',
|
||||
'title': 'Menu1-2',
|
||||
'name': 'Menu12Demo'
|
||||
}]
|
||||
}, {
|
||||
'path': '/level/menu1/menu1-1',
|
||||
'title': 'Menu1-1',
|
||||
'name': 'Menu11Demo',
|
||||
'children': [{
|
||||
'path': '/level/menu1/menu1-1/menu1-1-1',
|
||||
'title': 'Menu1-1-1',
|
||||
'name': 'Menu111Demo'
|
||||
}]
|
||||
}, {
|
||||
'path': '/level/menu1/menu1-1/menu1-1-1',
|
||||
'title': 'Menu1-1-1',
|
||||
'name': 'Menu111Demo'
|
||||
}, {
|
||||
'path': '/level/menu1/menu1-2',
|
||||
'title': 'Menu1-2',
|
||||
'name': 'Menu12Demo'
|
||||
}, {
|
||||
'path': '/level/menu2',
|
||||
'title': 'Menu2',
|
||||
'name': 'Menu2Demo'
|
||||
}, {
|
||||
'path': '/example-demo',
|
||||
'title': '综合实例',
|
||||
'name': 'ExampleDemo',
|
||||
'children': [{
|
||||
'path': '/example-demo/example-dialog',
|
||||
'title': '列表综合实例-弹窗',
|
||||
'name': 'ExampleDialog'
|
||||
}, {
|
||||
'path': '/example-demo/example-page',
|
||||
'title': '列表综合实例-页面',
|
||||
'name': 'ExamplePage'
|
||||
}]
|
||||
}, {
|
||||
'path': '/example-demo/example-dialog',
|
||||
'title': '列表综合实例-弹窗',
|
||||
'name': 'ExampleDialog'
|
||||
}, {
|
||||
'path': '/example-demo/example-page',
|
||||
'title': '列表综合实例-页面',
|
||||
'name': 'ExamplePage'
|
||||
}, {
|
||||
'path': '/role-demo',
|
||||
'title': '权限管理',
|
||||
'name': 'RoleDemo',
|
||||
'children': [{
|
||||
'path': '/role-demo/user',
|
||||
'title': '用户管理',
|
||||
'name': 'User'
|
||||
}, {
|
||||
'path': '/role-demo/role',
|
||||
'title': '角色管理',
|
||||
'name': 'Role'
|
||||
}]
|
||||
}, {
|
||||
'path': '/role-demo/user',
|
||||
'title': '用户管理',
|
||||
'name': 'User'
|
||||
}, {
|
||||
'path': '/role-demo/role',
|
||||
'title': '角色管理',
|
||||
'name': 'Role'
|
||||
}]
|
||||
|
||||
export const checkedkeys = ['/components-demo', '/components-demo/echarts', '/components-demo/preview',
|
||||
'/components-demo/button', '/components-demo/message', '/components-demo/count-to', '/components-demo/search',
|
||||
'/components-demo/editor', '/components-demo/markdown', '/components-demo/dialog', '/components-demo/more',
|
||||
'/components-demo/detail', '/table-demo', '/table-demo/basic-table', '/table-demo/page-table',
|
||||
'/table-demo/stripe-table', '/table-demo/border-table', '/table-demo/state-table', '/table-demo/fixed-header',
|
||||
'/table-demo/fixed-column', '/table-demo/fixed-column-header', '/table-demo/fluid-height',
|
||||
'/table-demo/multi-header', '/table-demo/single-choice', '/table-demo/multiple-choice', '/table-demo/sort-table',
|
||||
'/table-demo/screen-table', '/table-demo/expand-row', '/table-demo/tree-and-load', '/table-demo/custom-header',
|
||||
'/table-demo/total-table', '/table-demo/merge-table', '/table-demo/custom-index', '/directives-demo',
|
||||
'/directives-demo/clipboard', '/hooks-demo', '/hooks-demo/watermark', '/hooks-demo/useScrollTo', '/icon/index',
|
||||
'/level', '/level/menu1', '/level/menu1/menu1-1', '/level/menu1/menu1-1/menu1-1-1', '/level/menu1/menu1-2',
|
||||
'/level/menu2', '/example-demo', '/example-demo/example-dialog', '/example-demo/example-page', '/role-demo',
|
||||
'/role-demo/user', '/role-demo/role'
|
||||
]
|
||||
@ -0,0 +1,97 @@
|
||||
import wsCache from '@/cache'
|
||||
import { Role } from './types'
|
||||
import { checkedNodes, checkedkeys } from './admin-role'
|
||||
import { checkedRoleNodes } from './test-role'
|
||||
|
||||
let List: Role[] = wsCache.get('roleList') || [
|
||||
{
|
||||
roleName: 'admin',
|
||||
id: '1',
|
||||
checkedNodes: checkedNodes,
|
||||
checkedkeys: checkedkeys
|
||||
},
|
||||
{
|
||||
roleName: 'test',
|
||||
id: '2',
|
||||
checkedNodes: checkedRoleNodes,
|
||||
checkedkeys: []
|
||||
}
|
||||
]
|
||||
|
||||
export default [
|
||||
// 列表接口
|
||||
{
|
||||
url: 'http://mockjs.test.cn/role/list',
|
||||
type: 'get',
|
||||
response: (config: any) => {
|
||||
const {
|
||||
roleName,
|
||||
pageIndex,
|
||||
pageSize
|
||||
} = config.query
|
||||
|
||||
const mockList = List.filter(item => {
|
||||
if (roleName && item.roleName.indexOf(roleName) < 0) return false
|
||||
return true
|
||||
})
|
||||
const pageList = mockList.filter((item, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1))
|
||||
|
||||
return {
|
||||
code: '0000',
|
||||
data: {
|
||||
total: mockList.length,
|
||||
list: pageList
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 详情接口
|
||||
{
|
||||
url: 'http://mockjs.test.cn/role/detail',
|
||||
type: 'get',
|
||||
response: (config: any) => {
|
||||
const {
|
||||
id
|
||||
} = config.query
|
||||
for (const role of List) {
|
||||
if (role.id === id) {
|
||||
return {
|
||||
code: '0000',
|
||||
data: role
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 保存接口
|
||||
{
|
||||
url: 'http://mockjs.test.cn/role/save',
|
||||
type: 'post',
|
||||
response: (config: any) => {
|
||||
const data = config.body
|
||||
if (!data.id) {
|
||||
List = [data].concat(List)
|
||||
return {
|
||||
code: '0000',
|
||||
data: 'success'
|
||||
}
|
||||
} else {
|
||||
List.map(item => {
|
||||
if (item.id === data.id) {
|
||||
for (const key in item) {
|
||||
item[key] = data[key]
|
||||
}
|
||||
}
|
||||
})
|
||||
// 存在缓存中,避免刷新没有掉
|
||||
wsCache.set('roleList', List)
|
||||
return {
|
||||
code: '0000',
|
||||
data: 'success'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,489 @@
|
||||
export const checkedRoleNodes = [{
|
||||
path: '/components-demo',
|
||||
component: '#',
|
||||
redirect: '/components-demo/echarts',
|
||||
name: 'ComponentsDemo',
|
||||
meta: {
|
||||
title: '功能组件',
|
||||
icon: 'component',
|
||||
alwaysShow: true
|
||||
},
|
||||
children: [{
|
||||
path: 'echarts',
|
||||
component: 'pages/index/views/components-demo/echarts/index.vue',
|
||||
name: 'EchartsDemo',
|
||||
meta: {
|
||||
title: '图表'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'preview',
|
||||
component: 'pages/index/views/components-demo/preview/index.vue',
|
||||
name: 'PreviewDemo',
|
||||
meta: {
|
||||
title: '图片预览'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'button',
|
||||
component: 'pages/index/views/components-demo/button/index.vue',
|
||||
name: 'ButtonDemo',
|
||||
meta: {
|
||||
title: '按钮'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'message',
|
||||
component: 'pages/index/views/components-demo/message/index.vue',
|
||||
name: 'MessageDemo',
|
||||
meta: {
|
||||
title: '消息提示'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'count-to',
|
||||
component: 'pages/index/views/components-demo/count-to/index.vue',
|
||||
name: 'CountToDemo',
|
||||
meta: {
|
||||
title: '数字动画'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'search',
|
||||
component: 'pages/index/views/components-demo/search/index.vue',
|
||||
name: 'SearchDemo',
|
||||
meta: {
|
||||
title: '查询'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'editor',
|
||||
component: 'pages/index/views/components-demo/editor/index.vue',
|
||||
name: 'EditorDemo',
|
||||
meta: {
|
||||
title: '富文本编辑器'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'markdown',
|
||||
component: 'pages/index/views/components-demo/markdown/index.vue',
|
||||
name: 'MarkdownDemo',
|
||||
meta: {
|
||||
title: 'markdown编辑器'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'dialog',
|
||||
component: 'pages/index/views/components-demo/dialog/index.vue',
|
||||
name: 'DialogDemo',
|
||||
meta: {
|
||||
title: '弹窗'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'more',
|
||||
component: 'pages/index/views/components-demo/more/index.vue',
|
||||
name: 'MoreDemo',
|
||||
meta: {
|
||||
title: '显示更多'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'detail',
|
||||
component: 'pages/index/views/components-demo/detail/index.vue',
|
||||
name: 'DetailDemo',
|
||||
meta: {
|
||||
title: '详情组件'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/table-demo',
|
||||
component: '#',
|
||||
redirect: '/table-demo/basic-usage',
|
||||
name: 'TableDemo',
|
||||
meta: {
|
||||
title: '表格',
|
||||
icon: 'table',
|
||||
alwaysShow: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'basic-table',
|
||||
component: 'pages/index/views/table-demo/basic-table/index.vue',
|
||||
name: 'BasicTable',
|
||||
meta: {
|
||||
title: '基础表格'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'page-table',
|
||||
component: 'pages/index/views/table-demo/page-table/index.vue',
|
||||
name: 'PageTable',
|
||||
meta: {
|
||||
title: '分页表格'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'stripe-table',
|
||||
component: 'pages/index/views/table-demo/stripe-table/index.vue',
|
||||
name: 'StripeTable',
|
||||
meta: {
|
||||
title: '带斑马纹表格'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'border-table',
|
||||
component: 'pages/index/views/table-demo/border-table/index.vue',
|
||||
name: 'BorderTable',
|
||||
meta: {
|
||||
title: '带边框表格'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'state-table',
|
||||
component: 'pages/index/views/table-demo/state-table/index.vue',
|
||||
name: 'StateTable',
|
||||
meta: {
|
||||
title: '带状态表格'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'fixed-header',
|
||||
component: 'pages/index/views/table-demo/fixed-header/index.vue',
|
||||
name: 'FixedHeader',
|
||||
meta: {
|
||||
title: '固定表头'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'fixed-column',
|
||||
component: 'pages/index/views/table-demo/fixed-column/index.vue',
|
||||
name: 'FixedColumn',
|
||||
meta: {
|
||||
title: '固定列'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'fixed-column-header',
|
||||
component: 'pages/index/views/table-demo/fixed-column-header/index.vue',
|
||||
name: 'FixedColumnHeader',
|
||||
meta: {
|
||||
title: '固定列和表头'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'fluid-height',
|
||||
component: 'pages/index/views/table-demo/fluid-height/index.vue',
|
||||
name: 'FluidHeight',
|
||||
meta: {
|
||||
title: '流体高度'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'multi-header',
|
||||
component: 'pages/index/views/table-demo/multi-header/index.vue',
|
||||
name: 'MultiHeader',
|
||||
meta: {
|
||||
title: '多级表头'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'single-choice',
|
||||
component: 'pages/index/views/table-demo/single-choice/index.vue',
|
||||
name: 'SingleChoice',
|
||||
meta: {
|
||||
title: '单选'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'multiple-choice',
|
||||
component: 'pages/index/views/table-demo/multiple-choice/index.vue',
|
||||
name: 'MultipleChoice',
|
||||
meta: {
|
||||
title: '多选'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'sort-table',
|
||||
component: 'pages/index/views/table-demo/sort-table/index.vue',
|
||||
name: 'SortTable',
|
||||
meta: {
|
||||
title: '排序'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'screen-table',
|
||||
component: 'pages/index/views/table-demo/screen-table/index.vue',
|
||||
name: 'ScreenTable',
|
||||
meta: {
|
||||
title: '筛选'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'expand-row',
|
||||
component: 'pages/index/views/table-demo/expand-row/index.vue',
|
||||
name: 'ExpandRow',
|
||||
meta: {
|
||||
title: '展开行'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'tree-and-load',
|
||||
component: 'pages/index/views/table-demo/tree-and-load/index.vue',
|
||||
name: 'TreeAndLoad',
|
||||
meta: {
|
||||
title: '树形数据与懒加载'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'custom-header',
|
||||
component: 'pages/index/views/table-demo/custom-header/index.vue',
|
||||
name: 'CustomHeader',
|
||||
meta: {
|
||||
title: '自定义表头'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'total-table',
|
||||
component: 'pages/index/views/table-demo/total-table/index.vue',
|
||||
name: 'TotalTable',
|
||||
meta: {
|
||||
title: '表尾合计行'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'merge-table',
|
||||
component: 'pages/index/views/table-demo/merge-table/index.vue',
|
||||
name: 'MergeTable',
|
||||
meta: {
|
||||
title: '合并行或列'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'custom-index',
|
||||
component: 'pages/index/views/table-demo/custom-index/index.vue',
|
||||
name: 'CustomIndex',
|
||||
meta: {
|
||||
title: '自定义索引'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/directives-demo',
|
||||
component: '#',
|
||||
redirect: '/directives-demo/clipboard',
|
||||
name: 'DirectivesDemo',
|
||||
meta: {
|
||||
title: '自定义指令',
|
||||
icon: 'clipboard',
|
||||
alwaysShow: true
|
||||
},
|
||||
children: [{
|
||||
path: 'clipboard',
|
||||
component: 'pages/index/views/directives-demo/clipboard/index.vue',
|
||||
name: 'ClipboardDemo',
|
||||
meta: {
|
||||
title: 'Clipboard'
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/hooks-demo',
|
||||
component: '#',
|
||||
redirect: '/hooks-demo/watermark',
|
||||
name: 'HooksDemo',
|
||||
meta: {
|
||||
title: 'Hooks',
|
||||
icon: 'international',
|
||||
alwaysShow: true
|
||||
},
|
||||
children: [{
|
||||
path: 'watermark',
|
||||
component: 'pages/index/views/hooks-demo/useWatermark/index.vue',
|
||||
name: 'UseWatermarkDemo',
|
||||
meta: {
|
||||
title: 'UseWaterMark'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'useScrollTo',
|
||||
component: 'pages/index/views/hooks-demo/useScrollTo/index.vue',
|
||||
name: 'UseScrollToDemo',
|
||||
meta: {
|
||||
title: 'UseScrollTo'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/icon',
|
||||
component: '#',
|
||||
name: 'IconsDemo',
|
||||
meta: {
|
||||
title: '图标',
|
||||
icon: 'icon'
|
||||
},
|
||||
children: [{
|
||||
path: 'index',
|
||||
component: 'pages/index/views/icons/index.vue',
|
||||
name: 'Icons',
|
||||
meta: {
|
||||
title: '图标',
|
||||
icon: 'icon'
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/level',
|
||||
component: '#',
|
||||
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||
name: 'Level',
|
||||
meta: {
|
||||
title: '多级菜单缓存',
|
||||
icon: 'nested'
|
||||
},
|
||||
children: [{
|
||||
path: 'menu1',
|
||||
name: 'Menu1Demo',
|
||||
component: '##Menu1Demo',
|
||||
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||
meta: {
|
||||
title: 'Menu1'
|
||||
},
|
||||
children: [{
|
||||
path: 'menu1-1',
|
||||
name: 'Menu11Demo',
|
||||
component: '##Menu11Demo',
|
||||
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||
meta: {
|
||||
title: 'Menu1-1',
|
||||
alwaysShow: true
|
||||
},
|
||||
children: [{
|
||||
path: 'menu1-1-1',
|
||||
name: 'Menu111Demo',
|
||||
component: 'pages/index/views/level/Menu111.vue',
|
||||
meta: {
|
||||
title: 'Menu1-1-1'
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: 'menu1-2',
|
||||
name: 'Menu12Demo',
|
||||
component: 'pages/index/views/level/Menu12.vue',
|
||||
meta: {
|
||||
title: 'Menu1-2'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'menu2',
|
||||
name: 'Menu2Demo',
|
||||
component: 'pages/index/views/level/Menu2.vue',
|
||||
meta: {
|
||||
title: 'Menu2'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/example-demo',
|
||||
component: '#',
|
||||
name: 'ExampleDemo',
|
||||
redirect: '/example-demo/example-dialog',
|
||||
meta: {
|
||||
alwaysShow: true,
|
||||
icon: 'example',
|
||||
title: '综合实例'
|
||||
},
|
||||
children: [{
|
||||
path: 'example-dialog',
|
||||
component: 'pages/index/views/example-demo/example-dialog/index.vue',
|
||||
name: 'ExampleDialog',
|
||||
meta: {
|
||||
title: '列表综合实例-弹窗'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'example-page',
|
||||
component: 'pages/index/views/example-demo/example-page/index.vue',
|
||||
name: 'ExamplePage',
|
||||
meta: {
|
||||
title: '列表综合实例-页面'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'example-add',
|
||||
component: 'pages/index/views/example-demo/example-page/example-add.vue',
|
||||
name: 'ExampleAdd',
|
||||
meta: {
|
||||
title: '列表综合实例-新增',
|
||||
noTagsView: true,
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
showMainRoute: true,
|
||||
activeMenu: '/example-demo/example-page'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'example-edit',
|
||||
component: 'pages/index/views/example-demo/example-page/example-edit.vue',
|
||||
name: 'ExampleEdit',
|
||||
meta: {
|
||||
title: '列表综合实例-编辑',
|
||||
noTagsView: true,
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
showMainRoute: true,
|
||||
activeMenu: '/example-demo/example-page'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'example-detail',
|
||||
component: 'pages/index/views/example-demo/example-page/example-detail.vue',
|
||||
name: 'ExampleDetail',
|
||||
meta: {
|
||||
title: '列表综合实例-详情',
|
||||
noTagsView: true,
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
showMainRoute: true,
|
||||
activeMenu: '/example-demo/example-page'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/role-demo',
|
||||
component: '#',
|
||||
redirect: '/role-demo/user',
|
||||
name: 'RoleDemo',
|
||||
meta: {
|
||||
title: '权限管理',
|
||||
icon: 'user',
|
||||
alwaysShow: true
|
||||
},
|
||||
children: [{
|
||||
path: 'user',
|
||||
component: 'pages/index/views/role-demo/user/index.vue',
|
||||
name: 'User',
|
||||
meta: {
|
||||
title: '用户管理'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
component: 'pages/index/views/role-demo/role/index.vue',
|
||||
name: 'Role',
|
||||
meta: {
|
||||
title: '角色管理'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,6 @@
|
||||
export interface Role {
|
||||
roleName: String
|
||||
id: String
|
||||
checkedNodes: any[]
|
||||
checkedkeys: any[]
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
import { User } from './types'
|
||||
|
||||
const List: User[] = [
|
||||
{
|
||||
userName: 'admin',
|
||||
password: 'admin',
|
||||
role: 'admin',
|
||||
roleId: '1'
|
||||
},
|
||||
{
|
||||
userName: 'test',
|
||||
password: 'test',
|
||||
role: 'test',
|
||||
roleId: '2'
|
||||
}
|
||||
]
|
||||
|
||||
export default [
|
||||
// 列表接口
|
||||
{
|
||||
url: 'http://mockjs.test.cn/user/list',
|
||||
type: 'get',
|
||||
response: (config: any) => {
|
||||
const {
|
||||
userName,
|
||||
pageIndex,
|
||||
pageSize
|
||||
} = config.query
|
||||
|
||||
const mockList = List.filter(item => {
|
||||
if (userName && item.userName.indexOf(userName) < 0) return false
|
||||
return true
|
||||
})
|
||||
const pageList = mockList.filter((item, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1))
|
||||
|
||||
return {
|
||||
code: '0000',
|
||||
data: {
|
||||
total: mockList.length,
|
||||
list: pageList
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 登录接口
|
||||
{
|
||||
url: 'http://mockjs.test.cn/user/login',
|
||||
type: 'post',
|
||||
response: (config: any) => {
|
||||
const data = config.body
|
||||
let hasUser = false
|
||||
for (const user of List) {
|
||||
if (user.userName === data.userName && user.password === data.passWord) {
|
||||
hasUser = true
|
||||
return {
|
||||
code: '0000',
|
||||
data: user
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasUser) {
|
||||
return {
|
||||
code: '500',
|
||||
message: '账号或密码错误'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,6 @@
|
||||
export interface User {
|
||||
userName: String
|
||||
password: String
|
||||
role: String
|
||||
roleId: String
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
# replace default config
|
||||
|
||||
# multipass: true
|
||||
# full: true
|
||||
|
||||
plugins:
|
||||
|
||||
# - name
|
||||
#
|
||||
# or:
|
||||
# - name: false
|
||||
# - name: true
|
||||
#
|
||||
# or:
|
||||
# - name:
|
||||
# param1: 1
|
||||
# param2: 2
|
||||
|
||||
- removeAttrs:
|
||||
attrs:
|
||||
- 'fill'
|
||||
- 'fill-rule'
|
||||
@ -1,14 +1,14 @@
|
||||
import { EmptyObj } from '@/types/glob'
|
||||
// import { EmptyObj } from '@/types/glob'
|
||||
|
||||
const modulesFiles: any = require.context('./modules', true, /\.ts$/)
|
||||
// const modulesFiles: any = require.context('./modules', true, /\.ts$/)
|
||||
|
||||
const modules: EmptyObj = modulesFiles.keys().reduce((modules: EmptyObj, modulePath: string): Object => {
|
||||
const moduleName: string = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
|
||||
const value: EmptyObj = modulesFiles(modulePath)
|
||||
modules[moduleName] = value.default
|
||||
return modules
|
||||
}, {})
|
||||
// const modules: EmptyObj = modulesFiles.keys().reduce((modules: EmptyObj, modulePath: string): Object => {
|
||||
// const moduleName: string = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
|
||||
// const value: EmptyObj = modulesFiles(modulePath)
|
||||
// modules[moduleName] = value.default
|
||||
// return modules
|
||||
// }, {})
|
||||
|
||||
export default {
|
||||
...modules
|
||||
}
|
||||
// export default {
|
||||
// ...modules
|
||||
// }
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
import { fetch } from '_p/index/axios-config/axios'
|
||||
|
||||
interface PropsData {
|
||||
params?: any
|
||||
data?: any
|
||||
}
|
||||
|
||||
export const loginApi = ({ data }: PropsData) => {
|
||||
return fetch({ url: '/user/login', method: 'post', data })
|
||||
}
|
||||
|
||||
export const getRoleDetApi = ({ params }: PropsData) => {
|
||||
return fetch({ url: '/role/detail', method: 'get', params })
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
import { fetch } from '_p/index/axios-config/axios'
|
||||
|
||||
interface PropsData {
|
||||
params?: any
|
||||
data?: any
|
||||
}
|
||||
|
||||
export const getRoleListApi = ({ params }: PropsData) => {
|
||||
return fetch({ url: '/role/list', method: 'get', params })
|
||||
}
|
||||
|
||||
export const setRoleApi = ({ data }: PropsData) => {
|
||||
return fetch({ url: '/role/save', method: 'post', data })
|
||||
}
|
||||
|
||||
export const getRoleDetApi = ({ params }: PropsData) => {
|
||||
return fetch({ url: '/role/detail', method: 'get', params })
|
||||
}
|
||||
@ -0,0 +1,259 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="130px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="roleName" label="角色名">
|
||||
<el-input v-model="form.roleName" disabled placeholder="请输入角色名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="角色权限">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
:check-strictly="false"
|
||||
:expand-on-click-node="false"
|
||||
:data="routesData"
|
||||
:props="defaultProps"
|
||||
accordion
|
||||
node-key="path"
|
||||
highlight-current
|
||||
class="permission-tree"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="seletTreeData" :span="12">
|
||||
<el-form-item label="title">
|
||||
<el-input v-model="seletTreeData.title" />
|
||||
</el-form-item>
|
||||
<el-form-item label="component">
|
||||
<el-input v-model="seletTreeData.component" />
|
||||
</el-form-item>
|
||||
<el-form-item label="redirect">
|
||||
<el-input v-model="seletTreeData.redirect" />
|
||||
</el-form-item>
|
||||
<el-form-item label="activeMenu">
|
||||
<el-input v-model="seletTreeData.meta.activeMenu" />
|
||||
</el-form-item>
|
||||
<el-form-item label="name">
|
||||
<el-input v-model="seletTreeData.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="icon">
|
||||
<el-input v-model="seletTreeData.meta.icon" />
|
||||
</el-form-item>
|
||||
<el-form-item label="hidden">
|
||||
<el-switch v-model="seletTreeData.meta.hidden" />
|
||||
</el-form-item>
|
||||
<el-form-item label="alwaysShow">
|
||||
<el-switch v-model="seletTreeData.meta.alwaysShow" />
|
||||
</el-form-item>
|
||||
<el-form-item label="noCache">
|
||||
<el-switch v-model="seletTreeData.meta.noCache" />
|
||||
</el-form-item>
|
||||
<el-form-item label="breadcrumb">
|
||||
<el-switch v-model="seletTreeData.meta.breadcrumb" />
|
||||
</el-form-item>
|
||||
<el-form-item label="affix">
|
||||
<el-switch v-model="seletTreeData.meta.affix" />
|
||||
</el-form-item>
|
||||
<el-form-item label="noTagsView">
|
||||
<el-switch v-model="seletTreeData.meta.noTagsView" />
|
||||
</el-form-item>
|
||||
<el-form-item label="showMainRoute">
|
||||
<el-switch v-model="seletTreeData.meta.showMainRoute" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div class="dialong__button--wrap">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button :loading="subLoading" type="primary" @click="setListData">保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { setRoleApi, getRoleDetApi } from '../api'
|
||||
import { defineComponent, PropType, ref, reactive, nextTick, unref } from 'vue'
|
||||
import { AppRouteRecordRaw } from '_p/index/router/types'
|
||||
import { isExternal } from '@/utils/validate'
|
||||
import { Message } from '_c/Message'
|
||||
|
||||
const requiredRule = {
|
||||
required: true,
|
||||
message: '该项为必填项'
|
||||
}
|
||||
|
||||
interface Form {
|
||||
id: String
|
||||
roleName: String
|
||||
checkedNodes: any[]
|
||||
checkedkeys: any[]
|
||||
}
|
||||
|
||||
interface Rules {
|
||||
roleName: any[]
|
||||
}
|
||||
|
||||
interface DefaultProps {
|
||||
children: String
|
||||
label: String
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'InfoWrite2',
|
||||
props: {
|
||||
info: {
|
||||
type: Object as PropType<object>,
|
||||
default: () => null
|
||||
}
|
||||
},
|
||||
emits: ['success', 'close'],
|
||||
setup(props, { emit }) {
|
||||
const tree = ref<HTMLElement | null>(null)
|
||||
const formRef = ref<HTMLElement | null>(null)
|
||||
|
||||
const subLoading = ref<boolean>(false)
|
||||
|
||||
let form = reactive<Form>({
|
||||
id: '', // id
|
||||
roleName: '', // 角色名
|
||||
checkedNodes: [], // 被选中的节点
|
||||
checkedkeys: [] // 被选中的keys
|
||||
})
|
||||
|
||||
const rules = reactive<Rules>({
|
||||
roleName: [requiredRule]
|
||||
})
|
||||
|
||||
const defaultProps = reactive<DefaultProps>({
|
||||
children: 'children',
|
||||
label: 'title'
|
||||
})
|
||||
|
||||
const routesData = ref<any[]>([])
|
||||
|
||||
const seletTreeData = ref<any>(null) // 选中的菜单
|
||||
|
||||
async function getDet(): Promise<void> {
|
||||
if (props.info) {
|
||||
const id = (props.info as any).id
|
||||
try {
|
||||
const res = await getRoleDetApi({
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
if (res) {
|
||||
const formData = {}
|
||||
for (const key in form) {
|
||||
formData[key] = res.data[key]
|
||||
}
|
||||
form = Object.assign(form, formData)
|
||||
routesData.value = generateRoutes(form.checkedNodes)
|
||||
nextTick(() => {
|
||||
const treeRef = unref(tree as any)
|
||||
treeRef.setCheckedKeys(form.checkedkeys)
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增或者编辑
|
||||
function setListData() {
|
||||
try {
|
||||
subLoading.value = true
|
||||
const formRefWrap = unref(formRef as any)
|
||||
formRefWrap.validate(async(valid: boolean) => {
|
||||
if (valid) {
|
||||
const res = await setRoleApi({
|
||||
data: Object.assign(form, { checkedNodes: routesData })
|
||||
})
|
||||
if (res) {
|
||||
Message.success(form.id ? '编辑成功,请重新退出登录后查看效果' : '新增成功,请重新退出登录后查看效果')
|
||||
emit('success', form.id ? 'edit' : 'add')
|
||||
}
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
} finally {
|
||||
subLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 树形点击
|
||||
function handleNodeClick(data: any) {
|
||||
seletTreeData.value = data
|
||||
}
|
||||
|
||||
function close() {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
function generateRoutes(routes: any[]) {
|
||||
const res: any[] = []
|
||||
|
||||
for (const route of routes) {
|
||||
const data: any = {
|
||||
path: route.path,
|
||||
title: route.title || (route.meta && route.meta.title),
|
||||
name: route.name,
|
||||
redirect: route.redirect || '',
|
||||
component: route.component || '',
|
||||
meta: {
|
||||
hidden: route.meta && route.meta.hidden,
|
||||
alwaysShow: route.meta && route.meta.alwaysShow,
|
||||
icon: route.meta && route.meta.icon,
|
||||
noCache: route.meta && route.meta.noCache,
|
||||
breadcrumb: route.meta && route.meta.breadcrumb,
|
||||
affix: route.meta && route.meta.affix,
|
||||
noTagsView: route.meta && route.meta.noTagsView,
|
||||
activeMenu: route.meta && route.meta.activeMenu,
|
||||
showMainRoute: route.meta && route.meta.showMainRoute
|
||||
}
|
||||
}
|
||||
// recursive child routes
|
||||
if (route.children) {
|
||||
data.children = generateRoutes(route.children)
|
||||
}
|
||||
res.push(data)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
getDet()
|
||||
|
||||
return {
|
||||
formRef,
|
||||
routesData,
|
||||
tree,
|
||||
subLoading,
|
||||
form,
|
||||
rules,
|
||||
defaultProps,
|
||||
getDet,
|
||||
handleNodeClick,
|
||||
close,
|
||||
setListData,
|
||||
seletTreeData
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="由于是模拟数据,所以只提供了两种不同权限的角色,开发者可根据实际情况自行改造结合。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px;"
|
||||
/>
|
||||
|
||||
<div class="search__example--wrap">
|
||||
<com-search
|
||||
:data="searchData"
|
||||
@search-submit="searchSubmit"
|
||||
@reset-submit="resetSubmit"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:pagination="{
|
||||
currentPage: defalutParams.pageIndex,
|
||||
total: total,
|
||||
onSizeChange: handleSizeChange,
|
||||
onCurrentChange: handleCurrentChange
|
||||
}"
|
||||
>
|
||||
<template #remark="scope">
|
||||
<span>模拟</span>
|
||||
<el-tag
|
||||
:type="scope.row.roleName === 'admin' ? 'success' : 'warning'"
|
||||
style="margin: 0 15px;"
|
||||
>{{ scope.row.roleName === 'admin' ? '前端' : '后端' }}</el-tag>
|
||||
<span>角色</span>
|
||||
</template>
|
||||
|
||||
<template #action="scope">
|
||||
<el-button type="primary" size="mini" @click="open(scope.row)">编辑</el-button>
|
||||
</template>
|
||||
</com-table>
|
||||
|
||||
<com-dialog v-model="dialogVisible" :title="title">
|
||||
<info-write
|
||||
v-if="comName === 'InfoWrite' && dialogVisible"
|
||||
:info="info"
|
||||
@close="toggleVisible"
|
||||
@success="success"
|
||||
/>
|
||||
<info-write2
|
||||
v-if="comName === 'InfoWrite2' && dialogVisible"
|
||||
:info="info"
|
||||
@close="toggleVisible"
|
||||
@success="success"
|
||||
/>
|
||||
</com-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
import { useExample } from '@/hooks/useExample'
|
||||
|
||||
import { getRoleListApi } from './api'
|
||||
|
||||
import InfoWrite from './components/InfoWrite.vue'
|
||||
import InfoWrite2 from './components/InfoWrite2.vue'
|
||||
|
||||
const searchData = [
|
||||
{
|
||||
label: '角色名',
|
||||
value: '',
|
||||
itemType: 'input',
|
||||
field: 'roleName',
|
||||
placeholder: '请输入角色名',
|
||||
clearable: true
|
||||
}
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'roleName',
|
||||
label: '角色名'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
slots: {
|
||||
default: 'remark'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: '操作',
|
||||
width: '80px',
|
||||
slots: {
|
||||
default: 'action'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Role',
|
||||
components: {
|
||||
InfoWrite,
|
||||
InfoWrite2
|
||||
},
|
||||
setup() {
|
||||
const info = ref<any>(null)
|
||||
|
||||
const {
|
||||
defalutParams,
|
||||
tableData,
|
||||
loading,
|
||||
total,
|
||||
dialogVisible,
|
||||
title,
|
||||
currentChange,
|
||||
sizeChange,
|
||||
comName,
|
||||
toggleVisible
|
||||
} = useExample()
|
||||
|
||||
// 请求数据
|
||||
async function getRoleList(data?: any): Promise<void> {
|
||||
try {
|
||||
const res = await getRoleListApi({
|
||||
params: Object.assign(defalutParams, data || {})
|
||||
})
|
||||
if (res) {
|
||||
total.value = res.data.total
|
||||
tableData.value = res.data.list
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 查询
|
||||
function searchSubmit(data: any) {
|
||||
// 该方法重置了一些默认参数
|
||||
currentChange(1)
|
||||
getRoleList(data)
|
||||
}
|
||||
|
||||
// 重置
|
||||
function resetSubmit(data: any) {
|
||||
// 该方法重置了一些默认参数
|
||||
currentChange(1)
|
||||
getRoleList(data)
|
||||
}
|
||||
|
||||
// 展示多少条
|
||||
function handleSizeChange(val: number) {
|
||||
// 该方法重置了一些默认参数
|
||||
sizeChange(val)
|
||||
getRoleList()
|
||||
}
|
||||
|
||||
// 展示第几页
|
||||
function handleCurrentChange(val: number) {
|
||||
// 该方法重置了一些默认参数
|
||||
currentChange(val)
|
||||
getRoleList()
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
function open(row: any) {
|
||||
comName.value = row.roleName === 'admin' ? 'InfoWrite' : 'InfoWrite2'
|
||||
title.value = !row ? '新增' : '编辑'
|
||||
info.value = row || null
|
||||
toggleVisible(true)
|
||||
}
|
||||
|
||||
// 成功之后的回调
|
||||
function success(type: string) {
|
||||
if (type === 'add') {
|
||||
currentChange(1)
|
||||
}
|
||||
toggleVisible()
|
||||
getRoleList()
|
||||
}
|
||||
|
||||
getRoleList()
|
||||
|
||||
return {
|
||||
searchData,
|
||||
columns,
|
||||
info,
|
||||
defalutParams,
|
||||
tableData,
|
||||
loading,
|
||||
total,
|
||||
dialogVisible,
|
||||
title,
|
||||
currentChange,
|
||||
sizeChange,
|
||||
comName,
|
||||
toggleVisible,
|
||||
searchSubmit,
|
||||
resetSubmit,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
open,
|
||||
success
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@ -0,0 +1,10 @@
|
||||
import { fetch } from '_p/index/axios-config/axios'
|
||||
|
||||
interface PropsData {
|
||||
params?: any
|
||||
data?: any
|
||||
}
|
||||
|
||||
export const getUserListApi = ({ params }: PropsData): any => {
|
||||
return fetch({ url: '/user/list', method: 'get', params })
|
||||
}
|
||||
@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="由于是模拟数据,所以只提供了两种不同权限的帐号,开发者可根据实际情况自行改造结合。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px;"
|
||||
/>
|
||||
|
||||
<div class="search__example--wrap">
|
||||
<com-search
|
||||
:data="searchData"
|
||||
@search-submit="searchSubmit"
|
||||
@reset-submit="resetSubmit"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:pagination="{
|
||||
currentPage: defalutParams.pageIndex,
|
||||
total: total,
|
||||
onSizeChange: handleSizeChange,
|
||||
onCurrentChange: handleCurrentChange
|
||||
}"
|
||||
>
|
||||
<template #remark="scope">
|
||||
<span>模拟</span>
|
||||
<el-tag
|
||||
:type="scope.row.userName === 'admin' ? 'success' : 'warning'"
|
||||
style="margin: 0 15px;"
|
||||
>{{ scope.row.userName === 'admin' ? '前端' : '后端' }}</el-tag>
|
||||
<span>控制路由权限</span>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import { useExample } from '@/hooks/useExample'
|
||||
|
||||
import { getUserListApi } from './api'
|
||||
|
||||
const searchData = [
|
||||
{
|
||||
label: '帐号',
|
||||
value: '',
|
||||
itemType: 'input',
|
||||
field: 'userName',
|
||||
placeholder: '请输入帐号',
|
||||
clearable: true
|
||||
}
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'userName',
|
||||
label: '帐号'
|
||||
},
|
||||
{
|
||||
field: 'password',
|
||||
label: '密码'
|
||||
},
|
||||
{
|
||||
field: 'role',
|
||||
label: '角色'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
slots: {
|
||||
default: 'remark'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export default defineComponent({
|
||||
name: 'User',
|
||||
setup() {
|
||||
const {
|
||||
defalutParams,
|
||||
tableData,
|
||||
loading,
|
||||
total,
|
||||
title,
|
||||
currentChange,
|
||||
sizeChange
|
||||
} = useExample()
|
||||
|
||||
// 请求数据
|
||||
async function getUserList(data?: any): Promise<void> {
|
||||
try {
|
||||
const res = await getUserListApi({
|
||||
params: Object.assign(defalutParams, data || {})
|
||||
})
|
||||
if (res) {
|
||||
total.value = res.data.total
|
||||
tableData.value = res.data.list
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 查询
|
||||
function searchSubmit(data: any) {
|
||||
// 该方法重置了一些默认参数
|
||||
currentChange(1)
|
||||
getUserList(data)
|
||||
}
|
||||
|
||||
// 重置
|
||||
function resetSubmit(data: any) {
|
||||
// 该方法重置了一些默认参数
|
||||
currentChange(1)
|
||||
getUserList(data)
|
||||
}
|
||||
|
||||
// 展示多少条
|
||||
function handleSizeChange(val: number) {
|
||||
// 该方法重置了一些默认参数
|
||||
sizeChange(val)
|
||||
getUserList()
|
||||
}
|
||||
|
||||
// 展示第几页
|
||||
function handleCurrentChange(val: number) {
|
||||
// 该方法重置了一些默认参数
|
||||
currentChange(val)
|
||||
getUserList()
|
||||
}
|
||||
|
||||
getUserList()
|
||||
|
||||
return {
|
||||
searchData,
|
||||
columns,
|
||||
defalutParams,
|
||||
tableData,
|
||||
loading,
|
||||
total,
|
||||
title,
|
||||
currentChange,
|
||||
sizeChange,
|
||||
searchSubmit,
|
||||
resetSubmit,
|
||||
handleSizeChange,
|
||||
handleCurrentChange
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
Loading…
Reference in New Issue