合并代码冲突
This commit is contained in:
commit
f8a3e2ebde
|
|
@ -5,7 +5,7 @@ VITE_PUBLIC_PATH = '/'
|
||||||
VITE_APP_USE_MOCK = false
|
VITE_APP_USE_MOCK = false
|
||||||
|
|
||||||
# proxy
|
# proxy
|
||||||
VITE_PROXY = [["/api-dev","http://127.0.0.1:8002/api"]]
|
VITE_PROXY = [["/api-dev","http://192.168.11.11:9070/api"]]
|
||||||
|
|
||||||
# base api
|
# base api
|
||||||
VITE_APP_GLOB_BASE_API = '/api-dev'
|
VITE_APP_GLOB_BASE_API = '/api-dev'
|
||||||
|
|
@ -21,6 +21,7 @@ function deepClone(source) {
|
||||||
|
|
||||||
const menuList = []
|
const menuList = []
|
||||||
const userList = []
|
const userList = []
|
||||||
|
// const deptList = []
|
||||||
const count = 100
|
const count = 100
|
||||||
|
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
|
|
@ -48,7 +49,84 @@ for (let i = 0; i < count; i++) {
|
||||||
createTime: '@datetime',
|
createTime: '@datetime',
|
||||||
updateTime: '@datetime'
|
updateTime: '@datetime'
|
||||||
}))
|
}))
|
||||||
|
// deptList.push(Mock.mock({
|
||||||
|
// code: '',
|
||||||
|
// id: 1,
|
||||||
|
// name: '@name',
|
||||||
|
// fullname: '@cname',
|
||||||
|
// 'pid|1': [1, 2, 3, 4, 5],
|
||||||
|
// 'sort|+1': 0,
|
||||||
|
// type: 1,
|
||||||
|
// 'note|1-8': '好',
|
||||||
|
// createTime: '@datetime',
|
||||||
|
// updateTime: '@datetime'
|
||||||
|
// }))
|
||||||
}
|
}
|
||||||
|
const deptList = Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
message: '获取成功',
|
||||||
|
type: 'success',
|
||||||
|
data: [{
|
||||||
|
code: 'XH212313',
|
||||||
|
id: 1,
|
||||||
|
name: '@name',
|
||||||
|
fullname: '@cname',
|
||||||
|
pid: 0,
|
||||||
|
sort: 0,
|
||||||
|
type: 1,
|
||||||
|
'note|1-8': '好',
|
||||||
|
createTime: '@datetime',
|
||||||
|
updateTime: '@datetime'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'XH212312',
|
||||||
|
id: 2,
|
||||||
|
name: '@name',
|
||||||
|
fullname: '@cname',
|
||||||
|
pid: 1,
|
||||||
|
sort: 0,
|
||||||
|
type: 2,
|
||||||
|
'note|1-8': '好',
|
||||||
|
createTime: '@datetime',
|
||||||
|
updateTime: '@datetime'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'XH212323',
|
||||||
|
id: 3,
|
||||||
|
name: '@name',
|
||||||
|
fullname: '@cname',
|
||||||
|
pid: 2,
|
||||||
|
sort: 0,
|
||||||
|
type: 2,
|
||||||
|
'note|1-8': '好',
|
||||||
|
createTime: '@datetime',
|
||||||
|
updateTime: '@datetime'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'XH212319',
|
||||||
|
id: 4,
|
||||||
|
name: '@name',
|
||||||
|
fullname: '@cname',
|
||||||
|
pid: 0,
|
||||||
|
sort: 1,
|
||||||
|
type: 1,
|
||||||
|
'note|1-8': '好',
|
||||||
|
createTime: '@datetime',
|
||||||
|
updateTime: '@datetime'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'XH212398',
|
||||||
|
id: 5,
|
||||||
|
name: '@name',
|
||||||
|
fullname: '@cname',
|
||||||
|
pid: 0,
|
||||||
|
sort: 2,
|
||||||
|
type: 2,
|
||||||
|
'note|1-8': '好',
|
||||||
|
createTime: '@datetime',
|
||||||
|
updateTime: '@datetime'
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
|
|
@ -90,5 +168,20 @@ export default [
|
||||||
}
|
}
|
||||||
return resultSuccess(data)
|
return resultSuccess(data)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/api-mock/dept/apiIndex',
|
||||||
|
timeout: 1000,
|
||||||
|
method: 'get',
|
||||||
|
response: config => {
|
||||||
|
const { page = 1, limit = 10 } = config.query
|
||||||
|
const data = {
|
||||||
|
list: deptList,
|
||||||
|
page: Number(page),
|
||||||
|
limit: Number(limit),
|
||||||
|
total: 5
|
||||||
|
}
|
||||||
|
return resultSuccess(data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,14 @@ const asyncRoutes = [
|
||||||
meta: {
|
meta: {
|
||||||
title: '角色管理'
|
title: '角色管理'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'dept',
|
||||||
|
component: 'views/system/dept/index',
|
||||||
|
name: 'SystemDept',
|
||||||
|
meta: {
|
||||||
|
title: '部门管理'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
"@vicons/antd": "^0.10.0",
|
"@vicons/antd": "^0.10.0",
|
||||||
"@vicons/ionicons5": "^0.10.0",
|
"@vicons/ionicons5": "^0.10.0",
|
||||||
"axios": "^0.26.1",
|
"axios": "^0.26.1",
|
||||||
"dayjs": "^1.11.0",
|
"dayjs": "^1.11.2",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"pinia": "^2.0.13",
|
"pinia": "^2.0.13",
|
||||||
"vue": "^3.2.16",
|
"vue": "^3.2.16",
|
||||||
|
|
@ -3049,7 +3049,11 @@
|
||||||
"node_modules/connect/node_modules/ms": {
|
"node_modules/connect/node_modules/ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
<<<<<<< HEAD
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
|
=======
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||||
|
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/consola": {
|
"node_modules/consola": {
|
||||||
|
|
@ -3535,9 +3539,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dayjs": {
|
"node_modules/dayjs": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "1.11.3",
|
"version": "1.11.3",
|
||||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
|
||||||
"integrity": "sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A=="
|
"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": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
|
|
@ -4352,9 +4362,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/esbuild-register": {
|
"node_modules/esbuild-register": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "3.3.3",
|
"version": "3.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.3.3.tgz",
|
||||||
"integrity": "sha512-eFHOkutgIMJY5gc8LUp/7c+LLlDqzNi9T6AwCZ2WKKl3HmT+5ef3ZRyPPxDOynInML0fgaC50yszPKfPnjC0NQ==",
|
"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,
|
"dev": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"esbuild": ">=0.12 <1"
|
"esbuild": ">=0.12 <1"
|
||||||
|
|
@ -6082,7 +6098,11 @@
|
||||||
"node_modules/is-module": {
|
"node_modules/is-module": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||||
|
<<<<<<< HEAD
|
||||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
||||||
|
=======
|
||||||
|
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
|
||||||
|
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/is-number": {
|
"node_modules/is-number": {
|
||||||
|
|
@ -6232,9 +6252,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jake/node_modules/async": {
|
"node_modules/jake/node_modules/async": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "3.2.4",
|
"version": "3.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
|
||||||
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
|
"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
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/jake/node_modules/chalk": {
|
"node_modules/jake/node_modules/chalk": {
|
||||||
|
|
@ -7854,9 +7880,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pinia/node_modules/vue-demi": {
|
"node_modules/pinia/node_modules/vue-demi": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "0.13.1",
|
"version": "0.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.1.tgz",
|
||||||
"integrity": "sha512-xmkJ56koG3ptpLnpgmIzk9/4nFf4CqduSJbUM0OdPoU87NwRuZ6x49OLhjSa/fC15fV+5CbEnrxU4oyE022svg==",
|
"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,
|
"hasInstallScript": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||||
|
|
@ -13694,7 +13726,11 @@
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
<<<<<<< HEAD
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
|
=======
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||||
|
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14049,9 +14085,15 @@
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"dayjs": {
|
"dayjs": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "1.11.3",
|
"version": "1.11.3",
|
||||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
|
||||||
"integrity": "sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A=="
|
"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": {
|
"debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
|
|
@ -14603,9 +14645,15 @@
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"esbuild-register": {
|
"esbuild-register": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "3.3.3",
|
"version": "3.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.3.3.tgz",
|
||||||
"integrity": "sha512-eFHOkutgIMJY5gc8LUp/7c+LLlDqzNi9T6AwCZ2WKKl3HmT+5ef3ZRyPPxDOynInML0fgaC50yszPKfPnjC0NQ==",
|
"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,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
|
|
@ -15884,7 +15932,11 @@
|
||||||
"is-module": {
|
"is-module": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||||
|
<<<<<<< HEAD
|
||||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
||||||
|
=======
|
||||||
|
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
|
||||||
|
>>>>>>> 40d50ccf36aef63b9c0df852b2171d9185ea2c1f
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-number": {
|
"is-number": {
|
||||||
|
|
@ -15989,9 +16041,15 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async": {
|
"async": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "3.2.4",
|
"version": "3.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
|
||||||
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
|
"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
|
"dev": true
|
||||||
},
|
},
|
||||||
"chalk": {
|
"chalk": {
|
||||||
|
|
@ -17254,9 +17312,15 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vue-demi": {
|
"vue-demi": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "0.13.1",
|
"version": "0.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.1.tgz",
|
||||||
"integrity": "sha512-xmkJ56koG3ptpLnpgmIzk9/4nFf4CqduSJbUM0OdPoU87NwRuZ6x49OLhjSa/fC15fV+5CbEnrxU4oyE022svg==",
|
"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": {}
|
"requires": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
"@vicons/antd": "^0.10.0",
|
"@vicons/antd": "^0.10.0",
|
||||||
"@vicons/ionicons5": "^0.10.0",
|
"@vicons/ionicons5": "^0.10.0",
|
||||||
"axios": "^0.26.1",
|
"axios": "^0.26.1",
|
||||||
"dayjs": "^1.11.0",
|
"dayjs": "^1.11.2",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"pinia": "^2.0.13",
|
"pinia": "^2.0.13",
|
||||||
"vue": "^3.2.16",
|
"vue": "^3.2.16",
|
||||||
|
|
|
||||||
11
src/App.vue
11
src/App.vue
|
|
@ -2,16 +2,25 @@
|
||||||
<n-config-provider inline-theme-disabled :theme-overrides="themeOverrides">
|
<n-config-provider inline-theme-disabled :theme-overrides="themeOverrides">
|
||||||
<n-loading-bar-provider>
|
<n-loading-bar-provider>
|
||||||
<loading-bar />
|
<loading-bar />
|
||||||
|
<n-dialog-provider>
|
||||||
|
<dialog-content />
|
||||||
|
<n-message-provider>
|
||||||
|
<message-content />
|
||||||
|
</n-message-provider>
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<component :is="Component" />
|
<component :is="Component" />
|
||||||
</router-view>
|
</router-view>
|
||||||
|
</n-dialog-provider>
|
||||||
</n-loading-bar-provider>
|
</n-loading-bar-provider>
|
||||||
</n-config-provider>
|
</n-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import themeOverrides from '@/utils/ui/theme.js'
|
import themeOverrides from '@/utils/ui/theme.js'
|
||||||
import LoadingBar from '@/components/LoadingBar/index.vue'
|
import loadingBar from '@/components/LoadingBar/index.vue'
|
||||||
|
import messageContent from '@/components/Message/index.vue'
|
||||||
|
import dialogContent from '@/components/Dialog/index.vue'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,20 @@ export const login = (data) => {
|
||||||
return request({
|
return request({
|
||||||
url: '/auth/login',
|
url: '/auth/login',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data,
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const refreshToken = () => {
|
export const refreshToken = () => {
|
||||||
return request({
|
return request({
|
||||||
url: '/auth/refreshToken',
|
url: '/auth/refreshToken',
|
||||||
method: 'post',
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMenu() {
|
||||||
|
return request({
|
||||||
|
url: '/index/getMenuList',
|
||||||
|
method: 'GET'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
import { defAxios as request } from '@/utils/http'
|
import { defAxios as request } from '@/utils/http'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录接口
|
||||||
|
* @param {Object} 用户名以及密码
|
||||||
|
* @returns 返回token信息
|
||||||
|
*/
|
||||||
export function userLogin(data = {}) {
|
export function userLogin(data = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: '/login/login',
|
url: '/login/login',
|
||||||
|
|
@ -7,9 +12,25 @@ export function userLogin(data = {}) {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取验证码
|
||||||
|
* @returns 验证码图片
|
||||||
|
*/
|
||||||
export function userCaptcha() {
|
export function userCaptcha() {
|
||||||
return request({
|
return request({
|
||||||
url: '/login/captcha',
|
url: '/login/captcha',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出登录
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function loginOut() {
|
||||||
|
return request({
|
||||||
|
url: '/login/logout',
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { defAxios as request } from '@/utils/http'
|
||||||
|
/**
|
||||||
|
* 获取部门分页数据接口
|
||||||
|
* @returns 部门分页
|
||||||
|
*/
|
||||||
|
export function getDeptList(params) {
|
||||||
|
return request({
|
||||||
|
url: '/dept/index',
|
||||||
|
method: 'GET',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门全部数据接口
|
||||||
|
* @returns 部门全部数据
|
||||||
|
*/
|
||||||
|
export function getDeptAll(params) {
|
||||||
|
return request({
|
||||||
|
url: '/dept/getDeptList',
|
||||||
|
method: 'GET',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加部门
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function addDept(data) {
|
||||||
|
return request({
|
||||||
|
url: '/dept/add',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑部门
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function editDept(data) {
|
||||||
|
return request({
|
||||||
|
url: '/dept/edit',
|
||||||
|
method: 'PUT',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除部门
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function deleteDept(id) {
|
||||||
|
return request({
|
||||||
|
url: `/dept/delete${[id]}`,
|
||||||
|
method: 'DELETE'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -21,3 +21,11 @@ export function getUserList(params) {
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDeptList(params) {
|
||||||
|
return request({
|
||||||
|
url: '/dept/apiIndex',
|
||||||
|
method: 'GET',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { defAxios as request } from '@/utils/http'
|
||||||
|
/**
|
||||||
|
* 获取菜单分页数据接口
|
||||||
|
* @returns 菜单分页数据
|
||||||
|
*/
|
||||||
|
export function getMenuList(params) {
|
||||||
|
return request({
|
||||||
|
url: '/menu/index',
|
||||||
|
method: 'GET',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取菜单全部数据接口
|
||||||
|
* @returns 菜单全部数据
|
||||||
|
*/
|
||||||
|
export function getMenu(params) {
|
||||||
|
return request({
|
||||||
|
url: '/menu/getMenuAll',
|
||||||
|
method: 'GET',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加菜单
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function addMenu(data) {
|
||||||
|
return request({
|
||||||
|
url: '/menu/add',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑菜单
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function editMenu(data) {
|
||||||
|
return request({
|
||||||
|
url: '/menu/edit',
|
||||||
|
method: 'PUT',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除菜单
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function deleteMenu(id) {
|
||||||
|
return request({
|
||||||
|
url: `/menu/delete${[id]}`,
|
||||||
|
method: 'DELETE'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
import { defAxios as request } from '@/utils/http'
|
||||||
|
/**
|
||||||
|
* 获取角色分页数据接口
|
||||||
|
* @returns 角色分页数据
|
||||||
|
*/
|
||||||
|
export function getRoleList(params) {
|
||||||
|
return request({
|
||||||
|
url: '/role/index',
|
||||||
|
method: 'GET',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取角色全部数据接口
|
||||||
|
* @returns 角色全部数据
|
||||||
|
*/
|
||||||
|
export function getRoleAll(params) {
|
||||||
|
return request({
|
||||||
|
url: '/role/getRoleList',
|
||||||
|
method: 'GET',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加角色
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function addRole(data) {
|
||||||
|
return request({
|
||||||
|
url: '/role/add',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑角色
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function editRole(data) {
|
||||||
|
return request({
|
||||||
|
url: '/role/edit',
|
||||||
|
method: 'PUT',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置角色状态
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function setRoleStatus(data) {
|
||||||
|
return request({
|
||||||
|
url: '/role/status',
|
||||||
|
method: 'PUT',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除角色
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function deleteRole(id) {
|
||||||
|
return request({
|
||||||
|
url: `/role/delete${[id]}`,
|
||||||
|
method: 'DELETE'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取角色权限数据
|
||||||
|
* @param 角色id
|
||||||
|
* @returns 角色全部权限数据
|
||||||
|
*/
|
||||||
|
export function getRolePermission(id) {
|
||||||
|
return request({
|
||||||
|
url: `/role/getPermissionList/${id}`,
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存角色权限信息
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function savePermission(data) {
|
||||||
|
return request({
|
||||||
|
url: '/role/savePermission',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { defAxios as request } from '@/utils/http'
|
||||||
|
/**
|
||||||
|
* 获取用户分页数据接口
|
||||||
|
* @returns 用户分页
|
||||||
|
*/
|
||||||
|
export function getUserList(params) {
|
||||||
|
return request({
|
||||||
|
url: '/user/index',
|
||||||
|
method: 'GET',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加用户
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function addUser(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/add',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑部门
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function editUser(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/edit',
|
||||||
|
method: 'PUT',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除用户
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function deleteUser(id) {
|
||||||
|
return request({
|
||||||
|
url: `/user/delete${[id]}`,
|
||||||
|
method: 'DELETE'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置用户状态
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function setUserStatus(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/status',
|
||||||
|
method: 'PUT',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置用户密码
|
||||||
|
* params
|
||||||
|
*/
|
||||||
|
export function resetPassword(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/resetPwd',
|
||||||
|
method: 'PUT',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ export function getUsers(data = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: '/users',
|
url: '/users',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
data,
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -12,12 +12,12 @@ export function getUser(id) {
|
||||||
if (id) {
|
if (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/user/${id}`,
|
url: `/user/${id}`,
|
||||||
method: 'get',
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return request({
|
return request({
|
||||||
url: '/user',
|
url: '/user',
|
||||||
method: 'get',
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,13 +26,13 @@ export function saveUser(data = {}, id) {
|
||||||
return request({
|
return request({
|
||||||
url: '/user',
|
url: '/user',
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data,
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return request({
|
return request({
|
||||||
url: `/user/${id}`,
|
url: `/user/${id}`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data,
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
<template>
|
|
||||||
<n-config-provider inline-theme-disabled :theme-overrides="themeOverrides">
|
|
||||||
<n-loading-bar-provider>
|
|
||||||
<!-- <loading-bar /> -->
|
|
||||||
<n-dialog-provider>
|
|
||||||
<dialog-content />
|
|
||||||
<n-message-provider>
|
|
||||||
<message-content />
|
|
||||||
<slot />
|
|
||||||
</n-message-provider>
|
|
||||||
</n-dialog-provider>
|
|
||||||
</n-loading-bar-provider>
|
|
||||||
</n-config-provider>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import themeOverrides from '@/utils/ui/theme.js'
|
|
||||||
// import MessageContent from './MessageContent.vue'
|
|
||||||
// import DialogContent from './DialogContent.vue'
|
|
||||||
// import LoadingBar from './LoadingBar.vue'
|
|
||||||
|
|
||||||
// import { useAppStore } from '@/store/modules/app'
|
|
||||||
// const appStore = useAppStore()
|
|
||||||
</script>
|
|
||||||
|
|
@ -44,6 +44,15 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
...tableProps
|
...tableProps
|
||||||
},
|
},
|
||||||
|
emits: [
|
||||||
|
'fetch-success',
|
||||||
|
'fetch-error',
|
||||||
|
'update:checked-row-keys',
|
||||||
|
'edit-end',
|
||||||
|
'edit-cancel',
|
||||||
|
'edit-row-end',
|
||||||
|
'edit-change'
|
||||||
|
],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const getProps = computed(() => {
|
const getProps = computed(() => {
|
||||||
return { ...props }
|
return { ...props }
|
||||||
|
|
@ -88,6 +97,8 @@ export default {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
emit('fetch-success', isRequest ? unref(getDataSourceRef) : unref(getProps).data)
|
||||||
|
|
||||||
const key = Symbol('s-table')
|
const key = Symbol('s-table')
|
||||||
provide(key, { getBindProps })
|
provide(key, { getBindProps })
|
||||||
/* tableData-end */
|
/* tableData-end */
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<template>
|
||||||
|
<n-switch v-bind="getSwitchProps" v-model:value="switchVlue" @update:value="changeValue" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, ref, unref, computed } from 'vue'
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'TableSwitch',
|
||||||
|
props: {
|
||||||
|
data: {
|
||||||
|
type: [Object, String, Number, Boolean],
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
rowKey: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ['change'],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const switchVlue = ref()
|
||||||
|
const { data, rowKey } = unref(props)
|
||||||
|
switchVlue.value = rowKey ? data[rowKey] : data
|
||||||
|
const getSwitchProps = computed(() => {
|
||||||
|
return {
|
||||||
|
...unref(props)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
function changeValue(value) {
|
||||||
|
const { data } = props
|
||||||
|
const params = {
|
||||||
|
data,
|
||||||
|
value
|
||||||
|
}
|
||||||
|
emit('change', params)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
switchVlue,
|
||||||
|
getSwitchProps,
|
||||||
|
changeValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
<template>
|
||||||
|
<template v-if="isFilter">
|
||||||
|
<n-tag
|
||||||
|
v-for="(item,index) in getData.data"
|
||||||
|
:key="`tag_${index}`"
|
||||||
|
v-bind="getProps"
|
||||||
|
:color="getFilter(item[getData.rowKey])?.color || getProps?.color"
|
||||||
|
>
|
||||||
|
{{ getFilter(item[getData.rowKey]).label }}
|
||||||
|
</n-tag>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<n-tag v-for="(item,index) in getData.data" :key="`tag_${index}`" v-bind="getProps">
|
||||||
|
{{ item[getData.rowKey] }}
|
||||||
|
</n-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, computed, unref } from 'vue'
|
||||||
|
import { isArray } from '@/utils/is.js'
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'TableTags',
|
||||||
|
props: {
|
||||||
|
/* 展示的数据 */
|
||||||
|
data: {
|
||||||
|
type: [Array, String, Number],
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
/* 展示数据取的字段 */
|
||||||
|
rowKey: {
|
||||||
|
type: String,
|
||||||
|
default: 'name'
|
||||||
|
},
|
||||||
|
/* 过滤的数据 */
|
||||||
|
// filters: [
|
||||||
|
// {
|
||||||
|
// key: '',
|
||||||
|
// label: '',
|
||||||
|
// color: {}
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
filters: {
|
||||||
|
type: Array,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
/* tag标签的属性 */
|
||||||
|
tags: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const isFilter = computed(() => {
|
||||||
|
return !!(props.filters)
|
||||||
|
})
|
||||||
|
const { filters } = unref(props)
|
||||||
|
function getFilter(value) {
|
||||||
|
const data = filters.find(item => {
|
||||||
|
return item.key === value
|
||||||
|
})
|
||||||
|
return data || {
|
||||||
|
key: value,
|
||||||
|
label: value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 获取传递的数据 */
|
||||||
|
const getData = computed(() => {
|
||||||
|
return {
|
||||||
|
rowKey: unref(props.rowKey),
|
||||||
|
data: isArray(props.data) ? { ...unref(props.data) } : [{ [props.rowKey]: props.data }],
|
||||||
|
filters: { ...unref(props.filters) }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/* 获取tags的属性 */
|
||||||
|
const getProps = computed(() => {
|
||||||
|
return {
|
||||||
|
...unref(props.tags),
|
||||||
|
closable: false,
|
||||||
|
bordered: props.tags?.bordered || false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
isFilter,
|
||||||
|
getFilter,
|
||||||
|
getData,
|
||||||
|
getProps
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
.n-tag{
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -30,7 +30,7 @@ export const tableProps = {
|
||||||
// 每页数量字段名
|
// 每页数量字段名
|
||||||
sizeField: 'limit',
|
sizeField: 'limit',
|
||||||
// 接口返回的数据字段名
|
// 接口返回的数据字段名
|
||||||
listField: 'list',
|
listField: 'records',
|
||||||
// 接口返回总页数字段名
|
// 接口返回总页数字段名
|
||||||
totalField: 'total',
|
totalField: 'total',
|
||||||
// 默认分页数量
|
// 默认分页数量
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
* pid形式数据转children形式
|
||||||
|
* @param data 需要转换的数组
|
||||||
|
* @param idKey id字段名
|
||||||
|
* @param pidKey pid字段名
|
||||||
|
* @param childKey 生成的children字段名
|
||||||
|
* @param pid 顶级的pid
|
||||||
|
* @param addPIds 是否添加所有父级id的字段
|
||||||
|
* @param parentsKey 所有父级id的字段名称,默认parentIds
|
||||||
|
* @param parentIds 所有父级id
|
||||||
|
* @returns {[]}
|
||||||
|
*/
|
||||||
|
export function toTreeData(data, idKey, pidKey, childKey, pid, addPIds, parentsKey, parentIds) {
|
||||||
|
if (typeof data === 'object' && !Array.isArray(data)) {
|
||||||
|
idKey = data.idKey
|
||||||
|
pidKey = data.pidKey
|
||||||
|
childKey = data.childKey
|
||||||
|
pid = data.pid
|
||||||
|
addPIds = data.addPIds
|
||||||
|
parentsKey = data.parentsKey
|
||||||
|
parentIds = data.parentIds
|
||||||
|
data = data.data
|
||||||
|
}
|
||||||
|
if (!childKey) {
|
||||||
|
childKey = 'children'
|
||||||
|
}
|
||||||
|
if (typeof pid === 'undefined') {
|
||||||
|
pid = []
|
||||||
|
data.forEach((d) => {
|
||||||
|
let flag = true
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
if (d[pidKey] === data[i][idKey]) {
|
||||||
|
flag = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flag) {
|
||||||
|
pid.push(d[pidKey])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const result = []
|
||||||
|
data.forEach((d) => {
|
||||||
|
if (d[idKey] === d[pidKey]) {
|
||||||
|
console.error('data error: ', d)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (Array.isArray(pid) ? (pid.indexOf(d[pidKey]) !== -1) : (d[pidKey] === pid)) {
|
||||||
|
const children = toTreeData({
|
||||||
|
data: data,
|
||||||
|
idKey: idKey,
|
||||||
|
pidKey: pidKey,
|
||||||
|
childKey: childKey,
|
||||||
|
pid: d[idKey],
|
||||||
|
addPIds: addPIds,
|
||||||
|
parentsKey: parentsKey,
|
||||||
|
parentIds: (parentIds || []).concat([d[idKey]])
|
||||||
|
})
|
||||||
|
if (children.length > 0) {
|
||||||
|
d[childKey] = children
|
||||||
|
}
|
||||||
|
if (addPIds) {
|
||||||
|
d[parentsKey || 'parentIds'] = parentIds || []
|
||||||
|
}
|
||||||
|
result.push(d)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { ref, unref, computed, onMounted } from 'vue'
|
import { ref, unref, computed, onMounted } from 'vue'
|
||||||
import { isBoolean } from '@/utils/is'
|
import { isBoolean } from '@/utils/is'
|
||||||
|
import { toTreeData } from './toTree'
|
||||||
|
|
||||||
export function useDataSource(propsRef, { getPaginationInfo, setPagination, setLoading, tableData }, emit) {
|
export function useDataSource(propsRef, { getPaginationInfo, setPagination, setLoading, tableData }, emit) {
|
||||||
const dataSourceRef = ref([])
|
const dataSourceRef = ref([])
|
||||||
|
|
@ -42,6 +43,7 @@ export function useDataSource(propsRef, { getPaginationInfo, setPagination, setL
|
||||||
fetch(opt)
|
fetch(opt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 处理数据结构
|
||||||
const resultInfo = res[listField] ? res[listField] : []
|
const resultInfo = res[listField] ? res[listField] : []
|
||||||
dataSourceRef.value = dataType === 'tree' ? dealTree(resultInfo) : resultInfo
|
dataSourceRef.value = dataType === 'tree' ? dealTree(resultInfo) : resultInfo
|
||||||
setPagination({
|
setPagination({
|
||||||
|
|
@ -67,8 +69,12 @@ export function useDataSource(propsRef, { getPaginationInfo, setPagination, setL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dealTree() {
|
/**
|
||||||
const tree = []
|
* 递归遍历数据处理成树形结构
|
||||||
|
* @returns 返回树形结构数据
|
||||||
|
*/
|
||||||
|
function dealTree(info) {
|
||||||
|
const tree = toTreeData(info.data, 'id', 'pid', 'children')
|
||||||
return tree
|
return tree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,134 +0,0 @@
|
||||||
<template>
|
|
||||||
<!-- <n-data-table>
|
|
||||||
n-data-table
|
|
||||||
</n-data-table> -->
|
|
||||||
<div class="table-toolbar">
|
|
||||||
<!--顶部左侧区域-->
|
|
||||||
<div class="flex items-center table-toolbar-left">
|
|
||||||
<slot name="tableTitle" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center table-toolbar-right">
|
|
||||||
<!--顶部右侧区域-->
|
|
||||||
<slot name="toolbar" />
|
|
||||||
<!--刷新-->
|
|
||||||
<!-- <n-tooltip trigger="hover">
|
|
||||||
<template #trigger>
|
|
||||||
<div class="table-toolbar-right-icon" @click="reload">
|
|
||||||
<n-icon size="18">
|
|
||||||
<ReloadOutlined />
|
|
||||||
</n-icon>
|
|
||||||
</div>
|
|
||||||
</template> -->
|
|
||||||
<span @click="reload">刷新</span>
|
|
||||||
<!-- </n-tooltip> -->
|
|
||||||
<!--表格设置单独抽离成组件-->
|
|
||||||
<!-- <ColumnSetting /> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="s-table">
|
|
||||||
<n-data-table
|
|
||||||
ref="tableElRef"
|
|
||||||
v-bind="getBindValues"
|
|
||||||
:pagination="pagination"
|
|
||||||
>
|
|
||||||
<template v-for="item in Object.keys($slots)" #[item]="data" :key="item">
|
|
||||||
<slot :name="item" v-bind="data" />
|
|
||||||
</template>
|
|
||||||
</n-data-table>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { tableProps } from './tools/props.js'
|
|
||||||
import { useDataSource } from './tools/useDataSource.js'
|
|
||||||
import { usePagination } from './tools/usePagination.js'
|
|
||||||
|
|
||||||
import { unref, ref, computed, toRaw } from 'vue'
|
|
||||||
export default {
|
|
||||||
name: 'DataTable',
|
|
||||||
props: {
|
|
||||||
...tableProps
|
|
||||||
},
|
|
||||||
emits: [
|
|
||||||
'fetch-success',
|
|
||||||
'fetch-error',
|
|
||||||
'update:checked-row-keys',
|
|
||||||
'edit-end',
|
|
||||||
'edit-cancel',
|
|
||||||
'edit-row-end',
|
|
||||||
'edit-change'
|
|
||||||
],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const loadingRef = ref(unref(props).loading)
|
|
||||||
const getLoading = computed(() => unref(loadingRef))
|
|
||||||
function setLoading(loading) {
|
|
||||||
loadingRef.value = loading
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pagination-start */
|
|
||||||
const pagination = computed(() => toRaw(unref(getPaginationInfo)))
|
|
||||||
const { getPaginationInfo, setPagination } = usePagination(props)
|
|
||||||
/* pagination-end */
|
|
||||||
|
|
||||||
/* tableData-start */
|
|
||||||
const tableData = ref([])
|
|
||||||
const { getDataSourceRef, reload } = useDataSource(props, { getPaginationInfo, setPagination, tableData, setLoading }, emit)
|
|
||||||
|
|
||||||
// 组装表格信息
|
|
||||||
const getBindValues = computed(() => {
|
|
||||||
const tableData = unref(getDataSourceRef)
|
|
||||||
return {
|
|
||||||
...unref(props),
|
|
||||||
loading: unref(getLoading),
|
|
||||||
// columns: toRaw(unref(getPageColumns)),
|
|
||||||
// rowKey: unref(getRowKey),
|
|
||||||
data: tableData,
|
|
||||||
// size: unref(getTableSize),
|
|
||||||
remote: true,
|
|
||||||
'max-height': 'auto'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
/* tableData-end */
|
|
||||||
|
|
||||||
return {
|
|
||||||
pagination,
|
|
||||||
fetch,
|
|
||||||
reload,
|
|
||||||
getBindValues
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<style scoped lang='scss'>
|
|
||||||
.table-toolbar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 0 16px 0;
|
|
||||||
.table-toolbar-left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.table-toolbar-right {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
flex: 1;
|
|
||||||
.table-toolbar-icon {
|
|
||||||
margin-left: 12px;
|
|
||||||
font-size: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--text-color);
|
|
||||||
&:hover {
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.table-toolbar-inner-popover-title {
|
|
||||||
padding: 2px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import { NDataTable } from 'naive-ui'
|
|
||||||
|
|
||||||
export const tableProps = {
|
|
||||||
...NDataTable.props,
|
|
||||||
/* 初始化接口请求 */
|
|
||||||
request: {
|
|
||||||
type: Function,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
/* 分页信息 */
|
|
||||||
pagination: {
|
|
||||||
type: [Object, Boolean],
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
/* 分页设置信息 */
|
|
||||||
paginationSetting: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {
|
|
||||||
// 当前页的字段名
|
|
||||||
pageField: 'page',
|
|
||||||
// 每页数量字段名
|
|
||||||
sizeField: 'pageSize',
|
|
||||||
// 接口返回的数据字段名
|
|
||||||
listField: 'list',
|
|
||||||
// 接口返回总页数字段名
|
|
||||||
totalField: 'pageCount',
|
|
||||||
// 默认分页数量
|
|
||||||
defaultPageSize: 10,
|
|
||||||
// 可切换每页数量集合
|
|
||||||
pageSizes: [10, 20, 30, 40, 50]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
import { ref, unref, computed, onMounted } from 'vue'
|
|
||||||
import { isBoolean } from '@/utils/is'
|
|
||||||
|
|
||||||
export function useDataSource(propsRef, { getPaginationInfo, setPagination, setLoading, tableData }, emit) {
|
|
||||||
const dataSourceRef = ref([])
|
|
||||||
|
|
||||||
async function fetch(opt) {
|
|
||||||
try {
|
|
||||||
// setLoading(true)
|
|
||||||
const { request, pagination } = unref(propsRef)
|
|
||||||
/* 无接口请求中断 */
|
|
||||||
if (!request) return
|
|
||||||
/* 获取分页信息 */
|
|
||||||
const paginationSetting = propsRef.paginationSetting
|
|
||||||
const pageField = paginationSetting.pageField
|
|
||||||
const sizeField = paginationSetting.sizeField
|
|
||||||
const totalField = paginationSetting.totalField
|
|
||||||
const listField = paginationSetting.listField
|
|
||||||
|
|
||||||
let pageParams = {}
|
|
||||||
const { page = 1, pageSize = 10 } = unref(getPaginationInfo)
|
|
||||||
if ((isBoolean(pagination) && !pagination) || isBoolean(getPaginationInfo)) {
|
|
||||||
pageParams = {}
|
|
||||||
} else {
|
|
||||||
pageParams[pageField] = (opt && opt[pageField]) || page
|
|
||||||
pageParams[sizeField] = pageSize
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
...pageParams
|
|
||||||
}
|
|
||||||
const res = await request(params)
|
|
||||||
console.log('res', res)
|
|
||||||
const resultTotal = res[totalField] || 0
|
|
||||||
const currentPage = res[pageField]
|
|
||||||
|
|
||||||
// // 如果数据异常,需获取正确的页码再次执行
|
|
||||||
// if (resultTotal) {
|
|
||||||
// if (page > resultTotal) {
|
|
||||||
// setPagination({
|
|
||||||
// [pageField]: resultTotal
|
|
||||||
// })
|
|
||||||
// fetch(opt)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
const resultInfo = res[listField] ? res[listField] : []
|
|
||||||
dataSourceRef.value = resultInfo
|
|
||||||
setPagination({
|
|
||||||
[pageField]: currentPage,
|
|
||||||
[totalField]: resultTotal
|
|
||||||
})
|
|
||||||
// if (opt && opt[pageField]) {
|
|
||||||
// setPagination({
|
|
||||||
// [pageField]: opt[pageField] || 1
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
emit('fetch-success', {
|
|
||||||
items: unref(resultInfo),
|
|
||||||
resultTotal
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
// emit('fetch-error', error)
|
|
||||||
// dataSourceRef.value = []
|
|
||||||
} finally {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getDataSourceRef = computed(() => {
|
|
||||||
const dataSource = unref(dataSourceRef)
|
|
||||||
if (!dataSource || dataSource.length === 0) {
|
|
||||||
return unref(dataSourceRef)
|
|
||||||
}
|
|
||||||
return unref(dataSourceRef)
|
|
||||||
})
|
|
||||||
|
|
||||||
function getDataSource() {
|
|
||||||
console.log(getDataSourceRef.value)
|
|
||||||
return getDataSourceRef.value
|
|
||||||
}
|
|
||||||
|
|
||||||
function setTableData(values) {
|
|
||||||
dataSourceRef.value = values
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
fetch()
|
|
||||||
}, 15)
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
fetch,
|
|
||||||
getDataSourceRef,
|
|
||||||
getDataSource,
|
|
||||||
setTableData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
import { computed, unref, ref } from 'vue'
|
|
||||||
import { isBoolean } from '@/utils/is'
|
|
||||||
|
|
||||||
export function usePagination(refProps) {
|
|
||||||
const configRef = ref({})
|
|
||||||
const show = ref(true)
|
|
||||||
console.log('configRef', configRef)
|
|
||||||
console.log('refProps', refProps)
|
|
||||||
const getPaginationInfo = computed(() => {
|
|
||||||
const { pagination, paginationSetting } = unref(refProps)
|
|
||||||
if (!unref(show) || (isBoolean(pagination) && !pagination)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
pageSize: paginationSetting.defaultPageSize,
|
|
||||||
pageSizes: paginationSetting.pageSizes,
|
|
||||||
showSizePicker: true,
|
|
||||||
showQuickJumper: true,
|
|
||||||
...(isBoolean(pagination) ? {} : pagination),
|
|
||||||
...unref(configRef),
|
|
||||||
pageCount: unref(configRef)[paginationSetting.totalField]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
function setPagination(info) {
|
|
||||||
const paginationInfo = unref(getPaginationInfo)
|
|
||||||
configRef.value = {
|
|
||||||
...(!isBoolean(paginationInfo) ? paginationInfo : {}),
|
|
||||||
...info
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { getPaginationInfo, setPagination }
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,54 @@
|
||||||
<template />
|
<template>
|
||||||
|
<div />
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { isNullOrUndef } from '@/utils/is'
|
||||||
import { useDialog } from 'naive-ui'
|
import { useDialog } from 'naive-ui'
|
||||||
window['$dialog'] = useDialog()
|
|
||||||
|
const NDialog = useDialog()
|
||||||
|
|
||||||
|
class Dialog {
|
||||||
|
success(title, option) {
|
||||||
|
this.showDialog('success', { title, ...option })
|
||||||
|
}
|
||||||
|
|
||||||
|
warning(title, option) {
|
||||||
|
this.showDialog('warning', { title, ...option })
|
||||||
|
}
|
||||||
|
|
||||||
|
error(title, option) {
|
||||||
|
this.showDialog('error', { title, ...option })
|
||||||
|
}
|
||||||
|
|
||||||
|
showDialog(type = 'success', option) {
|
||||||
|
if (isNullOrUndef(option.title)) {
|
||||||
|
option.showIcon = false
|
||||||
|
}
|
||||||
|
NDialog[type]({
|
||||||
|
positiveText: 'OK',
|
||||||
|
closable: false,
|
||||||
|
...option
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
confirm(option = {}) {
|
||||||
|
this.showDialog(option.type || 'error', {
|
||||||
|
positiveText: '确定',
|
||||||
|
negativeText: '取消',
|
||||||
|
onPositiveClick: option.confirm,
|
||||||
|
onNegativeClick: option.cancel,
|
||||||
|
onMaskClick: option.cancel,
|
||||||
|
...option
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window['$dialog'] = new Dialog()
|
||||||
|
Object.freeze(window.$dialog)
|
||||||
|
Object.defineProperty(window, '$dialog', {
|
||||||
|
configurable: false,
|
||||||
|
writable: false
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<n-upload
|
||||||
|
:default-file-list="fileList"
|
||||||
|
v-bind="getImgOptions"
|
||||||
|
:on-change="handleChange"
|
||||||
|
:on-before-upload="handleBeforeUpload"
|
||||||
|
>
|
||||||
|
点击上传
|
||||||
|
</n-upload>
|
||||||
|
<n-modal
|
||||||
|
v-model:show="showModal"
|
||||||
|
preset="card"
|
||||||
|
style="width: 600px"
|
||||||
|
>
|
||||||
|
<img :src="previewImageUrl" style="width: 100%">
|
||||||
|
</n-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, reactive, toRefs, computed, unref } from 'vue'
|
||||||
|
import { getToken } from '@/utils/token'
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'ImgUpload',
|
||||||
|
props: {
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: Number,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const data = reactive({
|
||||||
|
fileList: []
|
||||||
|
})
|
||||||
|
const BaseURL = window.__APP__GLOB__CONF__?.VITE_APP_GLOB_BASE_API || import.meta.env.VITE_APP_GLOB_BASE_API
|
||||||
|
const getImgOptions = computed(() => {
|
||||||
|
return {
|
||||||
|
...unref(props.options),
|
||||||
|
listType: 'image-card',
|
||||||
|
defaultUpload: props.options.defaultUpload || false,
|
||||||
|
action: `${BaseURL}${props.options.action}`,
|
||||||
|
headers: {
|
||||||
|
'Authorization': getToken(),
|
||||||
|
...props.options.headers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
function handleChange(file) {
|
||||||
|
console.log(222, file)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @description: 上传前判断文件是否符合条件
|
||||||
|
* @param {*} options
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
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) {
|
||||||
|
fileList.splice(fileList.length - 1)
|
||||||
|
$message.error('选择的文件大小不满足条件!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...toRefs(data),
|
||||||
|
getImgOptions,
|
||||||
|
handleChange,
|
||||||
|
handleBeforeUpload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
</style>
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
<template />
|
<template>
|
||||||
|
<div />
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useMessage } from 'naive-ui'
|
import { useMessage } from 'naive-ui'
|
||||||
|
|
@ -8,12 +10,6 @@ const NMessage = useMessage()
|
||||||
let loadingMessage = null
|
let loadingMessage = null
|
||||||
|
|
||||||
class Message {
|
class Message {
|
||||||
/**
|
|
||||||
* 规则:
|
|
||||||
* * loading message只显示一个,新的message会替换正在显示的loading message
|
|
||||||
* * loading message不会自动清除,除非被替换成非loading message,非loading message默认2秒后自动清除
|
|
||||||
*/
|
|
||||||
|
|
||||||
removeMessage(message, duration = 2000) {
|
removeMessage(message, duration = 2000) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (message) {
|
if (message) {
|
||||||
|
|
@ -25,16 +21,13 @@ class Message {
|
||||||
|
|
||||||
showMessage(type, content, option = {}) {
|
showMessage(type, content, option = {}) {
|
||||||
if (loadingMessage && loadingMessage.type === 'loading') {
|
if (loadingMessage && loadingMessage.type === 'loading') {
|
||||||
// 如果存在则替换正在显示的loading message
|
|
||||||
loadingMessage.type = type
|
loadingMessage.type = type
|
||||||
loadingMessage.content = content
|
loadingMessage.content = content
|
||||||
|
|
||||||
if (type !== 'loading') {
|
if (type !== 'loading') {
|
||||||
// 非loading message需设置自动清除
|
|
||||||
this.removeMessage(loadingMessage, option.duration)
|
this.removeMessage(loadingMessage, option.duration)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 不存在正在显示的loading则新建一个message,如果新建的message是loading message则将message赋值存储下来
|
|
||||||
const message = NMessage[type](content, option)
|
const message = NMessage[type](content, option)
|
||||||
if (type === 'loading') {
|
if (type === 'loading') {
|
||||||
loadingMessage = message
|
loadingMessage = message
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
<n-modal
|
<n-modal
|
||||||
v-bind="getModalOptions"
|
v-bind="getModalOptions"
|
||||||
:style="`width:${getModalOptions.width}px`"
|
:style="`width:${getModalOptions.width}px`"
|
||||||
preset="card"
|
:title="options.title"
|
||||||
@update:show="handleClose"
|
|
||||||
>
|
>
|
||||||
<n-card :bordered="false">
|
<n-card :bordered="false">
|
||||||
<slot name="Context" />
|
<slot name="Context" />
|
||||||
|
|
@ -13,9 +12,9 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import { defineComponent, computed, unref } from 'vue'
|
import { defineComponent, computed } from 'vue'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'CardModal',
|
name: 'CardDialogModal',
|
||||||
props: {
|
props: {
|
||||||
options: {
|
options: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
@ -23,7 +22,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
click: null, // click事件没有检验
|
onConfirm: null,
|
||||||
onClose: (value) => {
|
onClose: (value) => {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
@ -32,18 +31,21 @@ export default defineComponent({
|
||||||
const getModalOptions = computed(() => {
|
const getModalOptions = computed(() => {
|
||||||
return {
|
return {
|
||||||
...props.options,
|
...props.options,
|
||||||
width: props.options.width || 600
|
width: props.options.width || 600,
|
||||||
|
preset: props.options.preset || 'dialog',
|
||||||
|
showIcon: !!props.options.showIcon
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const handleClick = function() {
|
const handleConfirm = function() {
|
||||||
emit('click')
|
emit('onConfirm')
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
const handleClose = function() {
|
const handleClose = function() {
|
||||||
emit('onClose', true)
|
emit('onClose', true)
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
getModalOptions,
|
getModalOptions,
|
||||||
handleClick,
|
handleConfirm,
|
||||||
handleClose
|
handleClose
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,8 +29,6 @@ const getMenuOptions = computed(() => {
|
||||||
return generateOptions(permissionStore.routes, '')
|
return generateOptions(permissionStore.routes, '')
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('getMenuOptions', getMenuOptions)
|
|
||||||
|
|
||||||
function resolvePath(basePath, path) {
|
function resolvePath(basePath, path) {
|
||||||
if (isExternal(path)) return path
|
if (isExternal(path)) return path
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,9 @@ export function createPermissionGuard(router) {
|
||||||
try {
|
try {
|
||||||
// await userStore.getUserInfo()
|
// await userStore.getUserInfo()
|
||||||
const routes = await permissionStore.generateRoutes()
|
const routes = await permissionStore.generateRoutes()
|
||||||
router.addRoute(routes[0])
|
routes.forEach((item) => {
|
||||||
|
router.addRoute(item)
|
||||||
|
})
|
||||||
router.addRoute(NOT_FOUND_ROUTE)
|
router.addRoute(NOT_FOUND_ROUTE)
|
||||||
router.addRoute(REDIRECT_ROUTE)
|
router.addRoute(REDIRECT_ROUTE)
|
||||||
next({ ...to, replace: true })
|
next({ ...to, replace: true })
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { asyncRoutes, basicRoutes } from '@/router/routes'
|
import { asyncRoutes, basicRoutes } from '@/router/routes'
|
||||||
import { getMenu } from '@/api/system'
|
import { getMenu } from '@/api/auth/index'
|
||||||
import Layout from '@/layout/index.vue'
|
import Layout from '@/layout/index.vue'
|
||||||
import modules from '@/utils/module.js'
|
import modules from '@/utils/module.js'
|
||||||
|
|
||||||
|
|
@ -114,7 +114,6 @@ export const usePermissionStore = defineStore('permission', {
|
||||||
const res = await getMenu()
|
const res = await getMenu()
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
const result = dataArrayToRoutes(res.data)
|
const result = dataArrayToRoutes(res.data)
|
||||||
console.log(result)
|
|
||||||
this.accessRoutes = result
|
this.accessRoutes = result
|
||||||
return Promise.resolve(result)
|
return Promise.resolve(result)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,9 @@
|
||||||
height: calc(100vh - 48px);
|
height: calc(100vh - 48px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.n-data-table .n-data-table-tr{
|
||||||
|
th{
|
||||||
|
white-space:nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
/**
|
||||||
|
* pid形式数据转children形式
|
||||||
|
* @param data 需要转换的数组
|
||||||
|
* @param idKey id字段名
|
||||||
|
* @param pidKey pid字段名
|
||||||
|
* @param childKey 生成的children字段名
|
||||||
|
* @param pid 顶级的pid
|
||||||
|
* @param addPIds 是否添加所有父级id的字段
|
||||||
|
* @param parentsKey 所有父级id的字段名称,默认parentIds
|
||||||
|
* @param parentIds 所有父级id
|
||||||
|
* @returns {[]}
|
||||||
|
*/
|
||||||
|
export function toTreeData(data, idKey, pidKey, childKey, pid, addPIds, parentsKey, parentIds) {
|
||||||
|
if (typeof data === 'object' && !Array.isArray(data)) {
|
||||||
|
idKey = data.idKey
|
||||||
|
pidKey = data.pidKey
|
||||||
|
childKey = data.childKey
|
||||||
|
pid = data.pid
|
||||||
|
addPIds = data.addPIds
|
||||||
|
parentsKey = data.parentsKey
|
||||||
|
parentIds = data.parentIds
|
||||||
|
data = data.data
|
||||||
|
}
|
||||||
|
if (!childKey) {
|
||||||
|
childKey = 'children'
|
||||||
|
}
|
||||||
|
if (typeof pid === 'undefined') {
|
||||||
|
pid = []
|
||||||
|
data.forEach((d) => {
|
||||||
|
let flag = true
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
if (d[pidKey] === data[i][idKey]) {
|
||||||
|
flag = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flag) {
|
||||||
|
pid.push(d[pidKey])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const result = []
|
||||||
|
data.forEach((d) => {
|
||||||
|
if (d[idKey] === d[pidKey]) {
|
||||||
|
console.error('data error: ', d)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (Array.isArray(pid) ? (pid.indexOf(d[pidKey]) !== -1) : (d[pidKey] === pid)) {
|
||||||
|
const children = toTreeData({
|
||||||
|
data: data,
|
||||||
|
idKey: idKey,
|
||||||
|
pidKey: pidKey,
|
||||||
|
childKey: childKey,
|
||||||
|
pid: d[idKey],
|
||||||
|
addPIds: addPIds,
|
||||||
|
parentsKey: parentsKey,
|
||||||
|
parentIds: (parentIds || []).concat([d[idKey]])
|
||||||
|
})
|
||||||
|
if (children.length > 0) {
|
||||||
|
d[childKey] = children
|
||||||
|
}
|
||||||
|
if (addPIds) {
|
||||||
|
d[parentsKey || 'parentIds'] = parentIds || []
|
||||||
|
}
|
||||||
|
result.push(d)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 遍历children形式数据
|
||||||
|
* @param data 需要遍历的数组
|
||||||
|
* @param callback 回调
|
||||||
|
* @param childKey children字段名
|
||||||
|
*/
|
||||||
|
export function eachTreeData(data, callback, childKey = 'children') {
|
||||||
|
if (!data || !data.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data.forEach((d) => {
|
||||||
|
if (callback(d) !== false && d[childKey]) {
|
||||||
|
eachTreeData(d[childKey], callback, childKey)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理树形数据
|
||||||
|
* @param data 需要处理的数据
|
||||||
|
* @param formatter 处理器
|
||||||
|
* @param childKey children字段名
|
||||||
|
* @returns {[]} 处理后的数据
|
||||||
|
*/
|
||||||
|
export function formatTreeData(data, formatter, childKey = 'children') {
|
||||||
|
const result = []
|
||||||
|
if (data && data.length) {
|
||||||
|
data.forEach((d) => {
|
||||||
|
const item = formatter(d)
|
||||||
|
if (item !== false) {
|
||||||
|
if (item[childKey]) {
|
||||||
|
item[childKey] = formatTreeData(item[childKey], formatter, childKey)
|
||||||
|
}
|
||||||
|
result.push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理select数据
|
||||||
|
* @param data 需要处理的数据
|
||||||
|
* @params {label: XX, value: XX, children: XX} 需要处理的结构
|
||||||
|
* @returns {[]} 处理后的数据
|
||||||
|
*/
|
||||||
|
export function dataToSelect(data, optionsObj) {
|
||||||
|
const result = []
|
||||||
|
if (data && data.length) {
|
||||||
|
data.forEach((item) => {
|
||||||
|
const i = {}
|
||||||
|
i.label = item[optionsObj.label]
|
||||||
|
i.value = item[optionsObj.value]
|
||||||
|
if (item.children && item.children.length) {
|
||||||
|
dataToSelect(item.children, optionsObj)
|
||||||
|
i.children = item[optionsObj.children]
|
||||||
|
}
|
||||||
|
result.push(i)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
@ -43,8 +43,8 @@ export function setupInterceptor(service) {
|
||||||
// 未登录(可能是token过期或者无效了)
|
// 未登录(可能是token过期或者无效了)
|
||||||
removeToken()
|
removeToken()
|
||||||
router.replace({
|
router.replace({
|
||||||
path: '/login',
|
path: '/login'
|
||||||
query: { ...currentRoute.query, redirect: currentRoute.path }
|
// query: { ...currentRoute.query, redirect: currentRoute.path }
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,125 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="login_bg">
|
||||||
|
<n-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="loginForm"
|
||||||
|
:rules="rules"
|
||||||
|
label-placement="left"
|
||||||
|
label-width="auto"
|
||||||
|
require-mark-placement="right-hanging"
|
||||||
|
:style="{
|
||||||
|
maxWidth: '640px',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
padding: '20px',
|
||||||
|
borderRadius: '10px'
|
||||||
|
}"
|
||||||
|
@keyup.enter="handleLogin"
|
||||||
|
>
|
||||||
|
<n-form-item label="用户名" path="username">
|
||||||
|
<n-input v-model:value="loginForm.username" placeholder="请输入用户名" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="密码" path="password">
|
||||||
|
<n-input v-model:value="loginForm.password" type="password" placeholder="请输入用户名" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="验证码" path="captcha">
|
||||||
|
<n-input v-model:value="loginForm.captcha" placeholder="请输入验证码" />
|
||||||
|
<img v-if="captcha" :src="captcha" alt="" @click="changeCode">
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="remember">
|
||||||
|
<n-checkbox v-model:checked="loginForm.remember" size="medium" label="记住密码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item>
|
||||||
<n-button @click="handleLogin">登录</n-button>
|
<n-button @click="handleLogin">登录</n-button>
|
||||||
|
</n-form-item>
|
||||||
|
</n-form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { userLogin, userCaptcha } from '@/api/login/index.js'
|
import { userLogin, userCaptcha } from '@/api/login/index.js'
|
||||||
import { setToken } from '@/utils/token'
|
import { setToken } from '@/utils/token'
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
export default {
|
export default {
|
||||||
name: 'LoginPage',
|
name: 'LoginPage',
|
||||||
setup() {
|
setup() {
|
||||||
async function handleLogin() {
|
const loginForm = reactive({
|
||||||
try {
|
username: '',
|
||||||
|
password: '',
|
||||||
|
key: '',
|
||||||
|
captcha: '',
|
||||||
|
remember: false
|
||||||
|
})
|
||||||
|
onMounted(() => {
|
||||||
|
changeCode(loginForm)
|
||||||
|
})
|
||||||
|
// 获取图形验证码
|
||||||
|
const captcha = ref('')
|
||||||
|
async function changeCode(form) {
|
||||||
const params = {
|
const params = {
|
||||||
captcha: '520',
|
username: form.username,
|
||||||
key: 'f2d40fb6-b946-4b99-969d-978c6d8a4ea2',
|
password: form.password,
|
||||||
password: '123456',
|
captcha: form.captcha
|
||||||
remember: false,
|
|
||||||
username: 'admin'
|
|
||||||
}
|
}
|
||||||
const res = await userLogin(params)
|
const captForm = await userCaptcha(params)
|
||||||
if (res.code === 0) {
|
captcha.value = captForm.data.captcha
|
||||||
setToken(res.data.access_token)
|
loginForm.key = captForm.data.key
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
// console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// userCaptcha()
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleLogin
|
loginForm,
|
||||||
|
captcha,
|
||||||
|
changeCode,
|
||||||
|
rules: reactive({
|
||||||
|
username: {
|
||||||
|
required: true,
|
||||||
|
trigger: ['blur', 'input'],
|
||||||
|
message: '请输入用户名'
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
required: true,
|
||||||
|
trigger: ['blur', 'input'],
|
||||||
|
message: '请输入密码'
|
||||||
|
},
|
||||||
|
captcha: {
|
||||||
|
required: true,
|
||||||
|
trigger: ['blur', 'input'],
|
||||||
|
message: '请输入验证码'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleLogin() {
|
||||||
|
console.log(this.loginForm)
|
||||||
|
userLogin(this.loginForm).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
// 登录成功存储token,跳转首页
|
||||||
|
setToken(res.data.access_token)
|
||||||
|
this.goPage()
|
||||||
|
} else {
|
||||||
|
console.log(res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 登录成功跳转
|
||||||
|
goPage() {
|
||||||
|
// const query = this.$route.query
|
||||||
|
// const path = query && query.from ? query.from : '/'
|
||||||
|
// console.log(path)
|
||||||
|
// this.$router.replace(path)
|
||||||
|
this.$router.replace('/home')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.login_bg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<n-card>
|
||||||
|
<data-table
|
||||||
|
:columns="data.columns"
|
||||||
|
:data="data.data"
|
||||||
|
:pagination="data.pagination"
|
||||||
|
:request="loadDataTable"
|
||||||
|
:row-key="(row) => row.id"
|
||||||
|
data-type="tree"
|
||||||
|
size="large"
|
||||||
|
scroll-x="1200"
|
||||||
|
>
|
||||||
|
<template #tableTitle>
|
||||||
|
<n-button type="primary"> 新建 </n-button>
|
||||||
|
<n-button type="primary"> 删除 </n-button>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</n-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
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'
|
||||||
|
export default {
|
||||||
|
name: 'MenuPage',
|
||||||
|
components: { dataTable },
|
||||||
|
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
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
align: 'center',
|
||||||
|
width: 150,
|
||||||
|
fixed: 'right',
|
||||||
|
render(row) {
|
||||||
|
return h(TableAction, {
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: '添加',
|
||||||
|
type: 'button',
|
||||||
|
props: {
|
||||||
|
type: 'primary',
|
||||||
|
onClick: play.bind(null, row)
|
||||||
|
},
|
||||||
|
auth: 'basic_list'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '修改',
|
||||||
|
auth: 'basic_list'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '删除',
|
||||||
|
type: 'popconfirm',
|
||||||
|
auth: 'basic_list'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
align: 'center'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
pagination: {
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function play(row) {
|
||||||
|
console.log(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 获取部门数据并做树形结构处理
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
async function fetchList() {
|
||||||
|
const params = {
|
||||||
|
page: 1,
|
||||||
|
limit: 10
|
||||||
|
}
|
||||||
|
const res = await getDeptList(params)
|
||||||
|
data.data = res.data
|
||||||
|
}
|
||||||
|
const params = reactive({
|
||||||
|
name: 'xiaoMa'
|
||||||
|
})
|
||||||
|
|
||||||
|
const loadDataTable = async(res) => {
|
||||||
|
const _params = {
|
||||||
|
...unref(params),
|
||||||
|
...res
|
||||||
|
}
|
||||||
|
return await getDeptList(_params)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fetchList()
|
||||||
|
})
|
||||||
|
|
||||||
|
return { data, loadDataTable }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
.n-button + .n-button {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,36 +1,185 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal :options="getModalOptions" @on-close="handleClose">
|
<Modal
|
||||||
|
:options="getModalOptions"
|
||||||
|
:on-close="handleClose"
|
||||||
|
:on-positive-click="handleConfirm"
|
||||||
|
:on-negative-click="handleClose"
|
||||||
|
>
|
||||||
<template #Context>
|
<template #Context>
|
||||||
111
|
<n-form ref="formRef" :model="menuForm" :rules="menuRules" 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="请选择上级菜单"
|
||||||
|
:options="getMenuList"
|
||||||
|
/>
|
||||||
|
</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">
|
||||||
|
{{ item.label }}
|
||||||
|
</n-radio>
|
||||||
|
</n-radio-group>
|
||||||
|
</n-form-item>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi>
|
||||||
|
<n-form-item label="菜单名称" path="title">
|
||||||
|
<n-input v-model:value="menuForm.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">
|
||||||
|
{{ item.label }}
|
||||||
|
</n-radio>
|
||||||
|
</n-radio-group>
|
||||||
|
</n-form-item>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi>
|
||||||
|
<n-form-item label="菜单图标" path="icon">
|
||||||
|
<n-input v-model:value="menuForm.icon" placeholder="请选择菜单图标" />
|
||||||
|
</n-form-item>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi>
|
||||||
|
<n-form-item label="权限标识" path="permission">
|
||||||
|
<n-input v-model:value="menuForm.permission" placeholder="请输入权限标识" />
|
||||||
|
</n-form-item>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi>
|
||||||
|
<n-form-item label="路由地址" path="path">
|
||||||
|
<n-input v-model:value="menuForm.path" placeholder="请输入路由地址" />
|
||||||
|
</n-form-item>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi>
|
||||||
|
<n-form-item label="排序号" path="sort">
|
||||||
|
<n-input v-model:value="menuForm.sort" placeholder="请输入排序号" />
|
||||||
|
</n-form-item>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi>
|
||||||
|
<n-form-item label="组件路径" path="component">
|
||||||
|
<n-input v-model:value="menuForm.component" 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">
|
||||||
|
{{ item.label }}
|
||||||
|
</n-radio>
|
||||||
|
</n-radio-group>
|
||||||
|
</n-form-item>
|
||||||
|
</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">
|
||||||
|
{{ item.label }}
|
||||||
|
</n-radio>
|
||||||
|
</n-radio-group>
|
||||||
|
</n-form-item>
|
||||||
|
</n-gi>
|
||||||
|
|
||||||
|
</n-grid>
|
||||||
|
</n-form>
|
||||||
</template>
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, computed } from 'vue'
|
import { defineComponent, computed, reactive, toRefs, ref } from 'vue'
|
||||||
import Modal from '@/components/CardModal/index.vue'
|
import Modal from '@/components/Modal/index.vue'
|
||||||
|
import { addMenu } from '@/api/system/menu/index.js'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'MenuModal',
|
name: 'MenuModal',
|
||||||
components: { Modal },
|
components: { Modal },
|
||||||
props: {
|
props: {
|
||||||
|
/* 可见 */
|
||||||
visible: {
|
visible: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
row: {
|
/* 选中的数据 */
|
||||||
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {}
|
default: () => {}
|
||||||
|
},
|
||||||
|
menuList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
'update:visible': null,
|
'update:visible': null
|
||||||
onClose: null,
|
|
||||||
done: null
|
|
||||||
},
|
},
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
|
const data = reactive({
|
||||||
|
menuForm: {
|
||||||
|
pid: null,
|
||||||
|
type: '0',
|
||||||
|
title: '',
|
||||||
|
target: '0',
|
||||||
|
icon: '',
|
||||||
|
permission: '',
|
||||||
|
path: '',
|
||||||
|
sort: '',
|
||||||
|
component: '',
|
||||||
|
hide: '0',
|
||||||
|
status: '1'
|
||||||
|
},
|
||||||
|
menuRules: {
|
||||||
|
title: {
|
||||||
|
required: true,
|
||||||
|
message: '请输入菜单名称',
|
||||||
|
trigger: ['blur']
|
||||||
|
},
|
||||||
|
sort: {
|
||||||
|
required: true,
|
||||||
|
message: '请输入排序号',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
typeOptions: [
|
||||||
|
{ key: '0', label: '菜单' },
|
||||||
|
{ key: '1', label: '按钮' }
|
||||||
|
],
|
||||||
|
openOptions: [
|
||||||
|
{ key: '0', label: '组件' },
|
||||||
|
{ key: '1', label: '内链' },
|
||||||
|
{ key: '2', label: '外链' }
|
||||||
|
],
|
||||||
|
visibleOptions: [
|
||||||
|
{ key: '0', label: '可见' },
|
||||||
|
{ key: '1', label: '不可见' }
|
||||||
|
],
|
||||||
|
statusOptions: [
|
||||||
|
{ key: '1', label: '在用' },
|
||||||
|
{ key: '2', label: '停用' }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const getMenuList = computed(() => {
|
||||||
|
const list = props.menuList.map((item) => {
|
||||||
|
const menu = {
|
||||||
|
label: item.title,
|
||||||
|
value: item.pid
|
||||||
|
}
|
||||||
|
return menu
|
||||||
|
})
|
||||||
|
return list
|
||||||
|
})
|
||||||
|
|
||||||
const getModalOptions = computed(() => {
|
const getModalOptions = computed(() => {
|
||||||
return {
|
return {
|
||||||
show: props.visible
|
show: props.visible,
|
||||||
|
title: props.data ? '修改菜单' : '新建菜单',
|
||||||
|
width: 700,
|
||||||
|
negativeText: '取消',
|
||||||
|
positiveText: '确认'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -38,10 +187,31 @@ export default defineComponent({
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
emit('update:visible', false)
|
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 {
|
return {
|
||||||
|
...toRefs(data),
|
||||||
|
formRef,
|
||||||
|
getMenuList,
|
||||||
getModalOptions,
|
getModalOptions,
|
||||||
handleClose
|
handleClose,
|
||||||
|
handleConfirm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<n-card>
|
<n-card>
|
||||||
<data-table :columns="data.columns" :pagination="false" :data="data.data" size="large">
|
<data-table :columns="data.columns" :pagination="false" :data="data.data" size="large" @fetch-success="getFechData">
|
||||||
<template #tableTitle>
|
<template #tableTitle>
|
||||||
<n-button type="primary" @click="handlleRoleAdd">
|
<n-button type="primary" @click="handlleRoleAdd">
|
||||||
添加菜单
|
添加菜单
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
</n-card>
|
</n-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<RoleModal v-model:visible="data.modalShow" />
|
<RoleModal v-model:visible="data.modalShow" :data="data.selectRow" :menu-list="data.data" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -119,10 +119,9 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
data: [
|
data: [],
|
||||||
|
modalShow: false,
|
||||||
],
|
selectRow: null
|
||||||
modalShow: false
|
|
||||||
})
|
})
|
||||||
|
|
||||||
function play(row) {
|
function play(row) {
|
||||||
|
|
@ -141,11 +140,24 @@ export default {
|
||||||
data.modalShow = true
|
data.modalShow = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 获取表单数据
|
||||||
|
* @param {*} data
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
function getFechData(data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchList()
|
fetchList()
|
||||||
})
|
})
|
||||||
|
|
||||||
return { data, handlleRoleAdd }
|
return {
|
||||||
|
data,
|
||||||
|
handlleRoleAdd,
|
||||||
|
getFechData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
import headSearch from '@/components/Search/index.vue'
|
import headSearch from '@/components/Search/index.vue'
|
||||||
import dataTable from '@/components/DataTable/index.vue'
|
import dataTable from '@/components/DataTable/index.vue'
|
||||||
import TableAction from '@/components/DataTable/tools/Action.vue'
|
import TableAction from '@/components/DataTable/tools/Action.vue'
|
||||||
import { getUserList } from '@/api/system/index.js'
|
import { getRoleList } from '@/api/system/role/index'
|
||||||
import { h, ref, unref } from 'vue'
|
import { h, ref, unref } from 'vue'
|
||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
import table from './table.js'
|
import table from './table.js'
|
||||||
|
|
@ -96,7 +96,7 @@ export default {
|
||||||
...unref(params),
|
...unref(params),
|
||||||
...res
|
...res
|
||||||
}
|
}
|
||||||
return await getUserList(_params)
|
return await getRoleList(_params)
|
||||||
}
|
}
|
||||||
|
|
||||||
return { data, tableRef, loadDataTable, handleSearch }
|
return { data, tableRef, loadDataTable, handleSearch }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,260 @@
|
||||||
|
<template>
|
||||||
|
<Modal :options="getModalOptions" @on-close="handleClose">
|
||||||
|
<template #Context>
|
||||||
|
<n-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
label-placement="left"
|
||||||
|
:rules="rules"
|
||||||
|
>
|
||||||
|
<n-form-item
|
||||||
|
label="头像:"
|
||||||
|
path="avatar"
|
||||||
|
>
|
||||||
|
<uploadImage
|
||||||
|
:options="{
|
||||||
|
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
|
||||||
|
v-model:value="form.code"
|
||||||
|
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="username">
|
||||||
|
<n-input
|
||||||
|
v-model:value="form.username"
|
||||||
|
clearable
|
||||||
|
:maxlength="20"
|
||||||
|
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"
|
||||||
|
>
|
||||||
|
<n-input
|
||||||
|
v-model:value="form.password"
|
||||||
|
type="password"
|
||||||
|
:maxlength="20"
|
||||||
|
placeholder="请输入登录密码"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="用户类型" path="type">
|
||||||
|
<n-radio-group
|
||||||
|
v-model:value="form.type"
|
||||||
|
>
|
||||||
|
<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"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
:maxlength="200"
|
||||||
|
placeholder="请输入备注"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
</n-form>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, computed, onMounted, reactive } 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 { dataToSelect } from '@/utils/handleData.js'
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'UserModal',
|
||||||
|
components: { Modal, uploadImage },
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
row: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '添加'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: {
|
||||||
|
'update:visible': null,
|
||||||
|
onClose: null,
|
||||||
|
done: null
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const getModalOptions = computed(() => {
|
||||||
|
return {
|
||||||
|
title: props.title,
|
||||||
|
show: props.visible
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/* 关闭弹窗 */
|
||||||
|
const handleClose = () => {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取角色列表
|
||||||
|
let rolesOptions = reactive([])
|
||||||
|
async function getRoleOptions() {
|
||||||
|
const res = await getRoleAll()
|
||||||
|
rolesOptions = dataToSelect(res.data, { label: 'name', value: 'id' })
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getDeptOptions()
|
||||||
|
getRoleOptions()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
const handleUpload = ({ file, event }) => {
|
||||||
|
console.log(event)
|
||||||
|
form.avatar = file.url
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
</style>
|
||||||
|
|
@ -1,29 +1,36 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<data-table :columns="data.columns" :data="data.data" :pagination="data.pagination" size="large" scroll-x="1200">
|
<n-card>
|
||||||
|
<data-table
|
||||||
|
:columns="data.columns"
|
||||||
|
:row-key="(row) => row.id"
|
||||||
|
:request="loadDataTable"
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
<template #tableTitle>
|
<template #tableTitle>
|
||||||
<n-button type="primary">
|
<n-button type="primary" @click="handleUser"> 新建 </n-button>
|
||||||
新建
|
<!-- <n-button type="primary" @click="deleteUsers"> 删除 </n-button> -->
|
||||||
</n-button>
|
|
||||||
<n-button type="primary">
|
|
||||||
删除
|
|
||||||
</n-button>
|
|
||||||
</template>
|
</template>
|
||||||
</data-table>
|
</data-table>
|
||||||
|
</n-card>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 新增、编辑弹窗 -->
|
||||||
|
<user-modal v-if="data.modalShow" v-model:visible="data.modalShow" :row="rowData" :title="modalTitle" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import dataTable from '@/components/DataTable/index.vue'
|
import dataTable from '@/components/DataTable/index.vue'
|
||||||
import TableAction from '@/components/DataTable/tools/Action.vue'
|
import TableAction from '@/components/DataTable/tools/Action.vue'
|
||||||
import TableImage from '@/components/DataTable/tools/Image.vue'
|
import TableImage from '@/components/DataTable/tools/Image.vue'
|
||||||
import { getUserList } from '@/api/system/index.js'
|
import TableTags from '@/components/DataTable/tools/Tags.vue'
|
||||||
import { h, onMounted } from '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 { reactive } from 'vue'
|
||||||
|
import UserModal from './components/UserModal.vue'
|
||||||
export default {
|
export default {
|
||||||
name: 'MenuPage',
|
name: 'MenuPage',
|
||||||
components: { dataTable },
|
components: { dataTable, UserModal },
|
||||||
setup() {
|
setup() {
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
columns: [
|
columns: [
|
||||||
|
|
@ -41,7 +48,7 @@ export default {
|
||||||
images: {
|
images: {
|
||||||
width: 36,
|
width: 36,
|
||||||
height: 36,
|
height: 36,
|
||||||
src: row.avatar
|
src: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQiKrYt-fEfJ4SZhF9KfLLaX9f15KV6Ve1ptA&usqp=CAU'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -65,14 +72,27 @@ export default {
|
||||||
{
|
{
|
||||||
title: '角色',
|
title: '角色',
|
||||||
key: 'roles',
|
key: 'roles',
|
||||||
align: 'center'
|
align: 'center',
|
||||||
|
render(row) {
|
||||||
|
return h(TableTags, {
|
||||||
|
data: row.roles
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '状态',
|
||||||
key: 'status',
|
key: 'status',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 100
|
width: 100,
|
||||||
|
render(row) {
|
||||||
|
return h(TableSwitch, {
|
||||||
|
data: row,
|
||||||
|
rowKey: 'status',
|
||||||
|
checkedValue: 1,
|
||||||
|
uncheckedValue: 2,
|
||||||
|
onChange: getSwitch.bind(row)
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '部门',
|
title: '部门',
|
||||||
|
|
@ -100,7 +120,7 @@ export default {
|
||||||
return h(TableAction, {
|
return h(TableAction, {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
label: '添加',
|
label: '修改',
|
||||||
type: 'button',
|
type: 'button',
|
||||||
props: {
|
props: {
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
|
|
@ -108,10 +128,6 @@ export default {
|
||||||
},
|
},
|
||||||
auth: 'basic_list'
|
auth: 'basic_list'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '修改',
|
|
||||||
auth: 'basic_list'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '删除',
|
label: '删除',
|
||||||
type: 'popconfirm',
|
type: 'popconfirm',
|
||||||
|
|
@ -123,37 +139,42 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
data: [],
|
modalShow: false
|
||||||
pagination: {
|
})
|
||||||
pageSize: 10
|
const modalTitle = ref('添加用户')
|
||||||
|
let rowData = reactive({})
|
||||||
|
// 打开编辑弹窗
|
||||||
|
function play(row) {
|
||||||
|
rowData = row
|
||||||
|
modalTitle.value = '编辑用户'
|
||||||
|
console.log('编辑弹窗内容:', row)
|
||||||
|
data.modalShow = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const params = reactive({
|
||||||
|
name: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
function play(row) {
|
const loadDataTable = async(res) => {
|
||||||
|
const _params = {
|
||||||
|
...unref(params),
|
||||||
|
...res
|
||||||
|
}
|
||||||
|
return await getUserList(_params)
|
||||||
|
}
|
||||||
|
function handleUser() {
|
||||||
|
rowData = {}
|
||||||
|
modalTitle.value = '添加用户'
|
||||||
|
data.modalShow = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSwitch(row) {
|
||||||
console.log(row)
|
console.log(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return { data, loadDataTable, handleUser, rowData, modalTitle }
|
||||||
* @description: 获取用户数据
|
|
||||||
* @return {*}
|
|
||||||
*/
|
|
||||||
async function fetchList() {
|
|
||||||
const params = {
|
|
||||||
page: 1,
|
|
||||||
limit: 10
|
|
||||||
}
|
|
||||||
const res = await getUserList(params)
|
|
||||||
data.data = res.data.list
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
fetchList()
|
|
||||||
})
|
|
||||||
|
|
||||||
return { data }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
.n-button + .n-button {
|
.n-button + .n-button {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue