Merge branch 'develop' of http://192.168.11.14:51037/zhangtao/restructure into zhangtao
This commit is contained in:
commit
5e1064917d
|
|
@ -3049,7 +3049,11 @@
|
|||
"node_modules/connect/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
<<<<<<< HEAD
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
=======
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/consola": {
|
||||
|
|
@ -3535,9 +3539,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
<<<<<<< HEAD
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
|
||||
"integrity": "sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A=="
|
||||
=======
|
||||
"version": "1.11.2",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz",
|
||||
"integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw=="
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
|
|
@ -4352,9 +4362,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/esbuild-register": {
|
||||
<<<<<<< HEAD
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.3.3.tgz",
|
||||
"integrity": "sha512-eFHOkutgIMJY5gc8LUp/7c+LLlDqzNi9T6AwCZ2WKKl3HmT+5ef3ZRyPPxDOynInML0fgaC50yszPKfPnjC0NQ==",
|
||||
=======
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.3.2.tgz",
|
||||
"integrity": "sha512-jceAtTO6zxPmCfSD5cBb3rgIK1vmuqCKYwgylHiS1BF4pq0jJiJb4K2QMuqF4BEw7XDBRatYzip0upyTzfkgsQ==",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"esbuild": ">=0.12 <1"
|
||||
|
|
@ -6082,7 +6098,11 @@
|
|||
"node_modules/is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
<<<<<<< HEAD
|
||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
||||
=======
|
||||
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-number": {
|
||||
|
|
@ -6232,9 +6252,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jake/node_modules/async": {
|
||||
<<<<<<< HEAD
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
|
||||
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
|
||||
=======
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
|
||||
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/jake/node_modules/chalk": {
|
||||
|
|
@ -7854,9 +7880,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/pinia/node_modules/vue-demi": {
|
||||
<<<<<<< HEAD
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.1.tgz",
|
||||
"integrity": "sha512-xmkJ56koG3ptpLnpgmIzk9/4nFf4CqduSJbUM0OdPoU87NwRuZ6x49OLhjSa/fC15fV+5CbEnrxU4oyE022svg==",
|
||||
=======
|
||||
"version": "0.12.5",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz",
|
||||
"integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
|
|
@ -13694,7 +13726,11 @@
|
|||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
<<<<<<< HEAD
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
=======
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
|
|
@ -14049,9 +14085,15 @@
|
|||
"requires": {}
|
||||
},
|
||||
"dayjs": {
|
||||
<<<<<<< HEAD
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
|
||||
"integrity": "sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A=="
|
||||
=======
|
||||
"version": "1.11.2",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz",
|
||||
"integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw=="
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
|
|
@ -14603,9 +14645,15 @@
|
|||
"optional": true
|
||||
},
|
||||
"esbuild-register": {
|
||||
<<<<<<< HEAD
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.3.3.tgz",
|
||||
"integrity": "sha512-eFHOkutgIMJY5gc8LUp/7c+LLlDqzNi9T6AwCZ2WKKl3HmT+5ef3ZRyPPxDOynInML0fgaC50yszPKfPnjC0NQ==",
|
||||
=======
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.3.2.tgz",
|
||||
"integrity": "sha512-jceAtTO6zxPmCfSD5cBb3rgIK1vmuqCKYwgylHiS1BF4pq0jJiJb4K2QMuqF4BEw7XDBRatYzip0upyTzfkgsQ==",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
|
|
@ -15884,7 +15932,11 @@
|
|||
"is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
<<<<<<< HEAD
|
||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
||||
=======
|
||||
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"dev": true
|
||||
},
|
||||
"is-number": {
|
||||
|
|
@ -15989,9 +16041,15 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"async": {
|
||||
<<<<<<< HEAD
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
|
||||
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
|
||||
=======
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
|
||||
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
|
|
@ -17254,9 +17312,15 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"vue-demi": {
|
||||
<<<<<<< HEAD
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.1.tgz",
|
||||
"integrity": "sha512-xmkJ56koG3ptpLnpgmIzk9/4nFf4CqduSJbUM0OdPoU87NwRuZ6x49OLhjSa/fC15fV+5CbEnrxU4oyE022svg==",
|
||||
=======
|
||||
"version": "0.12.5",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz",
|
||||
"integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==",
|
||||
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
import { defAxios as request } from '@/utils/http'
|
||||
export function updatePwd(data) {
|
||||
return request({
|
||||
url: '/index/updatePwd',
|
||||
method: 'PUT',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { defAxios as request } from '@/utils/http'
|
||||
/**
|
||||
* 获取部门分页数据接口
|
||||
* 获取部门管理数据接口
|
||||
* @returns 部门分页
|
||||
*/
|
||||
export function getDeptList(params) {
|
||||
|
|
@ -53,7 +53,7 @@ export function editDept(data) {
|
|||
*/
|
||||
export function deleteDept(id) {
|
||||
return request({
|
||||
url: `/dept/delete${[id]}`,
|
||||
url: `/dept/delete/${id}`,
|
||||
method: 'DELETE'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { defAxios as request } from '@/utils/http'
|
||||
/**
|
||||
* 获取菜单分页数据接口
|
||||
* @returns 菜单分页数据
|
||||
* 获取菜单管理数据接口
|
||||
* @returns 菜单数据
|
||||
*/
|
||||
export function getMenuList(params) {
|
||||
return request({
|
||||
|
|
@ -53,7 +53,7 @@ export function editMenu(data) {
|
|||
*/
|
||||
export function deleteMenu(id) {
|
||||
return request({
|
||||
url: `/menu/delete${[id]}`,
|
||||
url: `/menu/delete/${id}`,
|
||||
method: 'DELETE'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ export function setRoleStatus(data) {
|
|||
* 删除角色
|
||||
* params
|
||||
*/
|
||||
export function deleteRole(id) {
|
||||
export function deleteRole(data) {
|
||||
return request({
|
||||
url: `/role/delete${[id]}`,
|
||||
url: `/role/delete/${data}`,
|
||||
method: 'DELETE'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ export function editUser(data) {
|
|||
* 删除用户
|
||||
* params
|
||||
*/
|
||||
export function deleteUser(id) {
|
||||
export function deleteUser(idList) {
|
||||
return request({
|
||||
url: `/user/delete${[id]}`,
|
||||
url: `/user/delete/${idList}`,
|
||||
method: 'DELETE'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,15 +8,9 @@ export function getUsers(data = {}) {
|
|||
})
|
||||
}
|
||||
|
||||
export function getUser(id) {
|
||||
if (id) {
|
||||
return request({
|
||||
url: `/user/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
export function getUser() {
|
||||
return request({
|
||||
url: '/user',
|
||||
url: '/index/getUserInfo',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<n-modal
|
||||
v-bind="getModalOptions"
|
||||
:style="`width:${getModalOptions.width}px`"
|
||||
preset="card"
|
||||
:title="options.title"
|
||||
@update:show="handleClose"
|
||||
>
|
||||
<n-card :bordered="false">
|
||||
<slot name="Context" />
|
||||
<n-space style="float: right">
|
||||
<n-button @click="handleClose">取消</n-button>
|
||||
<n-button type="primary" @click="handleClick">确认</n-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { defineComponent, computed, unref } from 'vue'
|
||||
export default defineComponent({
|
||||
name: 'Modal',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
save: null, // click事件没有检验
|
||||
onClose: (value) => {
|
||||
return value
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const getModalOptions = computed(() => {
|
||||
return {
|
||||
...props.options,
|
||||
width: props.options.width || 600
|
||||
}
|
||||
})
|
||||
const handleClick = function() {
|
||||
emit('save')
|
||||
}
|
||||
const handleClose = function() {
|
||||
emit('onClose', true)
|
||||
}
|
||||
return {
|
||||
getModalOptions,
|
||||
handleClick,
|
||||
handleClose
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
</style>
|
||||
|
|
@ -44,7 +44,7 @@ export function useDataSource(propsRef, { getPaginationInfo, setPagination, setL
|
|||
}
|
||||
}
|
||||
// 处理数据结构
|
||||
const resultInfo = res[listField] ? res[listField] : []
|
||||
const resultInfo = res[listField] ? res[listField] : res
|
||||
dataSourceRef.value = dataType === 'tree' ? dealTree(resultInfo) : resultInfo
|
||||
setPagination({
|
||||
[pageField]: currentPage,
|
||||
|
|
@ -74,7 +74,7 @@ export function useDataSource(propsRef, { getPaginationInfo, setPagination, setL
|
|||
* @returns 返回树形结构数据
|
||||
*/
|
||||
function dealTree(info) {
|
||||
const tree = toTreeData(info.data, 'id', 'pid', 'children')
|
||||
const tree = toTreeData(info, 'id', 'pid', 'children')
|
||||
return tree
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
点击上传
|
||||
</n-upload>
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
preset="card"
|
||||
style="width: 600px"
|
||||
>
|
||||
|
|
@ -50,8 +49,8 @@ export default defineComponent({
|
|||
}
|
||||
}
|
||||
})
|
||||
function handleChange(file) {
|
||||
console.log(222, file)
|
||||
function handleChange(res) {
|
||||
console.log('已选择的文件:', res.file.file)
|
||||
}
|
||||
/**
|
||||
* @description: 上传前判断文件是否符合条件
|
||||
|
|
@ -60,7 +59,6 @@ export default defineComponent({
|
|||
*/
|
||||
function handleBeforeUpload(options) {
|
||||
const { file, fileList } = options
|
||||
console.log(11, file, fileList)
|
||||
if (props.size) {
|
||||
const size = file.file.size
|
||||
if (size < props.size * 1024 * 1024) {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export default {
|
|||
/* 初始化搜索表单信息 */
|
||||
function initForm() {
|
||||
data.info.forEach((item) => {
|
||||
form.value[item.key] = ''
|
||||
form.value[item.key] = null
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,35 @@
|
|||
<template>
|
||||
<n-layout-header class="layout__header" bordered>
|
||||
Header Header Header
|
||||
<!-- <SideMenu menu-mode="horizontal" /> -->
|
||||
<log-out />
|
||||
</n-layout-header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SideMenu from '@/layout/components/Menu/index.vue'
|
||||
import LogOut from '../Logout/index.vue'
|
||||
import { defineComponent } from 'vue'
|
||||
export default defineComponent({
|
||||
name: 'LayoutHeader',
|
||||
components: { SideMenu }
|
||||
components: { SideMenu, LogOut }
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.layout__header {
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
.user_msg {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
.user_avatar {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
<template>
|
||||
<Modal
|
||||
:options="getModalOptions"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
:on-close="handleClose"
|
||||
>
|
||||
<template #Context>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-placement="left"
|
||||
:rules="rules"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
>
|
||||
<n-form-item
|
||||
label="旧密码:"
|
||||
path="oldPassword"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.oldPassword"
|
||||
type="password"
|
||||
:maxlength="20"
|
||||
placeholder="请输入旧密码"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="新密码:"
|
||||
path="newPassword"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.newPassword"
|
||||
type="password"
|
||||
:maxlength="20"
|
||||
placeholder="请输入新密码"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="确认密码:"
|
||||
path="configmPassword"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.configmPassword"
|
||||
type="password"
|
||||
:maxlength="20"
|
||||
placeholder="请再次输入新密码"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
<script>
|
||||
import Modal from '../../../../components/Modal/index.vue'
|
||||
import { updatePwd } from '@/api/home/index.js'
|
||||
import { reactive, toRefs, computed } from '@vue/reactivity'
|
||||
export default {
|
||||
name: 'UpdateModal',
|
||||
components: { Modal },
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
'update:visible': null
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const data = reactive({
|
||||
form: {
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
configmPassword: ''
|
||||
},
|
||||
rules: {
|
||||
oldPassword: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请输入旧密码'
|
||||
},
|
||||
newPassword: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请输入新密码'
|
||||
},
|
||||
configmPassword: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请再次输入新密码'
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
const getModalOptions = computed(() => {
|
||||
return {
|
||||
title: '修改密码',
|
||||
show: props.visible,
|
||||
negativeText: '取消',
|
||||
positiveText: '确认'
|
||||
}
|
||||
})
|
||||
|
||||
/* 关闭弹窗 */
|
||||
const handleClose = () => {
|
||||
emit('update:visible', false)
|
||||
}
|
||||
return {
|
||||
...toRefs(data),
|
||||
getModalOptions,
|
||||
handleClose
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleConfirm() {
|
||||
this.$refs.formRef.validate((errors) => {
|
||||
if (!errors) {
|
||||
updatePwd(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
<template>
|
||||
<n-dropdown trigger="hover" :options="options" @select="selectKey">
|
||||
<div class="user_msg">
|
||||
<n-image
|
||||
class="user_avatar"
|
||||
:src="userInfo.avatar"
|
||||
preview-disabled
|
||||
/>
|
||||
<span class="user_name">{{ userInfo.realname }}</span>
|
||||
</div>
|
||||
</n-dropdown>
|
||||
|
||||
<!-- 修改密码 -->
|
||||
<update-modal v-if="modalShow" v-modal:visible="modalShow" />
|
||||
</template>
|
||||
<script>
|
||||
import { reactive, toRefs, h } from 'vue'
|
||||
import { NIcon } from 'naive-ui'
|
||||
import {
|
||||
Pencil as EditIcon,
|
||||
LogOutOutline as LogoutIcon
|
||||
} from '@vicons/ionicons5'
|
||||
import { useDialog } from 'naive-ui'
|
||||
import { loginOut } from '@/api/login/index.js'
|
||||
import { mapActions, mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user.js'
|
||||
import UpdateModal from './components/UpdateModal.vue'
|
||||
export default {
|
||||
name: 'LogOut',
|
||||
components: { UpdateModal },
|
||||
setup() {
|
||||
const renderIcon = (icon) => {
|
||||
return () => {
|
||||
return h(NIcon, null, {
|
||||
default: () => h(icon)
|
||||
})
|
||||
}
|
||||
}
|
||||
const data = reactive({
|
||||
options: [
|
||||
{
|
||||
label: '修改密码',
|
||||
key: 'edit',
|
||||
icon: renderIcon(EditIcon)
|
||||
},
|
||||
{
|
||||
label: '退出登录',
|
||||
key: 'out',
|
||||
icon: renderIcon(LogoutIcon)
|
||||
}
|
||||
],
|
||||
modalShow: false
|
||||
})
|
||||
|
||||
// 选中选项触发的回调
|
||||
const dialog = useDialog()
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
dialog
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, {
|
||||
userInfo: 'userInfo'
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useUserStore, ['logout']),
|
||||
selectKey(key) {
|
||||
console.log(key)
|
||||
if (key === 'out') {
|
||||
this.dialog.warning({
|
||||
title: '提示',
|
||||
content: '确定要退出登录吗?',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
loginOut().then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$router.replace('/login')
|
||||
this.logout()
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} else if (key === 'edit') {
|
||||
this.modalShow = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.user_msg {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
.user_avatar {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<n-menu
|
||||
:mode="menuMode"
|
||||
:accordion="true"
|
||||
:value="(currentRoute.title && currentRoute.meta.activeMenu) || currentRoute.title"
|
||||
:options="getMenuOptions"
|
||||
@update:value="handleMenuSelect"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<Modal
|
||||
:options="getModalOptions"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
:on-close="handleClose"
|
||||
>
|
||||
<template #Context>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-placement="left"
|
||||
:rules="rules"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
>
|
||||
<n-form-item
|
||||
label="旧密码:"
|
||||
path="oldPassword"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.oldPassword"
|
||||
type="password"
|
||||
:maxlength="20"
|
||||
placeholder="请输入旧密码"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="新密码:"
|
||||
path="newPassword"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.newPassword"
|
||||
type="password"
|
||||
:maxlength="20"
|
||||
placeholder="请输入新密码"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="确认密码:"
|
||||
path="configmPassword"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.configmPassword"
|
||||
type="password"
|
||||
:maxlength="20"
|
||||
placeholder="请再次输入新密码"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
<script>
|
||||
import Modal from '@/components/Modal/index.vue'
|
||||
import { updatePwd } from '@/api/home/index.js'
|
||||
import { reactive, toRefs } from '@vue/reactivity'
|
||||
export default {
|
||||
name: 'UpdateModal',
|
||||
components: { Modal },
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
'update:visible': null
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const data = reactive({
|
||||
form: {
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
configmPassword: ''
|
||||
},
|
||||
rules: {
|
||||
oldPassword: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请输入旧密码'
|
||||
},
|
||||
newPassword: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请输入新密码'
|
||||
},
|
||||
configmPassword: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请再次输入新密码'
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
/* 关闭弹窗 */
|
||||
const handleClose = () => {
|
||||
emit('update:visible', false)
|
||||
}
|
||||
return {
|
||||
...toRefs(data),
|
||||
handleClose
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleConfirm() {
|
||||
this.$refs.formRef.validate((errors) => {
|
||||
if (!errors) {
|
||||
updatePwd(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -32,9 +32,15 @@ import SideBar from './components/Sidebar/index.vue'
|
|||
import Tags from './components/Tags/index.vue'
|
||||
import { useSettingStore } from '@/store/modules/setting.js'
|
||||
import { computed } from 'vue'
|
||||
import { useUserStore } from '@/store/modules/user.js'
|
||||
const settingStore = useSettingStore()
|
||||
const menuMode = computed(() => settingStore.getMenuMode)
|
||||
const tagsMenuSetting = computed(() => settingStore.getTagsMenuSetting)
|
||||
const useUser = useUserStore()
|
||||
function getUserNow() {
|
||||
useUser.getUserInfo()
|
||||
}
|
||||
getUserNow()
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,17 +9,8 @@ export const useUserStore = defineStore('user', {
|
|||
}
|
||||
},
|
||||
getters: {
|
||||
userId() {
|
||||
return this.userInfo?.id
|
||||
},
|
||||
name() {
|
||||
return this.userInfo?.name
|
||||
},
|
||||
avatar() {
|
||||
return this.userInfo?.avatar
|
||||
},
|
||||
role() {
|
||||
return this.userInfo?.role || []
|
||||
userInfoMsg() {
|
||||
return this.userInfo
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
|
@ -27,15 +18,14 @@ export const useUserStore = defineStore('user', {
|
|||
try {
|
||||
const res = await getUser()
|
||||
if (res.code === 0) {
|
||||
const { id, name, avatar, role } = res.data
|
||||
this.userInfo = { id, name, avatar, role }
|
||||
return Promise.resolve(res.data)
|
||||
this.userInfo = res.data
|
||||
return Promise.resolve(res.msg)
|
||||
} else {
|
||||
return Promise.reject(res.message)
|
||||
return Promise.reject(res.msg)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return Promise.reject(error.message)
|
||||
return Promise.reject(error.msg)
|
||||
}
|
||||
},
|
||||
logout() {
|
||||
|
|
|
|||
|
|
@ -38,38 +38,19 @@
|
|||
<script>
|
||||
import { userLogin, userCaptcha } from '@/api/login/index.js'
|
||||
import { setToken } from '@/utils/token'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ref, toRefs, reactive, onMounted } from 'vue'
|
||||
export default {
|
||||
name: 'LoginPage',
|
||||
setup() {
|
||||
const loginForm = reactive({
|
||||
username: '',
|
||||
password: '',
|
||||
key: '',
|
||||
captcha: '',
|
||||
remember: false
|
||||
})
|
||||
onMounted(() => {
|
||||
changeCode(loginForm)
|
||||
})
|
||||
// 获取图形验证码
|
||||
const captcha = ref('')
|
||||
async function changeCode(form) {
|
||||
const params = {
|
||||
username: form.username,
|
||||
password: form.password,
|
||||
captcha: form.captcha
|
||||
}
|
||||
const captForm = await userCaptcha(params)
|
||||
captcha.value = captForm.data.captcha
|
||||
loginForm.key = captForm.data.key
|
||||
}
|
||||
|
||||
return {
|
||||
loginForm,
|
||||
captcha,
|
||||
changeCode,
|
||||
rules: reactive({
|
||||
const data = reactive({
|
||||
loginForm: {
|
||||
username: '',
|
||||
password: '',
|
||||
key: '',
|
||||
captcha: '',
|
||||
remember: false
|
||||
},
|
||||
rules: {
|
||||
username: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
|
|
@ -85,12 +66,33 @@ export default {
|
|||
trigger: ['blur', 'input'],
|
||||
message: '请输入验证码'
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
onMounted(() => {
|
||||
changeCode(data.loginForm)
|
||||
})
|
||||
// 获取图形验证码
|
||||
const captcha = ref('')
|
||||
async function changeCode(form) {
|
||||
const params = {
|
||||
username: form.username,
|
||||
password: form.password,
|
||||
captcha: form.captcha
|
||||
}
|
||||
const captForm = await userCaptcha(params)
|
||||
captcha.value = captForm.data.captcha
|
||||
data.loginForm.key = captForm.data.key
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
captcha,
|
||||
changeCode
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleLogin() {
|
||||
console.log(this.loginForm)
|
||||
userLogin(this.loginForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
// 登录成功存储token,跳转首页
|
||||
|
|
|
|||
|
|
@ -0,0 +1,187 @@
|
|||
<template>
|
||||
<Modal
|
||||
:options="getModalOptions"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
:on-close="handleClose"
|
||||
>
|
||||
<template #Context>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-placement="left"
|
||||
:rules="rules"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
>
|
||||
<n-form-item label="部门编号:" path="code">
|
||||
<n-input
|
||||
v-model:value="form.code"
|
||||
clearable
|
||||
:maxlength="20"
|
||||
placeholder="请输入部门编号"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="部门名称:" path="name">
|
||||
<n-input
|
||||
v-model:value="form.name"
|
||||
clearable
|
||||
:maxlength="20"
|
||||
placeholder="请输入部门名称"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="所属部门:" path="pid">
|
||||
<n-select
|
||||
v-model:value="form.pid"
|
||||
:options="getDeptList"
|
||||
placeholder="请选择所属部门"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="排序号" path="sort">
|
||||
<n-input-number v-model:value="form.sort" placeholder="请输入排序号" />
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="备注:"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.note"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
:maxlength="200"
|
||||
placeholder="请输入备注"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, computed, reactive, toRefs } from 'vue'
|
||||
import Modal from '@/components/Modal/index.vue'
|
||||
import { addDept, editDept } from '@/api/system/dept/index'
|
||||
export default defineComponent({
|
||||
name: 'UserModal',
|
||||
components: { Modal },
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
row: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
deptList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
'update:visible': null,
|
||||
'done': null
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const data = reactive({
|
||||
form: {
|
||||
avatar: '/images/user/20211011/20211011151447698.jpg',
|
||||
code: '',
|
||||
deptId: null,
|
||||
username: '',
|
||||
realname: '',
|
||||
password: '',
|
||||
roleIds: [],
|
||||
status: 1,
|
||||
note: ''
|
||||
|
||||
},
|
||||
deptOptions: [],
|
||||
rolesOptions: [],
|
||||
rules: {
|
||||
code: [
|
||||
{ required: true, message: '请输入部门编号', trigger: 'blur' }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '请输入部门名称', type: 'string', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, type: 'number', message: '请输入排序号', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
// 获取部门选项
|
||||
const getDeptList = computed(() => {
|
||||
const list = props.deptList.map((item) => {
|
||||
const menu = {
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}
|
||||
return menu
|
||||
})
|
||||
return list
|
||||
})
|
||||
|
||||
const getModalOptions = computed(() => {
|
||||
const row = props.row
|
||||
if (props.row.pid === 0) {
|
||||
row.pid = null
|
||||
}
|
||||
console.log('====部门计算属性触发了====', row)
|
||||
return {
|
||||
title: props.row.name ? '修改部门' : '添加部门',
|
||||
show: props.visible,
|
||||
form: Object.assign(data.form, row),
|
||||
negativeText: '取消',
|
||||
positiveText: '确认'
|
||||
}
|
||||
})
|
||||
|
||||
/* 关闭弹窗 */
|
||||
const handleClose = () => {
|
||||
emit('update:visible', false)
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
getDeptList,
|
||||
getModalOptions,
|
||||
handleClose
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 表单提交
|
||||
handleConfirm() {
|
||||
const type = this.row.name ? 'edit' : 'add'
|
||||
this.$refs.formRef.validate((errors) => {
|
||||
if (!errors) {
|
||||
if (type === 'add') {
|
||||
addDept(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
this.$emit('done')
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
} else if (type === 'edit') {
|
||||
editDept(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
this.$emit('done')
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style scoped lang='scss'>
|
||||
</style>
|
||||
|
|
@ -1,81 +1,52 @@
|
|||
<template>
|
||||
<div>
|
||||
<n-card>
|
||||
<headSearch :info="info" @search="handleSearch" />
|
||||
<data-table
|
||||
:columns="data.columns"
|
||||
:data="data.data"
|
||||
:pagination="data.pagination"
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
:pagination="false"
|
||||
data-type="tree"
|
||||
size="large"
|
||||
scroll-x="1200"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary"> 新建 </n-button>
|
||||
<n-button type="primary"> 删除 </n-button>
|
||||
<n-button type="primary" @click="handleModal"> 新建 </n-button>
|
||||
</template>
|
||||
</data-table>
|
||||
</n-card>
|
||||
</div>
|
||||
<!-- 新增、编辑弹窗 -->
|
||||
<dept-modal
|
||||
v-if="modalShow"
|
||||
v-model:visible="modalShow"
|
||||
:row="rowData"
|
||||
:dept-list="deptList"
|
||||
@done="handleSearch"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import headSearch from '@/components/Search/index.vue'
|
||||
import dataTable from '@/components/DataTable/index.vue'
|
||||
import TableAction from '@/components/DataTable/tools/Action.vue'
|
||||
import { getDeptList } from '@/api/system/index.js'
|
||||
import { h, onMounted, unref } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import {
|
||||
getDeptList,
|
||||
getDeptAll,
|
||||
deleteDept
|
||||
} from '@/api/system/dept/index.js'
|
||||
import { h, unref, toRefs, ref, reactive, onMounted } from 'vue'
|
||||
import DeptModal from './components/DeptModal.vue'
|
||||
import info from './info.js'
|
||||
import table from './table.js'
|
||||
export default {
|
||||
name: 'MenuPage',
|
||||
components: { dataTable },
|
||||
components: { dataTable, DeptModal, headSearch },
|
||||
setup() {
|
||||
const data = reactive({
|
||||
columns: [
|
||||
{
|
||||
title: '部门编号',
|
||||
key: 'code',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '部门名称',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '部门全称',
|
||||
key: 'fullname',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '部门类型',
|
||||
key: 'type',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
key: 'sort',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
key: 'note',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
key: 'updateTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
},
|
||||
...table.columns,
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
|
|
@ -89,18 +60,29 @@ export default {
|
|||
type: 'button',
|
||||
props: {
|
||||
type: 'primary',
|
||||
onClick: play.bind(null, row)
|
||||
onClick: add.bind(null, row)
|
||||
},
|
||||
auth: 'basic_list'
|
||||
},
|
||||
{
|
||||
label: '修改',
|
||||
type: 'button',
|
||||
props: {
|
||||
type: 'primary',
|
||||
onClick: play.bind(null, row)
|
||||
},
|
||||
auth: 'basic_list'
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'popconfirm',
|
||||
auth: 'basic_list'
|
||||
auth: 'basic_list',
|
||||
tip: '确定删除这条数据吗?',
|
||||
props: {
|
||||
negativeText: '取消',
|
||||
positiveText: '确认',
|
||||
onPositiveClick: deleteSingle.bind(null, row.id)
|
||||
}
|
||||
}
|
||||
],
|
||||
align: 'center'
|
||||
|
|
@ -108,31 +90,38 @@ export default {
|
|||
}
|
||||
}
|
||||
],
|
||||
data: [],
|
||||
pagination: {
|
||||
pageSize: 10
|
||||
}
|
||||
info: ref(info),
|
||||
modalShow: false,
|
||||
rowData: {
|
||||
status: 1,
|
||||
type: 0,
|
||||
hide: 0
|
||||
},
|
||||
deptList: []
|
||||
})
|
||||
|
||||
function play(row) {
|
||||
console.log(row)
|
||||
// 获取全部菜单信息
|
||||
async function getDept() {
|
||||
const list = await getDeptAll()
|
||||
data.deptList = list.data
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getDept()
|
||||
})
|
||||
/**
|
||||
* @description: 获取部门数据并做树形结构处理
|
||||
* @return {*}
|
||||
*/
|
||||
async function fetchList() {
|
||||
const params = {
|
||||
page: 1,
|
||||
limit: 10
|
||||
const params = ref({})
|
||||
|
||||
const tableRef = ref()
|
||||
|
||||
function handleSearch(data) {
|
||||
params.value = {
|
||||
...data
|
||||
}
|
||||
const res = await getDeptList(params)
|
||||
data.data = res.data
|
||||
tableRef.value.reFetch({ ...unref(params) })
|
||||
}
|
||||
const params = reactive({
|
||||
name: 'xiaoMa'
|
||||
})
|
||||
|
||||
const loadDataTable = async(res) => {
|
||||
const _params = {
|
||||
|
|
@ -142,11 +131,53 @@ export default {
|
|||
return await getDeptList(_params)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchList()
|
||||
})
|
||||
// 新增
|
||||
function handleModal() {
|
||||
data.modalShow = true
|
||||
data.rowData = {}
|
||||
}
|
||||
// 行内新增
|
||||
function add(row) {
|
||||
data.modalShow = true
|
||||
data.rowData = {}
|
||||
data.rowData.pid = row.id
|
||||
}
|
||||
|
||||
return { data, loadDataTable }
|
||||
// 编辑
|
||||
function play(row) {
|
||||
data.rowData = row
|
||||
data.modalShow = true
|
||||
}
|
||||
|
||||
// 单个删除数据
|
||||
function deleteSingle(id) {
|
||||
deleteData(id)
|
||||
}
|
||||
|
||||
// 删除方法
|
||||
function deleteData(id) {
|
||||
deleteDept(id)
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
handleSearch({})
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
tableRef,
|
||||
loadDataTable,
|
||||
handleSearch,
|
||||
handleModal,
|
||||
deleteSingle
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
const data = [
|
||||
{
|
||||
label: '部门名称',
|
||||
key: 'name',
|
||||
props: {
|
||||
placeholder: '请输入部门名称'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export default data
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
const table = {
|
||||
columns: [{
|
||||
title: '部门编号',
|
||||
key: 'code',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '部门名称',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
key: 'sort',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
key: 'updateTime',
|
||||
align: 'center',
|
||||
minWidth: 120
|
||||
}]
|
||||
}
|
||||
export default table
|
||||
|
|
@ -6,21 +6,21 @@
|
|||
:on-negative-click="handleClose"
|
||||
>
|
||||
<template #Context>
|
||||
<n-form ref="formRef" :model="menuForm" :rules="menuRules" require-mark-placement="left" :label-width="80" label-placement="left">
|
||||
<n-form ref="formRef" :model="form" :rules="rules" require-mark-placement="left" :label-width="80" label-placement="left">
|
||||
<n-grid x-gap="12" :cols="2">
|
||||
<n-gi>
|
||||
<n-form-item label="上级菜单" path="pid">
|
||||
<n-select
|
||||
v-model:value="menuForm.pid"
|
||||
placeholder="请选择上级菜单"
|
||||
v-model:value="form.pid"
|
||||
:options="getMenuList"
|
||||
placeholder="请选择上级菜单"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="菜单类型" path="type">
|
||||
<n-radio-group v-model:value="menuForm.type" name="type">
|
||||
<n-radio v-for="item in typeOptions" :key="`type_${item.key}`" :value="item.key">
|
||||
<n-radio-group v-model:value="form.type" name="type">
|
||||
<n-radio v-for="item in typeOptions" :key="item.key" :value="item.key">
|
||||
{{ item.label }}
|
||||
</n-radio>
|
||||
</n-radio-group>
|
||||
|
|
@ -28,13 +28,13 @@
|
|||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="菜单名称" path="title">
|
||||
<n-input v-model:value="menuForm.title" placeholder="请输入菜单名称" />
|
||||
<n-input v-model:value="form.title" placeholder="请输入菜单名称" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="打开方式" path="target">
|
||||
<n-radio-group v-model:value="menuForm.target" name="target">
|
||||
<n-radio v-for="item in openOptions" :key="`target_${item.key}`" :value="item.key">
|
||||
<n-radio-group v-model:value="form.target" name="target">
|
||||
<n-radio v-for="item in openOptions" :key="item.key" :value="item.key">
|
||||
{{ item.label }}
|
||||
</n-radio>
|
||||
</n-radio-group>
|
||||
|
|
@ -42,33 +42,33 @@
|
|||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="菜单图标" path="icon">
|
||||
<n-input v-model:value="menuForm.icon" placeholder="请选择菜单图标" />
|
||||
<n-input v-model:value="form.icon" :disabled="form.type === 1" placeholder="请选择菜单图标" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="权限标识" path="permission">
|
||||
<n-input v-model:value="menuForm.permission" placeholder="请输入权限标识" />
|
||||
<n-input v-model:value="form.permission" :disabled="form.type === 0" placeholder="请输入权限标识" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="路由地址" path="path">
|
||||
<n-input v-model:value="menuForm.path" placeholder="请输入路由地址" />
|
||||
<n-input v-model:value="form.path" :disabled="form.type === 1" placeholder="请输入路由地址" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="排序号" path="sort">
|
||||
<n-input v-model:value="menuForm.sort" placeholder="请输入排序号" />
|
||||
<n-input-number v-model:value="form.sort" placeholder="请输入排序号" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="组件路径" path="component">
|
||||
<n-input v-model:value="menuForm.component" placeholder="请输入组件路径" />
|
||||
<n-input v-model:value="form.component" :disabled="form.type === 1" placeholder="请输入组件路径" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="是否可见" path="hide">
|
||||
<n-radio-group v-model:value="menuForm.hide" name="hide">
|
||||
<n-radio v-for="item in visibleOptions" :key="`hide_${item.key}`" :value="item.key">
|
||||
<n-radio-group v-model:value="form.hide" name="hide">
|
||||
<n-radio v-for="item in visibleOptions" :key="item.key" :value="item.key">
|
||||
{{ item.label }}
|
||||
</n-radio>
|
||||
</n-radio-group>
|
||||
|
|
@ -76,8 +76,8 @@
|
|||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="菜单状态" path="status">
|
||||
<n-radio-group v-model:value="menuForm.status" name="status">
|
||||
<n-radio v-for="item in statusOptions" :key="`status_${item.key}`" :value="item.key">
|
||||
<n-radio-group v-model:value="form.status" name="status">
|
||||
<n-radio v-for="item in statusOptions" :key="item.key" :value="item.key">
|
||||
{{ item.label }}
|
||||
</n-radio>
|
||||
</n-radio-group>
|
||||
|
|
@ -91,9 +91,9 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, computed, reactive, toRefs, ref } from 'vue'
|
||||
import { defineComponent, computed, reactive, toRefs } from 'vue'
|
||||
import Modal from '@/components/Modal/index.vue'
|
||||
import { addMenu } from '@/api/system/menu/index.js'
|
||||
import { addMenu, editMenu } from '@/api/system/menu/index.js'
|
||||
export default defineComponent({
|
||||
name: 'MenuModal',
|
||||
components: { Modal },
|
||||
|
|
@ -114,51 +114,48 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
emits: {
|
||||
'update:visible': null
|
||||
'update:visible': null,
|
||||
'done': null
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const data = reactive({
|
||||
menuForm: {
|
||||
pid: null,
|
||||
type: '0',
|
||||
form: {
|
||||
title: '',
|
||||
target: '0',
|
||||
icon: '',
|
||||
permission: '',
|
||||
path: '',
|
||||
sort: '',
|
||||
component: '',
|
||||
hide: '0',
|
||||
status: '1'
|
||||
hide: 0,
|
||||
status: 1
|
||||
},
|
||||
menuRules: {
|
||||
title: {
|
||||
rules: {
|
||||
title: [{
|
||||
required: true,
|
||||
message: '请输入菜单名称',
|
||||
trigger: ['blur']
|
||||
},
|
||||
sort: {
|
||||
trigger: 'blur'
|
||||
}],
|
||||
sort: [{
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请输入排序号',
|
||||
trigger: ['blur']
|
||||
}
|
||||
trigger: 'blur'
|
||||
}]
|
||||
},
|
||||
typeOptions: [
|
||||
{ key: '0', label: '菜单' },
|
||||
{ key: '1', label: '按钮' }
|
||||
{ key: 0, label: '菜单' },
|
||||
{ key: 1, label: '按钮' }
|
||||
],
|
||||
openOptions: [
|
||||
{ key: '0', label: '组件' },
|
||||
{ key: '1', label: '内链' },
|
||||
{ key: '2', label: '外链' }
|
||||
{ key: '1', label: '内部' },
|
||||
{ key: '2', label: '外部' }
|
||||
],
|
||||
visibleOptions: [
|
||||
{ key: '0', label: '可见' },
|
||||
{ key: '1', label: '不可见' }
|
||||
{ key: 0, label: '可见' },
|
||||
{ key: 1, label: '不可见' }
|
||||
],
|
||||
statusOptions: [
|
||||
{ key: '1', label: '在用' },
|
||||
{ key: '2', label: '停用' }
|
||||
{ key: 1, label: '在用' },
|
||||
{ key: 2, label: '停用' }
|
||||
]
|
||||
})
|
||||
|
||||
|
|
@ -166,7 +163,7 @@ export default defineComponent({
|
|||
const list = props.menuList.map((item) => {
|
||||
const menu = {
|
||||
label: item.title,
|
||||
value: item.pid
|
||||
value: item.id
|
||||
}
|
||||
return menu
|
||||
})
|
||||
|
|
@ -174,10 +171,15 @@ export default defineComponent({
|
|||
})
|
||||
|
||||
const getModalOptions = computed(() => {
|
||||
const row = props.data
|
||||
if (props.data.pid === 0) {
|
||||
row.pid = null
|
||||
}
|
||||
console.log('菜单页面计算属性触发:', row)
|
||||
return {
|
||||
title: props.data.title ? '修改菜单' : '添加菜单',
|
||||
show: props.visible,
|
||||
title: props.data ? '修改菜单' : '新建菜单',
|
||||
width: 700,
|
||||
form: Object.assign(data.form, row),
|
||||
negativeText: '取消',
|
||||
positiveText: '确认'
|
||||
}
|
||||
|
|
@ -187,31 +189,47 @@ export default defineComponent({
|
|||
const handleClose = () => {
|
||||
emit('update:visible', false)
|
||||
}
|
||||
const formRef = ref()
|
||||
const handleConfirm = () => {
|
||||
formRef.value?.validate((errors) => {
|
||||
if (!errors) {
|
||||
const params = {
|
||||
...data.menuForm
|
||||
}
|
||||
addMenu(params)
|
||||
.then(res => {
|
||||
handleClose()
|
||||
})
|
||||
} else {
|
||||
$message.error('清先完成校验')
|
||||
}
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
formRef,
|
||||
getMenuList,
|
||||
getModalOptions,
|
||||
handleClose,
|
||||
handleConfirm
|
||||
handleClose
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 表单提交
|
||||
handleConfirm() {
|
||||
const type = this.data.title ? 'edit' : 'add'
|
||||
this.$refs.formRef.validate((errors) => {
|
||||
if (!errors) {
|
||||
if (type === 'add') {
|
||||
addMenu(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
this.$emit('done')
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
} else if (type === 'edit') {
|
||||
editMenu(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
this.$emit('done')
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
$message.error('请完善必填信息')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,92 +1,46 @@
|
|||
<template>
|
||||
<div>
|
||||
<n-card>
|
||||
<data-table :columns="data.columns" :pagination="false" :data="data.data" size="large" @fetch-success="getFechData">
|
||||
<headSearch :info="info" @search="handleSearch" />
|
||||
<data-table
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:pagination="false"
|
||||
data-type="tree"
|
||||
:request="loadDataTable"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary" @click="handlleRoleAdd">
|
||||
添加菜单
|
||||
</n-button>
|
||||
<n-button type="primary" @click="handleModal"> 添加菜单 </n-button>
|
||||
</template>
|
||||
</data-table>
|
||||
</n-card>
|
||||
</div>
|
||||
|
||||
<RoleModal v-model:visible="data.modalShow" :data="data.selectRow" :menu-list="data.data" />
|
||||
<MenuModal
|
||||
v-if="modalShow"
|
||||
v-model:visible="modalShow"
|
||||
:data="rowData"
|
||||
:menu-list="menuList"
|
||||
@done="handleSearch"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import headSearch from '@/components/Search/index.vue'
|
||||
import dataTable from '@/components/DataTable/index.vue'
|
||||
import RoleModal from './components/MenuModal.vue'
|
||||
import MenuModal from './components/MenuModal.vue'
|
||||
import Action from '@/components/DataTable/tools/Action.vue'
|
||||
import { getMenuList } from '@/api/system/index.js'
|
||||
import { h, onMounted } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import { getMenu, getMenuList, deleteMenu } from '@/api/system/menu/index.js'
|
||||
import { h, ref, unref, reactive, toRefs, onMounted } from 'vue'
|
||||
import info from './info.js'
|
||||
import table from './table.js'
|
||||
export default {
|
||||
name: 'MenuPage',
|
||||
components: { dataTable, RoleModal },
|
||||
components: { dataTable, MenuModal, headSearch },
|
||||
setup() {
|
||||
const data = reactive({
|
||||
columns: [
|
||||
{
|
||||
title: '菜单标题',
|
||||
key: 'title',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '菜单类型',
|
||||
key: 'type',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '请求方式',
|
||||
key: 'method',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '路由地址',
|
||||
key: 'path',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '组件路径',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '权限标识',
|
||||
key: 'permission',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
key: 'sort',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '可见',
|
||||
key: 'hide',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
},
|
||||
...table.columns,
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
|
|
@ -100,18 +54,29 @@ export default {
|
|||
type: 'button',
|
||||
props: {
|
||||
type: 'primary',
|
||||
onClick: play.bind(null, row)
|
||||
onClick: add.bind(null, row)
|
||||
},
|
||||
auth: 'basic_list'
|
||||
},
|
||||
{
|
||||
label: '修改',
|
||||
type: 'button',
|
||||
props: {
|
||||
type: 'primary',
|
||||
onClick: play.bind(null, row)
|
||||
},
|
||||
auth: 'basic_list'
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'popconfirm',
|
||||
auth: 'basic_list'
|
||||
auth: 'basic_list',
|
||||
tip: '确定删除这条数据吗?',
|
||||
props: {
|
||||
negativeText: '取消',
|
||||
positiveText: '确认',
|
||||
onPositiveClick: deleteSingle.bind(null, row.id)
|
||||
}
|
||||
}
|
||||
],
|
||||
align: 'center'
|
||||
|
|
@ -119,48 +84,94 @@ export default {
|
|||
}
|
||||
}
|
||||
],
|
||||
data: [],
|
||||
info: ref(info),
|
||||
modalShow: false,
|
||||
selectRow: null
|
||||
menuList: [],
|
||||
rowData: {
|
||||
status: 1,
|
||||
type: 0,
|
||||
hide: 0
|
||||
}
|
||||
})
|
||||
|
||||
function play(row) {
|
||||
console.log(row)
|
||||
// 获取全部菜单信息
|
||||
async function getMenuAll() {
|
||||
const list = await getMenu()
|
||||
data.menuList = list.data
|
||||
}
|
||||
onMounted(() => {
|
||||
getMenuAll()
|
||||
})
|
||||
|
||||
/**
|
||||
* @description: 获取菜单数据
|
||||
* @return {*}
|
||||
*/
|
||||
async function fetchList() {
|
||||
const res = await getMenuList()
|
||||
data.data = res.data
|
||||
const params = ref({})
|
||||
const tableRef = ref()
|
||||
|
||||
function handleSearch(data) {
|
||||
params.value = {
|
||||
...data
|
||||
}
|
||||
tableRef.value.reFetch({ ...unref(params) })
|
||||
}
|
||||
function handlleRoleAdd() {
|
||||
|
||||
const loadDataTable = async(res) => {
|
||||
const _params = {
|
||||
...unref(params),
|
||||
...res
|
||||
}
|
||||
return await getMenuList(_params)
|
||||
}
|
||||
|
||||
// 打开新增弹框
|
||||
function handleModal() {
|
||||
data.modalShow = true
|
||||
data.rowData = {}
|
||||
}
|
||||
// 行内新增
|
||||
function add(row) {
|
||||
data.modalShow = true
|
||||
data.rowData = {}
|
||||
data.rowData.pid = row.id
|
||||
}
|
||||
// 编辑
|
||||
function play(row) {
|
||||
data.rowData = row
|
||||
data.modalShow = true
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 获取表单数据
|
||||
* @param {*} data
|
||||
* @return {*}
|
||||
*/
|
||||
function getFechData(data) {
|
||||
|
||||
// 单个删除数据
|
||||
function deleteSingle(id) {
|
||||
deleteData(id)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchList()
|
||||
})
|
||||
// 删除方法
|
||||
function deleteData(id) {
|
||||
deleteMenu(id)
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
handleSearch({})
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
data,
|
||||
handlleRoleAdd,
|
||||
getFechData
|
||||
...toRefs(data),
|
||||
tableRef,
|
||||
loadDataTable,
|
||||
handleSearch,
|
||||
handleModal,
|
||||
deleteSingle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang='scss'>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
const data = [
|
||||
{
|
||||
label: '菜单名称',
|
||||
key: 'title',
|
||||
props: {
|
||||
placeholder: '请输入菜单名称'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export default data
|
||||
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
import { h } from 'vue'
|
||||
import TableTags from '@/components/DataTable/tools/Tags.vue'
|
||||
const table = {
|
||||
columns: [
|
||||
{
|
||||
title: '菜单标题',
|
||||
key: 'title',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '菜单类型',
|
||||
key: 'type',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(TableTags, {
|
||||
data: row.type,
|
||||
filters: [
|
||||
{
|
||||
key: 0,
|
||||
label: '菜单'
|
||||
},
|
||||
{
|
||||
key: 1,
|
||||
label: '节点'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '路由地址',
|
||||
key: 'path',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '组件路径',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(TableTags, {
|
||||
data: row.status,
|
||||
filters: [
|
||||
{
|
||||
key: 1,
|
||||
label: '在用'
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
label: '停用'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
key: 'sort',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '是否可见',
|
||||
key: 'hide',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(TableTags, {
|
||||
data: row.hide,
|
||||
filters: [
|
||||
{
|
||||
key: 1,
|
||||
label: '可见'
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
label: '不可见'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default table
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<Modal
|
||||
:options="getModalOptions"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
:on-close="handleClose"
|
||||
>
|
||||
<template #Context>
|
||||
<n-tree
|
||||
block-line
|
||||
cascade
|
||||
checkable
|
||||
:data="allTreeData"
|
||||
key-field="id"
|
||||
label-field="title"
|
||||
:default-expand-all="true"
|
||||
:default-checked-keys="checkedTreeData"
|
||||
@update:checked-keys="handleCheckTree"
|
||||
/>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
<script>
|
||||
import { defineComponent, computed, onBeforeMount, reactive, toRefs } from 'vue'
|
||||
import { getRolePermission, savePermission } from '@/api/system/role/index'
|
||||
import Modal from '@/components/Modal/index.vue'
|
||||
import { toTreeData } from '@/utils/handleData.js'
|
||||
export default defineComponent({
|
||||
name: 'ConfigModal',
|
||||
components: { Modal },
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
row: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
'update:visible': null,
|
||||
'done': null
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const data = reactive({
|
||||
menuIds: [],
|
||||
checkedTreeData: [],
|
||||
allTreeData: []
|
||||
})
|
||||
const getModalOptions = computed(() => {
|
||||
return {
|
||||
title: '权限分配',
|
||||
show: props.visible,
|
||||
negativeText: '取消',
|
||||
positiveText: '确认'
|
||||
}
|
||||
})
|
||||
onBeforeMount(() => {
|
||||
getMenuByRoleId()
|
||||
})
|
||||
|
||||
// 获取当前角色的权限菜单列表
|
||||
async function getMenuByRoleId() {
|
||||
const res = await getRolePermission(props.row.id)
|
||||
data.allTreeData = toTreeData(res.data, 'id', 'pid', 'children')
|
||||
const checkedArr = res.data
|
||||
if (checkedArr.length) {
|
||||
checkedArr.forEach((item) => {
|
||||
if (item.checked) {
|
||||
data.checkedTreeData.push(item.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
data.menuIds = data.checkedTreeData
|
||||
}
|
||||
|
||||
// 勾选节点
|
||||
function handleCheckTree(keys) {
|
||||
data.menuIds = keys
|
||||
}
|
||||
|
||||
/* 关闭弹窗 */
|
||||
const handleClose = () => {
|
||||
emit('update:visible', false)
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
getModalOptions,
|
||||
handleClose,
|
||||
handleCheckTree
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 提交
|
||||
handleConfirm() {
|
||||
console.log(this.menuIds, this.checkedTreeData)
|
||||
savePermission({ roleId: this.row.id, menuIds: this.menuIds }).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
this.$emit('done')
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
<template>
|
||||
<Modal
|
||||
:options="getModalOptions"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
:on-close="handleClose"
|
||||
>
|
||||
<template #Context>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-placement="left"
|
||||
:rules="rules"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
>
|
||||
<n-form-item label="角色编号:" path="code">
|
||||
<n-input
|
||||
v-model:value="form.code"
|
||||
clearable
|
||||
:maxlength="20"
|
||||
placeholder="请输入角色编号"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="角色名称:" path="name">
|
||||
<n-input
|
||||
v-model:value="form.name"
|
||||
clearable
|
||||
:maxlength="20"
|
||||
placeholder="请输入角色名称"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group
|
||||
v-model:value="form.status"
|
||||
>
|
||||
<n-radio :value="1">正常</n-radio>
|
||||
<n-radio :value="2">禁用</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="备注:"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.note"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
:maxlength="200"
|
||||
placeholder="请输入备注"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, computed, reactive, toRefs } from 'vue'
|
||||
import Modal from '@/components/Modal/index.vue'
|
||||
import { addRole, editRole } from '@/api/system/role/index'
|
||||
export default defineComponent({
|
||||
name: 'RoleModal',
|
||||
components: { Modal },
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
row: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
'update:visible': null,
|
||||
'done': null
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const data = reactive({
|
||||
form: {
|
||||
code: '',
|
||||
name: '',
|
||||
status: 1,
|
||||
note: ''
|
||||
},
|
||||
rules: {
|
||||
code: [
|
||||
{ required: true, message: '请输入角色编号', trigger: 'blur' }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '请输入角色名称', type: 'string', trigger: 'blur' }
|
||||
],
|
||||
status: [
|
||||
{ required: true, message: '请选择状态', type: 'number', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
const getModalOptions = computed(() => {
|
||||
return {
|
||||
title: Object.keys(props.row).length === 0 ? '添加角色' : '编辑角色',
|
||||
show: props.visible,
|
||||
form: Object.assign(data.form, props.row),
|
||||
negativeText: '取消',
|
||||
positiveText: '确认'
|
||||
}
|
||||
})
|
||||
|
||||
/* 关闭弹窗 */
|
||||
const handleClose = () => {
|
||||
emit('update:visible', false)
|
||||
}
|
||||
|
||||
return {
|
||||
getModalOptions,
|
||||
handleClose,
|
||||
...toRefs(data),
|
||||
rules: reactive({
|
||||
code: [
|
||||
{ required: true, message: '请输入角色编号', trigger: 'blur' }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '请输入角色名称', type: 'string', trigger: 'blur' }
|
||||
],
|
||||
status: [
|
||||
{ required: true, message: '请选择状态', type: 'number', trigger: 'blur' }
|
||||
]
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 表单提交
|
||||
handleConfirm() {
|
||||
const type = Object.keys(this.row).length === 0 ? 'add' : 'edit'
|
||||
this.$refs.formRef.validate((errors) => {
|
||||
if (!errors) {
|
||||
if (type === 'add') {
|
||||
addRole(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
this.$emit('done')
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
} else if (type === 'edit') {
|
||||
editRole(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
this.$emit('done')
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style scoped lang='scss'>
|
||||
</style>
|
||||
|
|
@ -1,45 +1,86 @@
|
|||
<template>
|
||||
<div>
|
||||
<n-card>
|
||||
<headSearch :info="data.info" @search="handleSearch" />
|
||||
|
||||
<headSearch :info="info" @search="handleSearch" />
|
||||
<data-table
|
||||
ref="tableRef"
|
||||
:columns="data.columns"
|
||||
:columns="columns"
|
||||
:row-key="(row) => row.id"
|
||||
:request="loadDataTable"
|
||||
size="large"
|
||||
scroll-x="1200"
|
||||
@update:checked-row-keys="handleCheck"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary">
|
||||
新建
|
||||
</n-button>
|
||||
<n-button type="primary">
|
||||
删除
|
||||
</n-button>
|
||||
<n-button type="primary" @click="handleModal"> 新建 </n-button>
|
||||
<n-popconfirm
|
||||
negative-text="取消"
|
||||
positive-text="确认"
|
||||
@positive-click="deleteComplex"
|
||||
>
|
||||
<template #trigger>
|
||||
<n-button type="primary">删除</n-button>
|
||||
</template>
|
||||
确定删除选中的数据吗?
|
||||
</n-popconfirm>
|
||||
</template>
|
||||
</data-table>
|
||||
</n-card>
|
||||
</div>
|
||||
<!-- 新增、编辑弹窗 -->
|
||||
<role-modal
|
||||
v-if="modalShow"
|
||||
v-model:visible="modalShow"
|
||||
:row="rowData"
|
||||
@done="handleSearch"
|
||||
/>
|
||||
<!-- 分配权限 -->
|
||||
<config-modal
|
||||
v-if="configModalShow"
|
||||
v-model:visible="configModalShow"
|
||||
:row="rowData"
|
||||
@done="handleSearch"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import headSearch from '@/components/Search/index.vue'
|
||||
import dataTable from '@/components/DataTable/index.vue'
|
||||
import TableAction from '@/components/DataTable/tools/Action.vue'
|
||||
import { getRoleList } from '@/api/system/role/index'
|
||||
import { h, ref, unref } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import TableSwitch from '@/components/DataTable/tools/Switch.vue'
|
||||
import {
|
||||
getRoleList,
|
||||
deleteRole,
|
||||
setRoleStatus
|
||||
} from '@/api/system/role/index'
|
||||
import { h, ref, unref, toRefs, reactive } from 'vue'
|
||||
import table from './table.js'
|
||||
import info from './info.js'
|
||||
import RoleModal from './components/RoleModal.vue'
|
||||
import ConfigModal from './components/ConfigModal.vue'
|
||||
|
||||
export default {
|
||||
name: 'MenuPage',
|
||||
components: { headSearch, dataTable },
|
||||
components: { headSearch, dataTable, RoleModal, ConfigModal },
|
||||
setup() {
|
||||
const data = reactive({
|
||||
columns: [
|
||||
...table.columns,
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(TableSwitch, {
|
||||
data: { id: row.id, status: row.status },
|
||||
rowKey: 'status',
|
||||
checkedValue: 1,
|
||||
uncheckedValue: 2,
|
||||
onChange: setStatus.bind(row)
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
|
|
@ -49,7 +90,7 @@ export default {
|
|||
return h(TableAction, {
|
||||
actions: [
|
||||
{
|
||||
label: '添加',
|
||||
label: '修改',
|
||||
type: 'button',
|
||||
props: {
|
||||
type: 'primary',
|
||||
|
|
@ -58,13 +99,25 @@ export default {
|
|||
auth: 'basic_list'
|
||||
},
|
||||
{
|
||||
label: '修改',
|
||||
label: '分配权限',
|
||||
type: 'button',
|
||||
props: {
|
||||
type: 'primary',
|
||||
ghost: true,
|
||||
onClick: configure.bind(null, row)
|
||||
},
|
||||
auth: 'basic_list'
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'popconfirm',
|
||||
auth: 'basic_list'
|
||||
auth: 'basic_list',
|
||||
tip: '确定删除这条数据吗?',
|
||||
props: {
|
||||
negativeText: '取消',
|
||||
positiveText: '确认',
|
||||
onPositiveClick: deleteSingle.bind(null, row.id)
|
||||
}
|
||||
}
|
||||
],
|
||||
align: 'center'
|
||||
|
|
@ -72,22 +125,29 @@ export default {
|
|||
}
|
||||
}
|
||||
],
|
||||
info: ref(info)
|
||||
info: ref(info),
|
||||
modalShow: false,
|
||||
configModalShow: false,
|
||||
rowData: {}
|
||||
})
|
||||
|
||||
// 编辑
|
||||
function play(row) {
|
||||
console.log(row)
|
||||
data.rowData = row
|
||||
data.modalShow = true
|
||||
}
|
||||
|
||||
// 配置权限
|
||||
function configure(row) {
|
||||
data.rowData = row
|
||||
data.configModalShow = true
|
||||
}
|
||||
|
||||
const params = ref({})
|
||||
|
||||
const tableRef = ref()
|
||||
|
||||
function handleSearch(data) {
|
||||
params.value = {
|
||||
...data
|
||||
}
|
||||
console.log(params.value)
|
||||
tableRef.value.reFetch({ ...unref(params) })
|
||||
}
|
||||
|
||||
|
|
@ -99,13 +159,81 @@ export default {
|
|||
return await getRoleList(_params)
|
||||
}
|
||||
|
||||
return { data, tableRef, loadDataTable, handleSearch }
|
||||
// 新增用户
|
||||
function handleModal() {
|
||||
data.rowData = {}
|
||||
data.modalShow = true
|
||||
}
|
||||
|
||||
// 选择表格数据
|
||||
const selectedIds = ref([])
|
||||
function handleCheck(rowKeys) {
|
||||
selectedIds.value = rowKeys
|
||||
}
|
||||
// 批量删除
|
||||
function deleteComplex() {
|
||||
if (selectedIds.value.length) {
|
||||
deleteData(selectedIds.value)
|
||||
} else {
|
||||
$message.warning('请至少选中一条数据')
|
||||
}
|
||||
}
|
||||
// 单个删除数据
|
||||
function deleteSingle(id) {
|
||||
deleteData([id])
|
||||
}
|
||||
|
||||
// 删除接口
|
||||
function deleteData(data) {
|
||||
deleteRole(data)
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
handleSearch()
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
// 设置状态
|
||||
function setStatus(row) {
|
||||
console.log(row)
|
||||
setRoleStatus({ id: row.data.id, status: row.value })
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
handleSearch()
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
tableRef,
|
||||
loadDataTable,
|
||||
handleSearch,
|
||||
handleModal,
|
||||
handleCheck,
|
||||
selectedIds,
|
||||
deleteSingle,
|
||||
deleteComplex,
|
||||
deleteData,
|
||||
setStatus
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang='scss'>
|
||||
.n-button+.n-button{
|
||||
margin-left: 10px;
|
||||
.n-button + .n-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -6,24 +6,6 @@ const data = [
|
|||
placeholder: '请输入角色名称'
|
||||
}
|
||||
}
|
||||
// {
|
||||
// label: '角色类型',
|
||||
// type: 'select',
|
||||
// key: 'op',
|
||||
// props: {
|
||||
// options: [{
|
||||
// label: 11, value: 1
|
||||
// }]
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '角色类型',
|
||||
// type: 'date',
|
||||
// key: 'date',
|
||||
// props: {
|
||||
// type: 'date'
|
||||
// }
|
||||
// }
|
||||
]
|
||||
|
||||
export default data
|
||||
|
|
|
|||
|
|
@ -1,71 +1,28 @@
|
|||
import TableImage from '@/components/DataTable/tools/Image.vue'
|
||||
import { h } from 'vue'
|
||||
|
||||
const data = {
|
||||
columns: [
|
||||
{ type: 'selection' },
|
||||
{
|
||||
title: '用户编号',
|
||||
title: '角色编号',
|
||||
key: 'code',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
key: 'avatar',
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(TableImage, {
|
||||
images: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
src: row.avatar
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '用户账号',
|
||||
key: 'username',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
key: 'realname',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '用户类型',
|
||||
key: 'type',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '角色',
|
||||
key: 'roles',
|
||||
align: 'center'
|
||||
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
key: 'deptName',
|
||||
title: '角色名称',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
Minwidth: 160
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
key: 'updateTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
Minwidth: 160
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,18 @@
|
|||
<template>
|
||||
<Modal :options="getModalOptions" @on-close="handleClose">
|
||||
<Modal
|
||||
:options="getModalOptions"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
:on-close="handleClose"
|
||||
>
|
||||
<template #Context>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-placement="left"
|
||||
:rules="rules"
|
||||
:on-positive-click="handleConfirm"
|
||||
:on-negative-click="handleClose"
|
||||
>
|
||||
<n-form-item
|
||||
label="头像:"
|
||||
|
|
@ -16,22 +23,7 @@
|
|||
max:1,
|
||||
action: '/upload/uploadImage/demo',
|
||||
}"
|
||||
size="2"
|
||||
/>
|
||||
<!-- <n-upload
|
||||
action="https://www.mocky.io/v2/5e4bafc63100007100d8b70f"
|
||||
:default-file-list="previewFileList"
|
||||
list-type="image-card"
|
||||
@preview="handlePreview"
|
||||
/>
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
preset="card"
|
||||
style="width: 600px"
|
||||
title="头像"
|
||||
>
|
||||
<img :src="form.avatar" style="width: 100%">
|
||||
</n-modal> -->
|
||||
</n-form-item>
|
||||
<n-form-item label="用户编号:" path="code">
|
||||
<n-input
|
||||
|
|
@ -41,13 +33,6 @@
|
|||
placeholder="请输入用户编号"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="所属部门:" path="deptId">
|
||||
<n-select
|
||||
v-model:value="form.deptId"
|
||||
:options="deptOptions"
|
||||
placeholder="请选择所属部门"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="用户账号:" path="username">
|
||||
<n-input
|
||||
v-model:value="form.username"
|
||||
|
|
@ -56,43 +41,6 @@
|
|||
placeholder="请输入用户账号"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="角色:" path="roleIds">
|
||||
<n-select
|
||||
v-model:value="form.roleIds"
|
||||
clearable
|
||||
:multiple="true"
|
||||
:options="rolesOptions"
|
||||
placeholder="请选择角色"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
v-if="form.type==2"
|
||||
label="驾照类型:"
|
||||
path="driverType"
|
||||
>
|
||||
<n-select
|
||||
v-model:value="form.driverType"
|
||||
clearable
|
||||
:options="[1, 2]"
|
||||
placeholder="请选择驾照类型"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="用户姓名:" path="realname">
|
||||
<n-input
|
||||
v-model:value="form.realname"
|
||||
clearable
|
||||
:maxlength="20"
|
||||
placeholder="请输入用户姓名"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group
|
||||
v-model:value="form.status"
|
||||
>
|
||||
<n-radio :value="1">正常</n-radio>
|
||||
<n-radio :value="2">禁用</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="登录密码:"
|
||||
path="password"
|
||||
|
|
@ -104,30 +52,40 @@
|
|||
placeholder="请输入登录密码"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="用户类型" path="type">
|
||||
<n-form-item label="用户姓名:" path="realname">
|
||||
<n-input
|
||||
v-model:value="form.realname"
|
||||
clearable
|
||||
:maxlength="20"
|
||||
placeholder="请输入用户姓名"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="所属部门:" path="deptId">
|
||||
<n-select
|
||||
v-model:value="form.deptId"
|
||||
:options="deptOptions"
|
||||
placeholder="请选择所属部门"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="角色:" path="roleIds">
|
||||
<n-select
|
||||
v-model:value="form.roleIds"
|
||||
clearable
|
||||
:multiple="true"
|
||||
:options="rolesOptions"
|
||||
placeholder="请选择角色"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group
|
||||
v-model:value="form.type"
|
||||
v-model:value="form.status"
|
||||
>
|
||||
<n-radio :value="1">普通用户</n-radio>
|
||||
<n-radio :value="2">飞手</n-radio>
|
||||
<n-radio :value="1">正常</n-radio>
|
||||
<n-radio :value="2">禁用</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
v-if="form.type==2"
|
||||
label="驾照编号:"
|
||||
path="driverCode"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.driverCode"
|
||||
clearable
|
||||
:maxlength="20"
|
||||
placeholder="请输入驾照编号"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="备注:"
|
||||
:label-col="{sm: {span: 3}, xs: {span: 6}}"
|
||||
:wrapper-col="{sm: {span: 21}, xs: {span: 18}}"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.note"
|
||||
|
|
@ -143,11 +101,12 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, computed, onMounted, reactive } from 'vue'
|
||||
import { defineComponent, computed, onMounted, reactive, toRefs } from 'vue'
|
||||
import Modal from '@/components/Modal/index.vue'
|
||||
import uploadImage from '@/components/ImgUpload/index.vue'
|
||||
import { getDeptAll } from '@/api/system/dept/index'
|
||||
import { getRoleAll } from '@/api/system/role/index'
|
||||
import { addUser, editUser } from '@/api/system/user/index'
|
||||
import { dataToSelect } from '@/utils/handleData.js'
|
||||
export default defineComponent({
|
||||
name: 'UserModal',
|
||||
|
|
@ -160,22 +119,59 @@ export default defineComponent({
|
|||
row: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '添加'
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
'update:visible': null,
|
||||
onClose: null,
|
||||
done: null
|
||||
'done': null
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const data = reactive({
|
||||
form: {
|
||||
avatar: '/images/user/20211011/20211011151447698.jpg',
|
||||
code: '',
|
||||
deptId: null,
|
||||
username: '',
|
||||
realname: '',
|
||||
password: '',
|
||||
roleIds: [],
|
||||
status: 1,
|
||||
note: ''
|
||||
|
||||
},
|
||||
deptOptions: [],
|
||||
rolesOptions: [],
|
||||
rules: {
|
||||
avatar: [
|
||||
{ required: true, message: '请选择头像', type: 'string', trigger: 'blur' }
|
||||
],
|
||||
code: [
|
||||
{ required: true, message: '请输入编号', trigger: 'blur' }
|
||||
],
|
||||
realname: [
|
||||
{ required: true, message: '请输入用户姓名', type: 'string', trigger: 'blur' }
|
||||
],
|
||||
deptId: [
|
||||
{ required: true, message: '请选择部门', type: 'number', trigger: 'blur' }
|
||||
],
|
||||
status: [
|
||||
{ required: true, message: '请选择状态', type: 'number', trigger: 'blur' }
|
||||
],
|
||||
roleIds: [
|
||||
{ required: true, message: '请选择角色', type: 'array', trigger: 'blur' }
|
||||
],
|
||||
username: [
|
||||
{ required: true, message: '请输入用户账号', type: 'string', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
const getModalOptions = computed(() => {
|
||||
return {
|
||||
title: props.title,
|
||||
show: props.visible
|
||||
title: Object.keys(props.row).length === 0 ? '添加用户' : '编辑用户',
|
||||
show: props.visible,
|
||||
form: Object.assign(data.form, props.row),
|
||||
negativeText: '取消',
|
||||
positiveText: '确认'
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -184,35 +180,16 @@ export default defineComponent({
|
|||
emit('update:visible', false)
|
||||
}
|
||||
|
||||
const form = reactive({
|
||||
avatar: '',
|
||||
code: '',
|
||||
deptId: null,
|
||||
username: '',
|
||||
realname: '',
|
||||
password: '',
|
||||
roleIds: [],
|
||||
driverType: null,
|
||||
driverCode: '',
|
||||
type: 1,
|
||||
status: 1,
|
||||
note: ''
|
||||
|
||||
})
|
||||
|
||||
// 获取部门列表
|
||||
let deptOptions = reactive([])
|
||||
async function getDeptOptions() {
|
||||
const res = await getDeptAll()
|
||||
deptOptions = dataToSelect(res.data, { label: 'name', value: 'id' })
|
||||
console.log('部门选项:', deptOptions)
|
||||
data.deptOptions = dataToSelect(res.data, { label: 'name', value: 'id' })
|
||||
}
|
||||
|
||||
// 获取角色列表
|
||||
let rolesOptions = reactive([])
|
||||
async function getRoleOptions() {
|
||||
const res = await getRoleAll()
|
||||
rolesOptions = dataToSelect(res.data, { label: 'name', value: 'id' })
|
||||
data.rolesOptions = dataToSelect(res.data, { label: 'name', value: 'id' })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
@ -221,38 +198,52 @@ export default defineComponent({
|
|||
})
|
||||
|
||||
// 上传文件
|
||||
const handleUpload = ({ file, event }) => {
|
||||
console.log(event)
|
||||
form.avatar = file.url
|
||||
const handleUpload = ({ file }) => {
|
||||
console.log(file)
|
||||
// data.form.avatar = file.url
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
getModalOptions,
|
||||
handleClose,
|
||||
form,
|
||||
rules: reactive({
|
||||
avatar: {
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: '请上传头像'
|
||||
},
|
||||
code: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请输入用户编号'
|
||||
},
|
||||
deptId: {
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: '请选择部门'
|
||||
}
|
||||
}),
|
||||
handleUpload,
|
||||
deptOptions,
|
||||
rolesOptions
|
||||
handleUpload
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 表单提交
|
||||
handleConfirm() {
|
||||
const type = Object.keys(this.row).length === 0 ? 'add' : 'edit'
|
||||
this.$refs.formRef.validate((errors) => {
|
||||
if (!errors) {
|
||||
if (type === 'add') {
|
||||
addUser(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
this.$emit('done')
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
} else if (type === 'edit') {
|
||||
editUser(this.form).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.handleClose()
|
||||
this.$emit('done')
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
$message.error('请完善必填信息')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,84 +1,57 @@
|
|||
<template>
|
||||
<div>
|
||||
<n-card>
|
||||
<headSearch :info="info" @search="handleSearch" />
|
||||
<data-table
|
||||
:columns="data.columns"
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:row-key="(row) => row.id"
|
||||
:request="loadDataTable"
|
||||
size="large"
|
||||
@update:checked-row-keys="handleCheck"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary" @click="handleUser"> 新建 </n-button>
|
||||
<!-- <n-button type="primary" @click="deleteUsers"> 删除 </n-button> -->
|
||||
<n-button type="primary" @click="handleModal"> 新建 </n-button>
|
||||
<n-popconfirm
|
||||
negative-text="取消"
|
||||
positive-text="确认"
|
||||
@positive-click="deleteComplex"
|
||||
>
|
||||
<template #trigger>
|
||||
<n-button type="primary"> 删除 </n-button>
|
||||
</template>
|
||||
确认要删除选中数据吗?
|
||||
</n-popconfirm>
|
||||
</template>
|
||||
</data-table>
|
||||
</n-card>
|
||||
</div>
|
||||
<!-- 新增、编辑弹窗 -->
|
||||
<user-modal v-if="data.modalShow" v-model:visible="data.modalShow" :row="rowData" :title="modalTitle" />
|
||||
<user-modal
|
||||
v-if="modalShow"
|
||||
v-model:visible="modalShow"
|
||||
:row="rowData"
|
||||
@done="handleSearch"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import headSearch from '@/components/Search/index.vue'
|
||||
import dataTable from '@/components/DataTable/index.vue'
|
||||
import TableAction from '@/components/DataTable/tools/Action.vue'
|
||||
import TableImage from '@/components/DataTable/tools/Image.vue'
|
||||
import TableTags from '@/components/DataTable/tools/Tags.vue'
|
||||
import TableSwitch from '@/components/DataTable/tools/Switch.vue'
|
||||
import { getUserList } from '@/api/system/user/index.js'
|
||||
import { h, unref, ref } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import TableAction from '@/components/DataTable/tools/Action.vue'
|
||||
import { getUserList, resetPassword, deleteUser, setUserStatus } from '@/api/system/user/index.js'
|
||||
import { h, unref, ref, toRefs, reactive } from 'vue'
|
||||
import UserModal from './components/UserModal.vue'
|
||||
import info from './info.js'
|
||||
import table from './table.js'
|
||||
export default {
|
||||
name: 'MenuPage',
|
||||
components: { dataTable, UserModal },
|
||||
components: { dataTable, UserModal, headSearch },
|
||||
setup() {
|
||||
const data = reactive({
|
||||
columns: [
|
||||
{
|
||||
title: '用户编号',
|
||||
key: 'code',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
key: 'avatar',
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(TableImage, {
|
||||
images: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
src: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQiKrYt-fEfJ4SZhF9KfLLaX9f15KV6Ve1ptA&usqp=CAU'
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '用户账号',
|
||||
key: 'username',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
key: 'realname',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '用户类型',
|
||||
key: 'type',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '角色',
|
||||
key: 'roles',
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(TableTags, {
|
||||
data: row.roles
|
||||
})
|
||||
}
|
||||
},
|
||||
...table.columns,
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
|
|
@ -86,31 +59,14 @@ export default {
|
|||
width: 100,
|
||||
render(row) {
|
||||
return h(TableSwitch, {
|
||||
data: row,
|
||||
data: { id: row.id, status: row.status },
|
||||
rowKey: 'status',
|
||||
checkedValue: 1,
|
||||
uncheckedValue: 2,
|
||||
onChange: getSwitch.bind(row)
|
||||
onChange: setStatus.bind(row)
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
key: 'deptName',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
key: 'updateTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
|
|
@ -128,10 +84,27 @@ export default {
|
|||
},
|
||||
auth: 'basic_list'
|
||||
},
|
||||
{
|
||||
label: '重置密码',
|
||||
type: 'popconfirm',
|
||||
auth: 'basic_list',
|
||||
tip: '确定要重置为123456吗?',
|
||||
props: {
|
||||
negativeText: '取消',
|
||||
positiveText: '确认',
|
||||
onPositiveClick: resetPsw.bind(null, row.id)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'popconfirm',
|
||||
auth: 'basic_list'
|
||||
auth: 'basic_list',
|
||||
tip: '确定删除这条数据吗?',
|
||||
props: {
|
||||
negativeText: '取消',
|
||||
positiveText: '确认',
|
||||
onPositiveClick: deleteSingle.bind(null, row.id)
|
||||
}
|
||||
}
|
||||
],
|
||||
align: 'center'
|
||||
|
|
@ -139,21 +112,26 @@ export default {
|
|||
}
|
||||
}
|
||||
],
|
||||
modalShow: false
|
||||
info: ref(info),
|
||||
modalShow: false,
|
||||
rowData: {}
|
||||
})
|
||||
const modalTitle = ref('添加用户')
|
||||
let rowData = reactive({})
|
||||
// 打开编辑弹窗
|
||||
function play(row) {
|
||||
rowData = row
|
||||
modalTitle.value = '编辑用户'
|
||||
console.log('编辑弹窗内容:', row)
|
||||
data.rowData = row
|
||||
data.modalShow = true
|
||||
}
|
||||
|
||||
const params = reactive({
|
||||
name: ''
|
||||
})
|
||||
const params = ref({})
|
||||
|
||||
const tableRef = ref()
|
||||
|
||||
function handleSearch(data) {
|
||||
params.value = {
|
||||
...data
|
||||
}
|
||||
tableRef.value.reFetch({ ...unref(params) })
|
||||
}
|
||||
|
||||
const loadDataTable = async(res) => {
|
||||
const _params = {
|
||||
|
|
@ -162,17 +140,89 @@ export default {
|
|||
}
|
||||
return await getUserList(_params)
|
||||
}
|
||||
function handleUser() {
|
||||
rowData = {}
|
||||
modalTitle.value = '添加用户'
|
||||
|
||||
// 新增
|
||||
function handleModal() {
|
||||
data.rowData = {}
|
||||
data.modalShow = true
|
||||
}
|
||||
|
||||
function getSwitch(row) {
|
||||
console.log(row)
|
||||
// 选择表格数据
|
||||
const selectedIds = ref([])
|
||||
function handleCheck(rowKeys) {
|
||||
selectedIds.value = rowKeys
|
||||
}
|
||||
// 批量删除
|
||||
function deleteComplex() {
|
||||
if (selectedIds.value.length) {
|
||||
deleteData(selectedIds.value)
|
||||
} else {
|
||||
$message.warning('请至少选中一条数据')
|
||||
}
|
||||
}
|
||||
// 单个删除数据
|
||||
function deleteSingle(id) {
|
||||
deleteData([id])
|
||||
}
|
||||
|
||||
return { data, loadDataTable, handleUser, rowData, modalTitle }
|
||||
// 删除用户接口
|
||||
function deleteData(data) {
|
||||
deleteUser(data).then((res) => {
|
||||
if (res.code === 0) {
|
||||
handleSearch()
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
function resetPsw(id) {
|
||||
resetPassword({ id }).then(res => {
|
||||
if (res.code === 0) {
|
||||
handleSearch()
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
// 设置状态
|
||||
function setStatus(row) {
|
||||
setUserStatus({ id: row.data.id, status: row.value }).then(res => {
|
||||
if (res.code === 0) {
|
||||
handleSearch()
|
||||
$message.success(res.msg)
|
||||
} else {
|
||||
$message.error(res.msg)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
loadDataTable,
|
||||
handleModal,
|
||||
...toRefs(data),
|
||||
tableRef,
|
||||
handleSearch,
|
||||
selectedIds,
|
||||
deleteComplex,
|
||||
handleCheck,
|
||||
deleteData,
|
||||
resetPsw,
|
||||
setStatus
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
import { getRoleAll } from '@/api/system/role/index'
|
||||
import { dataToSelect } from '@/utils/handleData.js'
|
||||
import { ref } from 'vue'
|
||||
const rolesOptions = ref([])
|
||||
const getRolesOption = async function() {
|
||||
const res = await getRoleAll()
|
||||
rolesOptions.value = dataToSelect(res.data, { label: 'name', value: 'id' })
|
||||
}
|
||||
getRolesOption()
|
||||
const data = [
|
||||
{
|
||||
label: '用户账号',
|
||||
key: 'username',
|
||||
props: {
|
||||
placeholder: '请输入用户账号'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '用户姓名',
|
||||
key: 'realname',
|
||||
props: {
|
||||
placeholder: '请输入用户姓名'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '用户角色',
|
||||
type: 'select',
|
||||
key: 'roleId',
|
||||
props: {
|
||||
placeholder: '请选择用户角色',
|
||||
options: rolesOptions
|
||||
}
|
||||
}
|
||||
// {
|
||||
// label: '角色类型',
|
||||
// type: 'date',
|
||||
// key: 'date',
|
||||
// props: {
|
||||
// type: 'date'
|
||||
// }
|
||||
// }
|
||||
]
|
||||
|
||||
export default data
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
import { h } from 'vue'
|
||||
import TableImage from '@/components/DataTable/tools/Image.vue'
|
||||
import TableTags from '@/components/DataTable/tools/Tags.vue'
|
||||
|
||||
const table = {
|
||||
columns: [
|
||||
{
|
||||
type: 'selection'
|
||||
},
|
||||
{
|
||||
title: '用户编号',
|
||||
key: 'code',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
key: 'avatar',
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(TableImage, {
|
||||
images: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
src: row.avatar
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '用户账号',
|
||||
key: 'username',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
key: 'realname',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '角色',
|
||||
key: 'roleList',
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(TableTags, {
|
||||
data: row.roleList,
|
||||
rowKey: 'name'
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
key: 'deptName',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
key: 'updateTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
}
|
||||
]
|
||||
}
|
||||
export default table
|
||||
Loading…
Reference in New Issue