mirror of
https://github.com/jekip/naive-ui-admin.git
synced 2026-02-04 13:42:27 +08:00
新增-系统设置-菜单权限-角色权限页面
This commit is contained in:
39
mock/system/role.ts
Normal file
39
mock/system/role.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { resultSuccess, doCustomTimes } from '../_util'
|
||||
|
||||
const roleList = ((pageSize) => {
|
||||
const result:any[] = []
|
||||
doCustomTimes(pageSize,()=> {
|
||||
result.push({
|
||||
id: '@integer(10,100)',
|
||||
name: '@cname()',
|
||||
explain:'@cname()',
|
||||
isDefault:'@boolean()',
|
||||
create_date: `@date('yyyy-MM-dd')`,
|
||||
'status|1': ['normal', 'enable', 'disable'],
|
||||
});
|
||||
})
|
||||
return result
|
||||
});
|
||||
|
||||
|
||||
export default [
|
||||
//表格数据列表
|
||||
{
|
||||
url: '/api/role/list',
|
||||
timeout: 1000,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
const { page = 1, pageSize = 10 } = query;
|
||||
const list = roleList(Number(pageSize))
|
||||
return resultSuccess({
|
||||
page:Number(page),
|
||||
pageSize:Number(pageSize),
|
||||
pageCount: 60,
|
||||
list
|
||||
}
|
||||
);
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
11
src/api/system/role.ts
Normal file
11
src/api/system/role.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import http from '@/utils/http/axios'
|
||||
|
||||
/**
|
||||
* @description: 角色列表
|
||||
*/
|
||||
export function getRoleList() {
|
||||
return http.request({
|
||||
url: '/role/list',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
@@ -60,7 +60,8 @@ import {
|
||||
NInputNumber,
|
||||
NLoadingBarProvider,
|
||||
NModal,
|
||||
NUpload
|
||||
NUpload,
|
||||
NTree
|
||||
} from 'naive-ui'
|
||||
|
||||
const naive = create({
|
||||
@@ -124,7 +125,8 @@ const naive = create({
|
||||
NInputNumber,
|
||||
NLoadingBarProvider,
|
||||
NModal,
|
||||
NUpload
|
||||
NUpload,
|
||||
NTree
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
50
src/router/modules/system.ts
Normal file
50
src/router/modules/system.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { RouteRecordRaw } from 'vue-router'
|
||||
import { Layout } from '@/router/constant';
|
||||
import { ToolOutlined } from '@vicons/antd'
|
||||
import { OptionsSharp } from '@vicons/ionicons5'
|
||||
import { renderIcon } from '@/utils/index'
|
||||
|
||||
/**
|
||||
* @param name 路由名称, 必须设置,且不能重名
|
||||
* @param meta 路由元信息(路由附带扩展信息)
|
||||
* @param redirect 重定向地址, 访问这个路由时,自定进行重定向
|
||||
* @param meta.disabled 禁用整个菜单
|
||||
* @param meta.title 菜单名称
|
||||
* @param meta.icon 菜单图标
|
||||
* @param meta.keepAlive 缓存该路由
|
||||
* @param meta.sort 排序越小越排前
|
||||
*
|
||||
* */
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: '/system',
|
||||
name: 'System',
|
||||
redirect: '/system/menu',
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: '系统设置',
|
||||
icon: renderIcon(OptionsSharp),
|
||||
sort: 1
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'menu',
|
||||
name: 'system_menu',
|
||||
meta: {
|
||||
title: '菜单权限管理',
|
||||
},
|
||||
component: () => import('@/views/system/menu/menu.vue')
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
name: 'system_role',
|
||||
meta: {
|
||||
title: '角色权限管理',
|
||||
},
|
||||
component: () => import('@/views/system/role/role.vue')
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
export default routes
|
||||
196
src/views/system/menu/menu.vue
Normal file
196
src/views/system/menu/menu.vue
Normal file
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="菜单权限管理">
|
||||
页面数据为 Mock 示例数据,非真实数据。
|
||||
</n-card>
|
||||
</div>
|
||||
|
||||
<n-grid class="mt-4" cols="1 s:1 m:1 l:3 xl:3 2xl:3" responsive="screen" :x-gap="12">
|
||||
<n-gi span="1">
|
||||
<n-card :segmented="{ content: 'hard' }" :bordered="false" size="small">
|
||||
<template #header>
|
||||
<n-space>
|
||||
<n-dropdown trigger="hover" :options="addMenuOptions">
|
||||
<n-button type="info" ghost icon-placement="right">
|
||||
添加菜单
|
||||
<template #icon>
|
||||
<div class="flex items-center">
|
||||
<n-icon size="14">
|
||||
<DownOutlined/>
|
||||
</n-icon>
|
||||
</div>
|
||||
</template>
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
<n-button type="info" ghost icon-placement="left">
|
||||
全部收起
|
||||
<template #icon>
|
||||
<div class="flex items-center">
|
||||
<n-icon size="14">
|
||||
<AlignLeftOutlined/>
|
||||
</n-icon>
|
||||
</div>
|
||||
</template>
|
||||
</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<div class="w-full menu">
|
||||
<n-input type="input" placeholder="输入菜单名称搜索">
|
||||
<template #suffix>
|
||||
<n-icon size="18" class="cursor-pointer">
|
||||
<SearchOutlined/>
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-input>
|
||||
<div class="py-3 menu-list">
|
||||
<n-tree
|
||||
block-line
|
||||
cascade
|
||||
checkable
|
||||
:data="treeData"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi span="2">
|
||||
<n-card :segmented="{ content: 'hard' }" :bordered="false" size="small">
|
||||
<template #header>
|
||||
<n-space>
|
||||
<n-icon size="18">
|
||||
<EditOutlined />
|
||||
</n-icon>
|
||||
编辑菜单
|
||||
</n-space>
|
||||
</template>
|
||||
<n-alert type="info" closable>
|
||||
从菜单列表选择一项后,进行编辑
|
||||
</n-alert>
|
||||
<n-form
|
||||
:model="formParams"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
label-placement="left"
|
||||
:label-width="100"
|
||||
>
|
||||
<n-form-item label="类型" path="type">
|
||||
<span>{{formParams.type}}</span>
|
||||
</n-form-item>
|
||||
<n-form-item label="标题" path="title">
|
||||
<n-input placeholder="请输入标题" v-model:value="formParams.title" />
|
||||
</n-form-item>
|
||||
<n-form-item label="副标题" path="subTitle">
|
||||
<n-input placeholder="请输入副标题" v-model:value="formParams.subTitle" />
|
||||
</n-form-item>
|
||||
<n-form-item label="路径" path="path">
|
||||
<n-input placeholder="请输入路径" v-model:value="formParams.path" />
|
||||
</n-form-item>
|
||||
<n-form-item label="打开方式" path="openType">
|
||||
<n-radio-group v-model:value="formParams.openType" name="openType">
|
||||
<n-space>
|
||||
<n-radio :value="1">当前窗口</n-radio>
|
||||
<n-radio :value="2">新窗口</n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item label="菜单权限" path="auth">
|
||||
<n-input placeholder="请输入权限,多个权限用,分割" v-model:value="formParams.auth" />
|
||||
</n-form-item>
|
||||
<n-form-item path="auth" style="margin-left: 100px">
|
||||
<n-space>
|
||||
<n-button type="primary">保存修改</n-button>
|
||||
<n-button>重置</n-button>
|
||||
</n-space>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, reactive, toRefs, } from 'vue'
|
||||
import { useMessage } from 'naive-ui'
|
||||
import { DownOutlined, AlignLeftOutlined, SearchOutlined, EditOutlined } from '@vicons/antd'
|
||||
|
||||
const rules = {
|
||||
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
components: { DownOutlined, AlignLeftOutlined, SearchOutlined, EditOutlined },
|
||||
setup() {
|
||||
|
||||
const message = useMessage()
|
||||
|
||||
const state = reactive({
|
||||
addMenuOptions: [
|
||||
{
|
||||
label: '添加顶级菜单',
|
||||
key: 'home',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
label: '添加子菜单',
|
||||
key: 'son',
|
||||
disabled: false
|
||||
},
|
||||
],
|
||||
treeData: [
|
||||
{
|
||||
label: 'Dashboard',
|
||||
key: 'dashboard',
|
||||
children: [
|
||||
{
|
||||
label: '主控台',
|
||||
key: 'console',
|
||||
},
|
||||
{
|
||||
label: '工作台',
|
||||
key: 'workplace',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '表单管理',
|
||||
key: 'form',
|
||||
children: [
|
||||
{
|
||||
label: '基础表单',
|
||||
key: 'basic-form',
|
||||
},
|
||||
{
|
||||
label: '分步表单',
|
||||
key: 'step-form',
|
||||
},
|
||||
{
|
||||
label: '表单详情',
|
||||
key: 'detail',
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
],
|
||||
defaultExpandedKeys: ref(['home', 'dashboard']),
|
||||
formParams: {
|
||||
type: '侧边栏菜单',
|
||||
title: '工作台',
|
||||
subTitle:'',
|
||||
path:'/dashboard/workplace',
|
||||
openType:1
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
rules
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
66
src/views/system/role/columns.ts
Normal file
66
src/views/system/role/columns.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { h } from 'vue'
|
||||
import { NTag, NButton } from 'naive-ui'
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: 'id',
|
||||
key: 'id'
|
||||
},
|
||||
{
|
||||
title: '角色名称',
|
||||
key: 'name'
|
||||
},
|
||||
{
|
||||
title: '说明',
|
||||
key: 'explain'
|
||||
},
|
||||
{
|
||||
title: '是否默认角色',
|
||||
key: 'isDefault',
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: row.isDefault ? 'success' : 'error'
|
||||
},
|
||||
{
|
||||
default: () => row.isDefault ? '是' : '否'
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'create_date'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'actions',
|
||||
width: 150,
|
||||
//简单写一下例子,不建议这么写,过段时间,这里封二次封装
|
||||
render() {
|
||||
return [
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
type: 'error',
|
||||
style: 'margin-right:10px',
|
||||
onClick: () => {
|
||||
}
|
||||
},
|
||||
{ default: () => '删除' }
|
||||
),
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
onClick: () => {
|
||||
}
|
||||
},
|
||||
{ default: () => '编辑' }
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
161
src/views/system/role/role.vue
Normal file
161
src/views/system/role/role.vue
Normal file
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="角色权限管理">
|
||||
页面数据为 Mock 示例数据,非真实数据。
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-4 proCard">
|
||||
<BasicTable
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="row => row.id"
|
||||
ref="actionRef"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary" @click="addTable">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<PlusOutlined/>
|
||||
</n-icon>
|
||||
</template>
|
||||
新建角色
|
||||
</n-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
|
||||
<n-modal v-model:show="showModal" :show-icon="false" preset="dialog" title="新建">
|
||||
<n-form
|
||||
:model="formParams"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
label-placement="left"
|
||||
:label-width="80"
|
||||
class="py-4"
|
||||
>
|
||||
<n-form-item label="名称" path="name">
|
||||
<n-input placeholder="请输入名称" v-model:value="formParams.name"/>
|
||||
</n-form-item>
|
||||
<n-form-item label="地址" path="address">
|
||||
<n-input type="textarea" placeholder="请输入地址" v-model:value="formParams.address"/>
|
||||
</n-form-item>
|
||||
<n-form-item label="日期" path="date">
|
||||
<n-date-picker type="datetime" placeholder="请选择日期" v-model:value="formParams.date"/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
|
||||
<template #action>
|
||||
<n-space>
|
||||
<n-button @click="()=> showModal = false">取消</n-button>
|
||||
<n-button type="info" :loading="formBtnLoading" @click="confirmForm">确定</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
</n-modal>
|
||||
|
||||
</n-card>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, toRefs, ref, h } from 'vue'
|
||||
import { useMessage } from 'naive-ui'
|
||||
import { BasicTable } from '@/components/Table'
|
||||
import { getRoleList } from '@/api/system/role'
|
||||
import { columns } from './columns'
|
||||
import { PlusOutlined } from '@vicons/antd'
|
||||
|
||||
const rules = {
|
||||
name: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请输入名称'
|
||||
},
|
||||
address: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请输入地址'
|
||||
},
|
||||
date: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
trigger: ['blur', 'change'],
|
||||
message: '请选择日期'
|
||||
},
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
components: { BasicTable, PlusOutlined },
|
||||
setup() {
|
||||
const formRef: any = ref(null)
|
||||
const message = useMessage()
|
||||
const actionRef = ref()
|
||||
const state = reactive({
|
||||
showModal: false,
|
||||
formBtnLoading: false,
|
||||
formParams: {
|
||||
name: '',
|
||||
address: '',
|
||||
date: []
|
||||
},
|
||||
params: {
|
||||
pageSize: 5,
|
||||
name: 'xiaoMa'
|
||||
},
|
||||
})
|
||||
|
||||
function addTable() {
|
||||
state.showModal = true
|
||||
}
|
||||
|
||||
const loadDataTable = async (params) => {
|
||||
const data = await getRoleList(params);
|
||||
return data
|
||||
}
|
||||
|
||||
function onCheckedRow(rowKeys) {
|
||||
console.log(rowKeys)
|
||||
}
|
||||
|
||||
function reloadTable() {
|
||||
actionRef.value.reload()
|
||||
}
|
||||
|
||||
function confirmForm(e) {
|
||||
e.preventDefault()
|
||||
state.formBtnLoading = true
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
message.success('新建成功')
|
||||
setTimeout(() => {
|
||||
state.showModal = false
|
||||
reloadTable()
|
||||
})
|
||||
} else {
|
||||
message.error('请填写完整信息')
|
||||
}
|
||||
state.formBtnLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
formRef,
|
||||
columns,
|
||||
rules,
|
||||
actionRef,
|
||||
confirmForm,
|
||||
loadDataTable,
|
||||
onCheckedRow,
|
||||
reloadTable,
|
||||
addTable
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user