Archer_cdm
2 years ago
25 changed files with 1757 additions and 5 deletions
@ -0,0 +1,87 @@ |
|||||
|
async function getResource(ctx, next) { |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
|
||||
|
const res = await models.Resource.findAll({ |
||||
|
where: { parentResource: null }, |
||||
|
include: [{ |
||||
|
model: models.Resource, |
||||
|
}] |
||||
|
}) |
||||
|
|
||||
|
ctx.body = res; |
||||
|
ctx.status = 200; |
||||
|
|
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": "查询所有权限数据失败" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
async function getUserResource(ctx, next) { |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const { userId } = ctx.query; |
||||
|
|
||||
|
const res = await models.UserResource.findAll({ |
||||
|
where: { userId: userId }, |
||||
|
include: [{ |
||||
|
model: models.Resource, |
||||
|
}] |
||||
|
}) |
||||
|
|
||||
|
ctx.body = res; |
||||
|
ctx.status = 200; |
||||
|
|
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": "查询用户权限数据失败" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function updateUserRes(ctx, next) { |
||||
|
const transaction = await ctx.fs.dc.orm.transaction(); |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const { userId, resCode } = ctx.request.body; |
||||
|
|
||||
|
const res = await models.UserResource.findAll({ |
||||
|
attributes: ["resourceId"], |
||||
|
raw: true, |
||||
|
where: { userId: userId } |
||||
|
}) |
||||
|
|
||||
|
const addRes = resCode.filter(r => !res.some(rr => rr.resourceId == r)).map(r => { return { userId: userId, resourceId: r } }); |
||||
|
const delRes = res.filter(r => !resCode.includes(r.resourceId)).map(r => r.resourceId); |
||||
|
addRes.length && await models.UserResource.bulkCreate(addRes, { transaction: transaction }); |
||||
|
delRes.length && await models.UserResource.destroy({ |
||||
|
where: { |
||||
|
resourceId: { $in: delRes }, |
||||
|
userId: userId |
||||
|
}, |
||||
|
transaction: transaction |
||||
|
}) |
||||
|
|
||||
|
ctx.status = 204; |
||||
|
await transaction.commit(); |
||||
|
|
||||
|
} catch (error) { |
||||
|
await transaction.rollback(); |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": "更新用户权限数据失败" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
getResource, |
||||
|
getUserResource, |
||||
|
updateUserRes |
||||
|
}; |
@ -0,0 +1,373 @@ |
|||||
|
'use strict'; |
||||
|
const Hex = require('crypto-js/enc-hex'); |
||||
|
const MD5 = require('crypto-js/md5'); |
||||
|
|
||||
|
// async function getDepMessage (ctx, next) {
|
||||
|
// try {
|
||||
|
// const { fs: { api: { userInfo } } } = ctx
|
||||
|
// const models = ctx.fs.dc.models;
|
||||
|
|
||||
|
// let deptWhere = {}
|
||||
|
// if (userInfo.username !== 'SuperAdmin') {
|
||||
|
// deptWhere.id = userInfo.departmentId
|
||||
|
// }
|
||||
|
// let depType1 = await models.Department.findAll({
|
||||
|
// order: [['id', 'asc']],
|
||||
|
// // include: [{
|
||||
|
// // model: models.User,
|
||||
|
// // required: false,
|
||||
|
// // where: { delete: false },
|
||||
|
// // attributes: { exclude: ['password'] },
|
||||
|
// // }],
|
||||
|
// where: deptWhere,
|
||||
|
// })
|
||||
|
|
||||
|
// let depRslt = []
|
||||
|
// const getDep = async (d) => {
|
||||
|
// let subordinate = []
|
||||
|
// let depRes = await models.Department.findAll({
|
||||
|
// order: [['id', 'asc']],
|
||||
|
// // include: [{
|
||||
|
// // model: models.User,
|
||||
|
// // required: false,
|
||||
|
// // where: { delete: false },
|
||||
|
// // attributes: { exclude: ['password'] },
|
||||
|
// // }],
|
||||
|
// where: {
|
||||
|
// dependence: d.id
|
||||
|
// },
|
||||
|
// })
|
||||
|
// if (depRes.length)
|
||||
|
// for (let d of depRes) {
|
||||
|
// let dep = d.dataValues
|
||||
|
// dep.subordinate = await getDep(d.dataValues)
|
||||
|
// subordinate.push(dep)
|
||||
|
// }
|
||||
|
// return subordinate
|
||||
|
// }
|
||||
|
// for (let d of depType1) {
|
||||
|
// let dep_1 = d.dataValues
|
||||
|
// dep_1.subordinate = await getDep(d.dataValues)
|
||||
|
// depRslt.push(dep_1)
|
||||
|
// }
|
||||
|
|
||||
|
// ctx.status = 200;
|
||||
|
// ctx.body = depRslt
|
||||
|
// } catch (error) {
|
||||
|
// ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
|
||||
|
// ctx.status = 400;
|
||||
|
// ctx.body = {
|
||||
|
// "message": "获取部门信息失败"
|
||||
|
// }
|
||||
|
// }
|
||||
|
// }
|
||||
|
|
||||
|
async function getDepMessage(ctx, next) { |
||||
|
let error = { name: 'FindError', message: '获取部门列表失败' }; |
||||
|
let rslt = []; |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
let list = await models.Department.findAll({}); |
||||
|
|
||||
|
let deptMap = [] |
||||
|
list.filter(l => !l.dependence).map(ld => {//一级
|
||||
|
deptMap.push({ |
||||
|
id: ld.id, |
||||
|
name: ld.name, |
||||
|
dependence: ld.dependence, |
||||
|
subordinate: [] |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
list.filter(l => l.dependence).map(ld => {//二级
|
||||
|
let parent = deptMap.find(dm => dm.id == ld.dependence); |
||||
|
if (parent) { |
||||
|
parent.subordinate.push({ |
||||
|
id: ld.id, |
||||
|
name: ld.name, |
||||
|
dependence: ld.dependence, |
||||
|
subordinate: [] |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
rslt = deptMap; |
||||
|
|
||||
|
error = null; |
||||
|
} catch (err) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); |
||||
|
} |
||||
|
if (error) { |
||||
|
ctx.status = 400; |
||||
|
ctx.body = error; |
||||
|
} else { |
||||
|
ctx.status = 200; |
||||
|
ctx.body = rslt; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function createDept(ctx, next) { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
try { |
||||
|
let rslt = ctx.request.body; |
||||
|
await models.Department.create(Object.assign({}, rslt, { read: 1 })) |
||||
|
ctx.status = 204; |
||||
|
ctx.body = { message: '新建部门成功' } |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { message: '新建部门失败' } |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function updateDept(ctx, next) { |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const { id } = ctx.params; |
||||
|
const body = ctx.request.body; |
||||
|
await models.Department.update( |
||||
|
body, |
||||
|
{ where: { id: id } } |
||||
|
) |
||||
|
ctx.status = 204; |
||||
|
ctx.body = { message: '修改部门成功' } |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { message: '修改部门失败' } |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function delDept(ctx, next) { |
||||
|
let errMsg = "删除部门失败"; |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const { id } = ctx.params; |
||||
|
let list = await models.Department.findAll({}); |
||||
|
let deptIds = list.map(l => l.id); |
||||
|
const allUsers = await models.User.findAll({ |
||||
|
where: { |
||||
|
departmentId: { $in: deptIds }, |
||||
|
delete: false |
||||
|
} |
||||
|
}) |
||||
|
const childrenDept = await models.Department.findAll({ where: { dependence: id } }) |
||||
|
const childrenUser = allUsers.filter(au => au.departmentId == id); |
||||
|
if (childrenUser.length || childrenDept.length) { |
||||
|
errMsg = '请先删除部门下的用户或子部门'; |
||||
|
throw errMsg; |
||||
|
} |
||||
|
await models.Department.destroy({ where: { id: id } }); |
||||
|
await models.Department.destroy({ where: { dependence: id } }); |
||||
|
ctx.status = 204; |
||||
|
ctx.body = { message: '删除部门成功' } |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { message: error } |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function getUser(ctx, next) { |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const { depId } = ctx.params |
||||
|
const userRes = await models.User.findAll({ |
||||
|
where: { |
||||
|
departmentId: parseInt(depId), |
||||
|
delete: false |
||||
|
}, |
||||
|
attributes: { exclude: ['password'] }, |
||||
|
order: [['id', 'asc']], |
||||
|
}) |
||||
|
|
||||
|
ctx.status = 200; |
||||
|
ctx.body = userRes |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": "获取用户信息失败" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function creatUser(ctx, next) { |
||||
|
let errMsg = "新建用户失败" |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const data = ctx.request.body; |
||||
|
|
||||
|
let repeatUserNameCount = await models.User.count({ |
||||
|
where: { |
||||
|
username: data.phone, |
||||
|
delete: false |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
if (repeatUserNameCount) { |
||||
|
errMsg = '已有当前用户名' |
||||
|
throw errMsg |
||||
|
} |
||||
|
|
||||
|
await models.User.create({ |
||||
|
name: data.name, |
||||
|
username: data.phone, |
||||
|
password: Hex.stringify(MD5(data.password)), |
||||
|
departmentId: data.departmentId, |
||||
|
email: data.email, |
||||
|
enable: data.enable, |
||||
|
delete: false, |
||||
|
phone: data.phone, |
||||
|
post: data.post, |
||||
|
}) |
||||
|
|
||||
|
ctx.status = 204; |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": errMsg |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
async function updateUser(ctx, next) { |
||||
|
let errMsg = "修改用户失败" |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const data = ctx.request.body; |
||||
|
const { id } = ctx.params; |
||||
|
|
||||
|
let repeatUserNameCount = await models.User.count({ |
||||
|
where: { |
||||
|
username: data.username |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
if (repeatUserNameCount) { |
||||
|
errMsg = '已有当前用户名' |
||||
|
throw errMsg |
||||
|
} |
||||
|
|
||||
|
await models.User.update({ |
||||
|
name: data.name, |
||||
|
username: data.phone, |
||||
|
departmentId: data.departmentId, |
||||
|
email: data.email, |
||||
|
enable: data.enable, |
||||
|
delete: false, |
||||
|
phone: data.phone, |
||||
|
post: data.post, |
||||
|
}, { |
||||
|
where: { |
||||
|
id: id |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
ctx.status = 204; |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": errMsg |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function deleteUser(ctx, next) { |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const { ids } = ctx.params; |
||||
|
const userIds = ids.split(','); |
||||
|
await models.User.update({ |
||||
|
delete: true, |
||||
|
}, { |
||||
|
where: { |
||||
|
id: { $in: userIds }, |
||||
|
} |
||||
|
}); |
||||
|
ctx.status = 204; |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": "删除用户失败" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function resetPwd(ctx, next) { |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const { id } = ctx.params; |
||||
|
const data = ctx.request.body; |
||||
|
await models.User.update({ |
||||
|
password: Hex.stringify(MD5(data.password)), |
||||
|
}, { |
||||
|
where: { |
||||
|
id: id, |
||||
|
} |
||||
|
}); |
||||
|
ctx.status = 204; |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": "重置用户密码失败" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改用户密码 |
||||
|
* @params {userId-用户Id} ctx |
||||
|
* @request.body {password-用户新密码} ctx |
||||
|
*/ |
||||
|
async function updateUserPassword(ctx, next) { |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models; |
||||
|
const { userId } = ctx.params; |
||||
|
const { password } = ctx.request.body; |
||||
|
if (!password) { |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { "message": "请输入修改密码" }; |
||||
|
return; |
||||
|
} |
||||
|
const userRes = await models.User.findOne({ |
||||
|
where: { |
||||
|
id: userId |
||||
|
}, |
||||
|
attributes: ['id'] |
||||
|
}); |
||||
|
if (userRes) { |
||||
|
await models.User.update({ password: Hex.stringify(MD5(password)) }, { where: { id: userId, } }); |
||||
|
ctx.status = 204; |
||||
|
} else { |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": "用户不存在" |
||||
|
} |
||||
|
} |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { |
||||
|
"message": "修改用户密码失败" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
module.exports = { |
||||
|
getDepMessage, |
||||
|
createDept, |
||||
|
updateDept, |
||||
|
delDept, |
||||
|
getUser, |
||||
|
creatUser, |
||||
|
updateUser, |
||||
|
deleteUser, |
||||
|
resetPwd, |
||||
|
updateUserPassword |
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
const Authority = require('../../controllers/organization/authority'); |
||||
|
|
||||
|
module.exports = function (app, router, opts) { |
||||
|
/** |
||||
|
* @api {GET} resource 查询所有权限码. |
||||
|
* @apiVersion 1.0.0 |
||||
|
* @apiGroup Org |
||||
|
*/ |
||||
|
app.fs.api.logAttr['GET/resource'] = { content: '查询所有权限码', visible: true }; |
||||
|
router.get('resource', Authority.getResource); |
||||
|
/** |
||||
|
* @api {GET} user/resource 查询用户权限. |
||||
|
* @apiVersion 1.0.0 |
||||
|
* @apiGroup Org |
||||
|
*/ |
||||
|
app.fs.api.logAttr['GET/user/resource'] = { content: '查询用户权限', visible: true }; |
||||
|
router.get('user/resource', Authority.getUserResource); |
||||
|
|
||||
|
/** |
||||
|
* @api {POST} user/resource 更新用户权限. |
||||
|
* @apiVersion 1.0.0 |
||||
|
* @apiGroup Org |
||||
|
*/ |
||||
|
app.fs.api.logAttr['POST/user/resource'] = { content: '更新用户权限', visible: true }; |
||||
|
router.post('user/resource', Authority.updateUserRes); |
||||
|
}; |
@ -0,0 +1,41 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
const user = require('../../controllers/organization/user'); |
||||
|
|
||||
|
module.exports = function (app, router, opts) { |
||||
|
|
||||
|
app.fs.api.logAttr['GET/organization/department'] = { content: '获取部门信息', visible: false }; |
||||
|
router.get('/organization/department', user.getDepMessage); |
||||
|
|
||||
|
app.fs.api.logAttr['POST/organization/dept/add'] = { content: '新增部门', visible: true }; |
||||
|
router.post('/organization/dept/add', user.createDept); |
||||
|
|
||||
|
app.fs.api.logAttr['PUT/organization/dept/:id/modify'] = { content: '修改部门', visible: true }; |
||||
|
router.put('/organization/dept/:id/modify', user.updateDept); |
||||
|
|
||||
|
app.fs.api.logAttr['DELETE/organization/dept/:id'] = { content: '删除部门', visible: true }; |
||||
|
router.del('/organization/dept/:id', user.delDept); |
||||
|
|
||||
|
app.fs.api.logAttr['GET/organization/department/:depId/user'] = { content: '获取部门下用户信息', visible: false }; |
||||
|
router.get('/organization/department/:depId/user', user.getUser); |
||||
|
|
||||
|
app.fs.api.logAttr['POST/organization/department/user'] = { content: '创建部门下用户信息', visible: false }; |
||||
|
router.post('/organization/department/user', user.creatUser); |
||||
|
|
||||
|
app.fs.api.logAttr['PUT/organization/department/user/:id'] = { content: '修改部门下用户信息', visible: false }; |
||||
|
router.put('/organization/department/user/:id', user.updateUser); |
||||
|
|
||||
|
app.fs.api.logAttr['DEL/organization/department/user/:ids'] = { content: '删除部门下用户信息', visible: false }; |
||||
|
router.del('/organization/department/user/:ids', user.deleteUser); |
||||
|
|
||||
|
app.fs.api.logAttr['PUT/organization/department/user/resetPwd/:id'] = { content: '重置用户密码', visible: false }; |
||||
|
router.put('/organization/department/user/resetPwd/:id', user.resetPwd); |
||||
|
|
||||
|
/** |
||||
|
* @api {PUT} user/password/:id 修改用户密码 |
||||
|
* @apiVersion 1.0.0 |
||||
|
* @apiGroup Organization |
||||
|
*/ |
||||
|
app.fs.api.logAttr['PUT/user/password/:userId'] = { content: '修改用户密码', visible: false }; |
||||
|
router.put('/user/password/:userId', user.updateUserPassword); |
||||
|
}; |
@ -1 +1 @@ |
|||||
INSERT INTO "public"."user" VALUES (1, '管理员', 'SuperAdmin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL, 't', 'f', '123456789', NULL); |
INSERT INTO "public"."user" VALUES (default, '管理员', 'SuperAdmin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL, 't', 'f', '123456789', NULL); |
||||
|
@ -0,0 +1,11 @@ |
|||||
|
INSERT INTO "public"."resource" VALUES ('STRUCTURE_MANAGE', '结构物管理', NULL); |
||||
|
INSERT INTO "public"."resource" VALUES ('STRU_INFO_CONFIG', '基础信息维护', 'STRUCTURE_MANAGE'); |
||||
|
INSERT INTO "public"."resource" VALUES ('QR_CODE_CONFIG', '二维码管理', 'STRUCTURE_MANAGE'); |
||||
|
INSERT INTO "public"."resource" VALUES ('PATROL_MANAGE', '巡检管理', NULL); |
||||
|
INSERT INTO "public"."resource" VALUES ('PATROL_PLAN_CONFIG', '巡检计划制订', 'PATROL_MANAGE'); |
||||
|
INSERT INTO "public"."resource" VALUES ('PATROL_RECORD_VIEW', '巡检记录查看', 'PATROL_MANAGE'); |
||||
|
INSERT INTO "public"."resource" VALUES ('REPAIR_MANAGE', '维修处理', NULL); |
||||
|
INSERT INTO "public"."resource" VALUES ('HANDLE_REPAIR', '维修处理', 'REPAIR_MANAGE'); |
||||
|
INSERT INTO "public"."resource" VALUES ('ORG_MANAGE', '组织管理', NULL); |
||||
|
INSERT INTO "public"."resource" VALUES ('USER_CONFIG', '部门成员', 'ORG_MANAGE'); |
||||
|
INSERT INTO "public"."resource" VALUES ('AUTH_CONFIG', '权限配置', 'ORG_MANAGE'); |
@ -0,0 +1,11 @@ |
|||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'STRUCTURE_MANAGE'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'STRU_INFO_CONFIG'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'QR_CODE_CONFIG'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'PATROL_MANAGE'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'PATROL_PLAN_CONFIG'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'PATROL_RECORD_VIEW'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'REPAIR_MANAGE'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'HANDLE_REPAIR'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'ORG_MANAGE'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'USER_CONFIG'); |
||||
|
INSERT INTO "public"."user_resource" VALUES (default, 1, 'AUTH_CONFIG'); |
@ -0,0 +1,51 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
import { basicAction } from '@peace/utils' |
||||
|
import { ApiTable } from '$utils' |
||||
|
|
||||
|
export function getAuthority(orgId) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'get', |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'GET_MEMBERS', |
||||
|
url: `${ApiTable.getEnterprisesMembers.replace('{enterpriseId}', orgId)}`, |
||||
|
msg: { error: '获取用户列表失败' }, |
||||
|
reducer: { name: 'members' } |
||||
|
}); |
||||
|
} |
||||
|
export function getResource(userId) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'get', |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'GET_RESOURCE', |
||||
|
url: `${ApiTable.getResource}`, |
||||
|
msg: { error: '获取权限失败' }, |
||||
|
reducer: { name: 'resource' } |
||||
|
}); |
||||
|
} |
||||
|
export function getUserResource(userId) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'get', |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'GET_USER_RESOURCE', |
||||
|
url: `${ApiTable.getUserResource}?userId=${userId}`, |
||||
|
msg: { error: '获取用户权限失败' }, |
||||
|
reducer: { name: 'userResource' } |
||||
|
}); |
||||
|
} |
||||
|
export function postUserRes(body) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'post', |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'UPDATE_USER_RESOURCE', |
||||
|
url: `${ApiTable.postUserRes}`, |
||||
|
data: body, |
||||
|
msg: { success: '更新用户权限' } |
||||
|
}); |
||||
|
} |
||||
|
export default { |
||||
|
getAuthority, |
||||
|
getResource, |
||||
|
getUserResource, |
||||
|
postUserRes |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
import * as authority from './authority' |
||||
|
import { getDepMessage, getDepUser, createUser } from './user' |
||||
|
|
||||
|
export default { |
||||
|
...authority, |
||||
|
getDepMessage, |
||||
|
getDepUser, |
||||
|
createUser, |
||||
|
} |
@ -0,0 +1,113 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
import { basicAction } from '@peace/utils' |
||||
|
import { ApiTable } from '$utils' |
||||
|
|
||||
|
export function getDepMessage() { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'get', |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'GET_DEPARTMENT_MESSAGE', |
||||
|
url: ApiTable.getDepMessage, |
||||
|
msg: { error: '获取部门信息失败' }, |
||||
|
reducer: { name: 'depMessage' } |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
//新建部门
|
||||
|
export function createDept(data) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'post', |
||||
|
data, |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'CREATE_DEPT', |
||||
|
url: ApiTable.createDept, |
||||
|
msg: { option: '新建部门' }, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
//修改部门
|
||||
|
export function updateDept(id, data) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'put', |
||||
|
data, |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'UPDATE_DEPT', |
||||
|
url: ApiTable.updateDept.replace('{id}', id), |
||||
|
msg: { option: '修改部门' }, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
//删除部门
|
||||
|
export function delDept(id) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'del', |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'DEL_DEPT', |
||||
|
url: ApiTable.delDept.replace('{id}', id), |
||||
|
msg: { option: '删除部门' }, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function getDepUser(depId) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'get', |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'GET_DEPARTMENT_USER', |
||||
|
url: ApiTable.getDepUser.replace('{depId}', depId), |
||||
|
msg: { error: '获取部门下用户信息失败' }, |
||||
|
reducer: { name: 'depUser' } |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function createUser(data) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'post', |
||||
|
data, |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'CREATE_DEPARTMENT_USER', |
||||
|
url: ApiTable.createUser, |
||||
|
msg: { option: '新建用户' }, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function updateUser(id, data) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'put', |
||||
|
data, |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'UPDATE_DEPARTMENT_USER', |
||||
|
url: ApiTable.updateUser.replace('{id}', id), |
||||
|
msg: { option: '修改用户' }, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function delUser(ids) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'del', |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'DEL_DEPARTMENT_USER', |
||||
|
url: ApiTable.delUser.replace('{ids}', ids), |
||||
|
msg: { option: '删除用户' }, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function resetPwd(id, data) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'put', |
||||
|
data, |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'CREATE_DEPARTMENT_USER', |
||||
|
url: ApiTable.resetPwd.replace('{id}', id), |
||||
|
msg: { option: '重置用户密码' }, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export default { |
||||
|
getDepMessage, |
||||
|
getDepUser, |
||||
|
createUser, |
||||
|
updateUser, |
||||
|
delUser, |
||||
|
resetPwd |
||||
|
} |
@ -0,0 +1,88 @@ |
|||||
|
import React from 'react'; |
||||
|
import { connect } from 'react-redux'; |
||||
|
import { ProFormText, ModalForm, ProFormSelect } from '@ant-design/pro-form'; |
||||
|
|
||||
|
const DeptModal = (props) => { |
||||
|
const { visible, modalType, onVisibleChange, onConfirm, editData, depts } = props |
||||
|
let deptOptions = [], sonArr = []; |
||||
|
depts.map(d => { |
||||
|
deptOptions.push({ |
||||
|
value: d.id, |
||||
|
label: d.name |
||||
|
}); |
||||
|
|
||||
|
d.subordinate.map(ds => { |
||||
|
sonArr.push({ |
||||
|
value: ds.id, |
||||
|
label: ds.name |
||||
|
}) |
||||
|
}) |
||||
|
}) |
||||
|
const onFinish = (values) => { |
||||
|
if (onConfirm) { |
||||
|
if (modalType === 'edit') { |
||||
|
values.contract.parentDeptId = values.contract.parentDeptId || null |
||||
|
onConfirm(values) |
||||
|
} else { |
||||
|
onConfirm(values); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const checkName = (rule, value, callback) => { |
||||
|
const list = modalType == 'edit' ? deptOptions.concat(sonArr).filter(g => g.value != editData.id) : deptOptions.concat(sonArr) |
||||
|
if (list.filter(s => s.label == value).length) { |
||||
|
callback('该名称已存在'); |
||||
|
} else { |
||||
|
callback(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<ModalForm |
||||
|
width={400} |
||||
|
title={modalType == 'edit' ? '编辑部门' : '新建部门'} |
||||
|
visible={visible} |
||||
|
onVisibleChange={onVisibleChange} |
||||
|
onFinish={onFinish} |
||||
|
destroyOnClose |
||||
|
initialValues={ |
||||
|
modalType == 'edit' ? |
||||
|
{ |
||||
|
contract: editData |
||||
|
} : |
||||
|
{ |
||||
|
contract: { |
||||
|
enable: true |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
> |
||||
|
<ProFormText |
||||
|
name={['contract', 'name']} |
||||
|
maxLength={24} |
||||
|
width="md" |
||||
|
label="部门名称" |
||||
|
required |
||||
|
placeholder="请输入部门名称" |
||||
|
rules={[{ required: true, message: '请输入部门名称' }, { validator: checkName }]} |
||||
|
/> |
||||
|
<ProFormSelect |
||||
|
name={['contract', 'dependence']} |
||||
|
label="上级部门" |
||||
|
request={async () => { |
||||
|
let t = modalType === 'edit' ? deptOptions.filter(i => i.value !== editData.id) : deptOptions |
||||
|
return t |
||||
|
}} |
||||
|
disabled={modalType === 'edit' ? editData.subordinate?.length === 0 ? false : true : false} |
||||
|
/> |
||||
|
</ModalForm> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function mapStateToProps(state) { |
||||
|
return { |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(DeptModal); |
@ -0,0 +1,74 @@ |
|||||
|
import React, { useRef, useState } from 'react'; |
||||
|
import { connect } from 'react-redux'; |
||||
|
import { Spin, Card, Modal, TreeSelect } from 'antd'; |
||||
|
import ProForm, { ProFormText, ModalForm, ProFormSwitch, ProFormTreeSelect } from '@ant-design/pro-form'; |
||||
|
|
||||
|
const ResetPwd = (props) => { |
||||
|
const { visible, onVisibleChange, onConfirm } = props; |
||||
|
const formRef = useRef(); |
||||
|
|
||||
|
const onFinish = (values) => { |
||||
|
if (onConfirm) { |
||||
|
onConfirm(values); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<Spin spinning={false}> |
||||
|
<ModalForm |
||||
|
title={'重置密码'} |
||||
|
visible={visible} |
||||
|
onVisibleChange={onVisibleChange} |
||||
|
onFinish={onFinish} |
||||
|
formRef={formRef} |
||||
|
destroyOnClose |
||||
|
> |
||||
|
<ProFormText.Password |
||||
|
name={['password']} |
||||
|
width="md" |
||||
|
label="新密码" |
||||
|
required |
||||
|
placeholder="请输入密码" |
||||
|
fieldProps={{ |
||||
|
autocomplete: 'new-password' |
||||
|
}} |
||||
|
rules={[ |
||||
|
{ required: true, message: '请填写密码' }, |
||||
|
{ min: 6, message: '请填写至少6位密码' }, |
||||
|
]} |
||||
|
/> |
||||
|
<ProFormText.Password |
||||
|
name={['checkPassword']} |
||||
|
width="md" |
||||
|
label="确认密码" |
||||
|
required |
||||
|
autocomplete='off' |
||||
|
placeholder="请输入密码" |
||||
|
rules={[ |
||||
|
{ required: true, message: '请再次填写密码' }, |
||||
|
{ min: 6, message: '请填写至少6位密码' }, |
||||
|
{ |
||||
|
validator: (rule, value, callback) => { |
||||
|
const pwd = formRef.current.getFieldValue('password'); |
||||
|
if (!value) { |
||||
|
callback(); |
||||
|
} |
||||
|
if (pwd == value) { |
||||
|
callback(); |
||||
|
} else { |
||||
|
callback('两次输入的密码不一致'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
]} |
||||
|
/> |
||||
|
</ModalForm> |
||||
|
</Spin> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function mapStateToProps(state) { |
||||
|
return {}; |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(ResetPwd); |
@ -0,0 +1,121 @@ |
|||||
|
import React, { useEffect } from 'react'; |
||||
|
import { Checkbox, Table } from 'antd'; |
||||
|
import { useState } from 'react'; |
||||
|
|
||||
|
const CheckboxGroup = Checkbox.Group; |
||||
|
|
||||
|
const Resource = props => { |
||||
|
const { roleData, userRole, userSelected, setResCode, userType } = props; |
||||
|
const [indeterminate, setIndeterminate] = useState({}); |
||||
|
const [roleCheck, setRoleCheck] = useState({});//一级权限码
|
||||
|
const [parentRoleCheck, setParentRoleCheck] = useState({}); //二级权限码
|
||||
|
|
||||
|
const roleDatas=roleData.slice(0) |
||||
|
useEffect(() => { |
||||
|
const check = {} |
||||
|
const parentCheck = {} |
||||
|
const initInd = {} |
||||
|
roleData && roleData.map && roleData.map(r => { |
||||
|
let currentInd = false; |
||||
|
let sum = 0; |
||||
|
if (r.resources) { |
||||
|
check[r.code] = [] |
||||
|
r.resources.map(child => { |
||||
|
if (userRole.find(code => code.resourceId == child.code)) { |
||||
|
currentInd = true; |
||||
|
sum++; |
||||
|
check[r.code].push(child.code); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
parentCheck[r.code] = r.resources.length === sum |
||||
|
initInd[r.code] = parentCheck[r.code] ? false : currentInd |
||||
|
}); |
||||
|
setParentRoleCheck(parentCheck) |
||||
|
setRoleCheck(check); |
||||
|
setIndeterminate(initInd); |
||||
|
}, [userRole]); |
||||
|
|
||||
|
const setResData = (role) => { |
||||
|
let codes = []; |
||||
|
// Object.keys(partRole).map(r => {
|
||||
|
// if (partRole[r]) codes.push(r)
|
||||
|
// })
|
||||
|
Object.keys(role).map(r => { |
||||
|
if (role[r].length) { |
||||
|
codes.push(r); |
||||
|
} |
||||
|
codes = codes.concat(role[r]) |
||||
|
}) |
||||
|
setResCode(codes) |
||||
|
} |
||||
|
return ( |
||||
|
<Table |
||||
|
bordered |
||||
|
pagination={false} |
||||
|
dataSource={roleDatas} |
||||
|
columns={[{ |
||||
|
title: '功能', |
||||
|
key: 'name', |
||||
|
dataIndex: 'name', |
||||
|
render: (text, record) => { |
||||
|
const parentCode = record.code |
||||
|
return <Checkbox |
||||
|
|
||||
|
indeterminate={indeterminate[parentCode]} |
||||
|
onChange={(e) => { |
||||
|
const currentParCheck = JSON.parse(JSON.stringify(parentRoleCheck)); |
||||
|
currentParCheck[parentCode] = e.target.checked; |
||||
|
const currentCode = JSON.parse(JSON.stringify(roleCheck)); |
||||
|
currentCode[parentCode] = e.target.checked ? roleData.find(r => r.code == parentCode).resources.map(r => r.code) : [] |
||||
|
const currentInd = JSON.parse(JSON.stringify(indeterminate)); |
||||
|
currentInd[parentCode] = false; |
||||
|
|
||||
|
setParentRoleCheck(currentParCheck); |
||||
|
setRoleCheck(currentCode); |
||||
|
setIndeterminate(currentInd); |
||||
|
setResData(currentCode) |
||||
|
}} |
||||
|
checked={parentRoleCheck[parentCode] || false} |
||||
|
disabled={userSelected === "SuperAdmin" || userType === 4} |
||||
|
options={''} |
||||
|
> |
||||
|
{text} |
||||
|
</Checkbox> |
||||
|
} |
||||
|
}, { |
||||
|
title: '列表', |
||||
|
key: 'resources', |
||||
|
dataIndex: 'resources', |
||||
|
render: (text, record) => { |
||||
|
let data = []; |
||||
|
console.log() |
||||
|
text.map(s => { s.name !== "整治汇总编辑" ? data.push({ label: s.name, value: s.code }) : '' }) |
||||
|
let parentCode = record.code; |
||||
|
|
||||
|
return <CheckboxGroup |
||||
|
disabled={userSelected === "SuperAdmin" || userType === 4} |
||||
|
options={data} |
||||
|
value={roleCheck[parentCode] || []} |
||||
|
onChange={value => { |
||||
|
const checkArr = JSON.parse(JSON.stringify(roleCheck)); |
||||
|
const parentCheck = JSON.parse(JSON.stringify(parentRoleCheck)); |
||||
|
const ind = JSON.parse(JSON.stringify(indeterminate)); |
||||
|
const currentCode = roleData.find(r => r.code == parentCode) || {} |
||||
|
|
||||
|
checkArr[parentCode] = value; |
||||
|
ind[parentCode] = !!value.length && value.length < currentCode.resources.length |
||||
|
parentCheck[parentCode] = value.length === currentCode.resources.length |
||||
|
|
||||
|
setRoleCheck(checkArr); |
||||
|
setIndeterminate(ind); |
||||
|
setParentRoleCheck(parentCheck); |
||||
|
setResData(checkArr) |
||||
|
}} |
||||
|
/> |
||||
|
} |
||||
|
}]} |
||||
|
></Table > |
||||
|
) |
||||
|
} |
||||
|
export default Resource |
@ -0,0 +1,171 @@ |
|||||
|
import React from 'react'; |
||||
|
import { connect } from 'react-redux'; |
||||
|
import { Spin, Card, Modal, TreeSelect, message } from 'antd'; |
||||
|
import ProForm, { ProFormText, ModalForm, ProFormSwitch, ProFormTreeSelect } from '@ant-design/pro-form'; |
||||
|
|
||||
|
const UserModal = (props) => { |
||||
|
const { visible, modalType, depData, onVisibleChange, onConfirm, editData } = props |
||||
|
const reg_tel = /^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/; |
||||
|
const onFinish = (values) => { |
||||
|
if (onConfirm) { |
||||
|
onConfirm(values); |
||||
|
} |
||||
|
} |
||||
|
const mobile = (value) => { |
||||
|
if (reg_tel.test(value)) { |
||||
|
return |
||||
|
} |
||||
|
return message('请输入姓名') |
||||
|
} |
||||
|
return ( |
||||
|
<Spin spinning={false}> |
||||
|
<ModalForm |
||||
|
title={modalType == 'edit' ? '编辑用户' : '新建用户'} |
||||
|
visible={visible} |
||||
|
onVisibleChange={onVisibleChange} |
||||
|
onFinish={onFinish} |
||||
|
destroyOnClose |
||||
|
initialValues={ |
||||
|
modalType == 'edit' ? |
||||
|
{ |
||||
|
contract: editData |
||||
|
} : |
||||
|
{ |
||||
|
contract: { |
||||
|
enable: true |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
> |
||||
|
<ProForm.Group> |
||||
|
<ProFormText |
||||
|
name={['contract', 'name']} |
||||
|
maxLength={24} |
||||
|
width="md" |
||||
|
label="姓名" |
||||
|
required |
||||
|
placeholder="请输入姓名" |
||||
|
rules={[{ required: true, message: '请输入姓名' }]} |
||||
|
/> |
||||
|
<ProFormText |
||||
|
name={['contract', 'phone']} |
||||
|
width="md" |
||||
|
label="用户名(手机号)" |
||||
|
required |
||||
|
fieldProps={{ |
||||
|
maxLength: 11, |
||||
|
}} |
||||
|
getValueFromEvent={(event) => { |
||||
|
return event.target.value.replace(/\D/g, '') |
||||
|
}} |
||||
|
placeholder="请输入用户名(手机号)" |
||||
|
rules={[ |
||||
|
{ required: true, valueType: Number, max: 11 }, { pattern: /^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/, message: "请输入正确的手机号" } |
||||
|
]} |
||||
|
/> |
||||
|
</ProForm.Group> |
||||
|
<ProForm.Group> |
||||
|
<ProFormTreeSelect |
||||
|
name={['contract', 'departmentId']} |
||||
|
placeholder="请选择所属部门" |
||||
|
width="md" |
||||
|
label="所属部门" |
||||
|
required |
||||
|
fieldNames={{ |
||||
|
title: 'name', |
||||
|
key: 'id', |
||||
|
children: 'subordinate' |
||||
|
}} |
||||
|
onSelect={(selectedKeys, { selected, selectedNodes }) => { |
||||
|
if (selected) { |
||||
|
setDepSelectedKeys(selectedKeys) |
||||
|
setDepSelected(selectedNodes[0].name || "") |
||||
|
dispatch(getDepUser(selectedKeys[0])) |
||||
|
} |
||||
|
}} |
||||
|
fieldProps={{ |
||||
|
fieldNames: { |
||||
|
label: 'title', |
||||
|
}, |
||||
|
treeDefaultExpandAll: false, |
||||
|
}} |
||||
|
rules={[{ required: true, message: '请选择所属部门' }]} |
||||
|
request={async () => { |
||||
|
console.log(depData); |
||||
|
return depData |
||||
|
}} |
||||
|
expandedKeys={["title"]} |
||||
|
/> |
||||
|
< ProFormText |
||||
|
name={['contract', 'post']} |
||||
|
width="md" |
||||
|
label="职位" |
||||
|
// required
|
||||
|
placeholder="请输入职位" |
||||
|
/> |
||||
|
</ProForm.Group> |
||||
|
<ProForm.Group> |
||||
|
<ProFormText |
||||
|
name={['contract', 'email']} |
||||
|
width="md" |
||||
|
label="邮箱" |
||||
|
// required
|
||||
|
placeholder="请输入邮箱" |
||||
|
rules={[ |
||||
|
// { required: true, message: '请输入邮箱' },
|
||||
|
{ type: 'email', message: '请输入正确格式的邮箱' }, |
||||
|
]} |
||||
|
/> |
||||
|
{modalType == 'edit' ? null : <ProFormText.Password |
||||
|
name={['contract', 'password']} |
||||
|
width="md" |
||||
|
label="密码" |
||||
|
required |
||||
|
placeholder="请输入密码" |
||||
|
fieldProps={{ |
||||
|
autocomplete: 'new-password' |
||||
|
}} |
||||
|
rules={[ |
||||
|
{ required: true, message: '请填写密码' }, |
||||
|
{ min: 6, message: '请填写至少6位密码' }, |
||||
|
]} |
||||
|
/>} |
||||
|
</ProForm.Group> |
||||
|
<ProForm.Group> |
||||
|
<ProFormSwitch |
||||
|
name={['contract', 'enable']} |
||||
|
width="md" |
||||
|
label="是否启用" |
||||
|
placeholder="请选择" |
||||
|
// defaultChecked
|
||||
|
valuePropName="checked" |
||||
|
/> |
||||
|
</ProForm.Group> |
||||
|
</ModalForm> |
||||
|
</Spin> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function mapStateToProps(state) { |
||||
|
const { depMessage } = state; |
||||
|
|
||||
|
const pakData = (dep) => { |
||||
|
// console.log(dep);
|
||||
|
return dep.map((d) => { |
||||
|
return { |
||||
|
title: d.name, |
||||
|
value: d.id, |
||||
|
// key: d.id,
|
||||
|
children: pakData(d.subordinate) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
let depData = pakData(depMessage.data || []) |
||||
|
|
||||
|
return { |
||||
|
loading: depMessage.isRequesting, |
||||
|
depData, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(UserModal); |
@ -0,0 +1,149 @@ |
|||||
|
import React, { useEffect, useState } from 'react'; |
||||
|
import { connect } from 'react-redux'; |
||||
|
import { Spin, Row, Col, Card, Button, Tree, Empty } from 'antd'; |
||||
|
import { getDepMessage, getDepUser } from '../actions/user'; |
||||
|
import { getResource, getUserResource, postUserRes } from '../actions/authority'; |
||||
|
import Resource from '../components/resource'; |
||||
|
|
||||
|
const Authority = (props) => { |
||||
|
const { dispatch, loading, depMessage, depUser, resource, userResource, clientHeight } = props |
||||
|
const [depSelectedKeys, setDepSelectedKeys] = useState([]) |
||||
|
const [userSelectedKeys, setUserSelectedKeys] = useState([]) |
||||
|
const [depSelected, setDepSelected] = useState() |
||||
|
const [userSelected, setUserSelected] = useState() |
||||
|
const [resCode, setResCode] = useState({}) |
||||
|
const [useName, setUseName] = useState()// 选中名字
|
||||
|
const [userType,setUserType]=useState() |
||||
|
console.log(resource) |
||||
|
useEffect(() => { |
||||
|
dispatch(getResource()) |
||||
|
if (!(depMessage && depMessage.length)) { |
||||
|
dispatch(getDepMessage()) |
||||
|
} |
||||
|
|
||||
|
}, []) |
||||
|
useEffect(() => { |
||||
|
if (depMessage.length) { |
||||
|
setDepSelectedKeys([depMessage[0].id]) |
||||
|
setDepSelected([depMessage[0].name]) |
||||
|
dispatch(getDepUser(depMessage[0].id)) |
||||
|
} |
||||
|
|
||||
|
}, [depMessage]) |
||||
|
useEffect(() => { |
||||
|
if (depUser.length) { |
||||
|
setUserSelectedKeys([depUser[0].id]) |
||||
|
setUserSelected(depUser[0].username) |
||||
|
dispatch(getUserResource(depUser[0].id)) |
||||
|
setUseName(depUser[0].name) |
||||
|
} |
||||
|
console.log(depUser, 'depUser') |
||||
|
}, [depUser]) |
||||
|
|
||||
|
const handleSave = () => { |
||||
|
dispatch(postUserRes({ userId: userSelectedKeys[0], resCode: resCode })).then(res => { |
||||
|
if (res.success) { |
||||
|
dispatch(getUserResource(userSelectedKeys[0])) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
return ( |
||||
|
<Spin spinning={loading}> |
||||
|
<Row gutter={16}> |
||||
|
<Col span={4} style={{ height: '100%' }}> |
||||
|
<Card title="部门" bordered={false} bodyStyle={{ padding: 8, paddingTop: 24 }}> |
||||
|
{ |
||||
|
depMessage.length ? |
||||
|
<Tree |
||||
|
height={clientHeight - 100} |
||||
|
defaultExpandedKeys={[depMessage[0].id]} |
||||
|
selectedKeys={depSelectedKeys} |
||||
|
onSelect={(selectedKeys, { selected, selectedNodes, node }) => { |
||||
|
setUserType(selectedNodes[0].type) |
||||
|
if (selected) { |
||||
|
setDepSelectedKeys(selectedKeys) |
||||
|
setDepSelected(selectedNodes[0].name || "") |
||||
|
dispatch(getDepUser(selectedKeys[0])) |
||||
|
} |
||||
|
|
||||
|
}} |
||||
|
treeData={depMessage} |
||||
|
fieldNames={{ |
||||
|
title: 'name', |
||||
|
key: 'id', |
||||
|
children: 'subordinate' |
||||
|
}} |
||||
|
/> : '' |
||||
|
} |
||||
|
</Card> |
||||
|
</Col> |
||||
|
<Col span={4} style={{ height: '100%', }}> |
||||
|
<Card title={`[${depSelected}] 用户列表`} bordered={false} bodyStyle={{ padding: 8, paddingTop: 24 }}> |
||||
|
{ |
||||
|
depUser.length ? |
||||
|
<Tree |
||||
|
height={clientHeight - 100} |
||||
|
defaultSelectedKeys={[depUser[0].id]} |
||||
|
selectedKeys={userSelectedKeys} |
||||
|
onSelect={(selectedKeys, { selected, selectedNodes, node, event }) => { |
||||
|
const name = node.name |
||||
|
setUseName(name) |
||||
|
|
||||
|
if (selected) { |
||||
|
setUserSelectedKeys(selectedKeys) |
||||
|
setUserSelected(selectedNodes[0].username || '') |
||||
|
dispatch(getUserResource(selectedKeys[0])) |
||||
|
} |
||||
|
|
||||
|
}} |
||||
|
treeData={depUser} |
||||
|
fieldNames={{ |
||||
|
title: 'name', |
||||
|
key: 'id' |
||||
|
}} |
||||
|
/> : <Empty /> |
||||
|
} |
||||
|
</Card> |
||||
|
</Col> |
||||
|
<Col span={16} style={{ height: '100%', }}> |
||||
|
{depUser.length ? |
||||
|
<Card title={`[${useName ? useName : '管理员'}] 功能范围`} bordered={false} bodyStyle={{ padding: 8, paddingTop: 24 }}> |
||||
|
<Resource |
||||
|
userSelected={userSelected} |
||||
|
roleData={resource} |
||||
|
userRole={userResource} |
||||
|
setResCode={setResCode} |
||||
|
userType={userType} |
||||
|
/> |
||||
|
<Row type="flex" justify="center" style={{ marginBottom: 16, marginTop: 16, textAlign: 'center' }}> |
||||
|
<Col span="24"> |
||||
|
<Button |
||||
|
disabled={userSelected === "SuperAdmin"||userType===4} |
||||
|
onClick={handleSave} |
||||
|
style={{ width: '60%' }} |
||||
|
type='primary'>保存修改</Button> |
||||
|
</Col></Row> |
||||
|
</Card> |
||||
|
: <Card title={`[]功能范围`} bordered={false} bodyStyle={{ padding: 8, paddingTop: 24 }}> |
||||
|
<Empty /> |
||||
|
</Card> |
||||
|
} |
||||
|
</Col> |
||||
|
</Row> |
||||
|
</Spin > |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function mapStateToProps(state) { |
||||
|
const { userResource, resource, depMessage, depUser, global } = state; |
||||
|
return { |
||||
|
clientHeight: global.clientHeight, |
||||
|
loading: depMessage.isRequesting || depUser.isRequesting || resource.isRequesting, |
||||
|
userResource: userResource.data || [], |
||||
|
resource: resource.data || [], |
||||
|
depMessage: depMessage.data || [], |
||||
|
depUser: depUser.data || [] |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(Authority); |
@ -0,0 +1,6 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
import Authority from './authority'; |
||||
|
import UserManage from './user'; |
||||
|
|
||||
|
export { Authority, UserManage }; |
@ -0,0 +1,331 @@ |
|||||
|
import React, { useEffect, useState } from 'react'; |
||||
|
import { connect } from 'react-redux'; |
||||
|
import { FormOutlined, DeleteOutlined } from '@ant-design/icons'; |
||||
|
import { Spin, Tooltip, Button, Popconfirm, Row, Col, Tree, Card, Switch } from 'antd'; |
||||
|
import ProTable from '@ant-design/pro-table'; |
||||
|
import { getDepMessage, getDepUser, createUser, updateUser, delUser, resetPwd, createDept, updateDept, delDept } from '../actions/user'; |
||||
|
import UserModal from '../components/userModal'; |
||||
|
import ResetPwd from '../components/resetPwd'; |
||||
|
import DeptModal from '../components/deptModal'; |
||||
|
|
||||
|
const TreeNode = Tree.TreeNode; |
||||
|
const user = JSON.parse(sessionStorage.getItem('user')); |
||||
|
|
||||
|
const UserManage = (props) => { |
||||
|
const { dispatch, loading, depMessage, depUser, clientHeight } = props; |
||||
|
// 部门
|
||||
|
const [deptModalVisible, setDeptModalVisible] = useState(false); |
||||
|
const [deptModalType, setDeptModalType] = useState(); |
||||
|
const [deptModalRecord, setDeptModalRecord] = useState(); |
||||
|
|
||||
|
// 成员
|
||||
|
const [modalVisible, setModalVisible] = useState(false); |
||||
|
const [modalType, setModalType] = useState(); |
||||
|
const [modalRecord, setModalRecord] = useState(); |
||||
|
const [pwdModalVisible, setPwdModalVisible] = useState(false); |
||||
|
const [depSelectedKeys, setDepSelectedKeys] = useState([]) |
||||
|
const [rowSelected, setRowSelected] = useState([]) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
dispatch(getDepMessage()) |
||||
|
}, []) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
if (depMessage.length) { |
||||
|
setDepSelectedKeys([depMessage[0].id]) |
||||
|
dispatch(getDepUser(depMessage[0].id)) |
||||
|
} |
||||
|
}, [depMessage]) |
||||
|
|
||||
|
const columns = [ |
||||
|
{ |
||||
|
title: '姓名', |
||||
|
dataIndex: 'name', |
||||
|
}, { |
||||
|
title: '用户名(手机号)', |
||||
|
dataIndex: 'username', |
||||
|
}, |
||||
|
{ |
||||
|
title: '职位', |
||||
|
dataIndex: 'post', |
||||
|
}, { |
||||
|
title: '邮箱', |
||||
|
dataIndex: 'email', |
||||
|
}, { |
||||
|
title: '启用状态', |
||||
|
dataIndex: 'enable', |
||||
|
render: (_, r) => { |
||||
|
return <Switch checkedChildren="启用" unCheckedChildren="禁用" disabled defaultChecked={r.enable} /> |
||||
|
} |
||||
|
}, { |
||||
|
title: '操作', |
||||
|
dataIndex: 'action', |
||||
|
render: (dom, record) => { |
||||
|
|
||||
|
return record.username == 'SuperAdmin' ? '' : [ |
||||
|
<Button type="link" onClick={() => { openModal('edit', record) }}>编辑</Button>, |
||||
|
<Popconfirm |
||||
|
title="确认删除?" |
||||
|
onConfirm={() => { |
||||
|
delUsers([record.id]) |
||||
|
}} |
||||
|
> |
||||
|
<Button type="link">删除</Button> |
||||
|
</Popconfirm>, |
||||
|
<Button |
||||
|
type="link" |
||||
|
onClick={() => { |
||||
|
setModalRecord(record); |
||||
|
setPwdModalVisible(true); |
||||
|
}} |
||||
|
>重置密码</Button> |
||||
|
] |
||||
|
}, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
//弹窗确认
|
||||
|
const onConfirm = (values) => { |
||||
|
if (modalType == 'edit') { |
||||
|
dispatch(updateUser(modalRecord.id, values.contract)).then(res => { |
||||
|
if (res.success) { |
||||
|
setModalVisible(false); |
||||
|
dispatch(getDepUser(depSelectedKeys[0])); |
||||
|
} |
||||
|
}); |
||||
|
} else { |
||||
|
dispatch(createUser(values.contract)).then(res => { |
||||
|
if (res.success) { |
||||
|
setModalVisible(false); |
||||
|
dispatch(getDepUser(depSelectedKeys[0])); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//打开弹窗
|
||||
|
const openModal = (type, record) => { |
||||
|
setModalVisible(true); |
||||
|
setModalType(type); |
||||
|
if (type == 'edit') { |
||||
|
setModalRecord(record); |
||||
|
} else { |
||||
|
setModalRecord(null); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//删除用户
|
||||
|
const delUsers = (ids, type) => { |
||||
|
dispatch(delUser(ids)).then(res => { |
||||
|
dispatch(getDepUser(depSelectedKeys[0])); |
||||
|
if (type == 'batch') { |
||||
|
setRowSelected([]); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
//重置密码
|
||||
|
const onPwdConfirm = (values) => { |
||||
|
dispatch(resetPwd(modalRecord.id, { password: values.password })).then(res => { |
||||
|
if (res.success) { |
||||
|
setPwdModalVisible(false); |
||||
|
dispatch(getDepUser(depSelectedKeys[0])); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
const openDeptModal = (type, record) => { |
||||
|
console.log(type, record, 'type, record') |
||||
|
|
||||
|
setDeptModalVisible(true); |
||||
|
setDeptModalType(type); |
||||
|
if (type === 'edit') { |
||||
|
setDeptModalRecord(record); |
||||
|
} else { |
||||
|
setDeptModalRecord(null); |
||||
|
} |
||||
|
} |
||||
|
const onDeptConfirm = (values) => { |
||||
|
if (deptModalType === 'edit') { |
||||
|
dispatch(updateDept(deptModalRecord.id, values.contract)).then(res => { |
||||
|
if (res.success) { |
||||
|
setDeptModalVisible(false); |
||||
|
dispatch(getDepMessage()) |
||||
|
} |
||||
|
}); |
||||
|
} else { |
||||
|
dispatch(createDept(values.contract)).then(res => { |
||||
|
if (res.success) { |
||||
|
setDeptModalVisible(false); |
||||
|
dispatch(getDepMessage()) |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
const delDepartment = (id) => { |
||||
|
dispatch(delDept(id)).then(res => { |
||||
|
if (res.success) { |
||||
|
dispatch(getDepMessage()) |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
const renderTree = (item, id) => { |
||||
|
// let cannotDel = item.users.length || item.subordinate?.filter(is => is.users.length).length;//自己下面有成员 或者下级部门下有成员 不能删除
|
||||
|
return <div style={{ display: 'flex', width: '6vw', justifyContent: 'space-between' }}> |
||||
|
<Tooltip title={item.name}> |
||||
|
<div style={{ width: '70%', textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden' }}>{item.name}</div> |
||||
|
</Tooltip> |
||||
|
<div style={{ width: '30%' }} > |
||||
|
{ |
||||
|
depSelectedKeys == id && user.username === "SuperAdmin" ? |
||||
|
<> |
||||
|
<FormOutlined onClick={() => { |
||||
|
setDeptModalRecord(item) |
||||
|
setDeptModalVisible(true) |
||||
|
setDeptModalType('edit') |
||||
|
}} /> |
||||
|
{ |
||||
|
<Popconfirm title='是否确认删除?' onConfirm={() => { delDepartment(id) }}> |
||||
|
<DeleteOutlined style={{ marginLeft: 5 }} /> |
||||
|
</Popconfirm> |
||||
|
} |
||||
|
</> : null |
||||
|
} |
||||
|
</div> |
||||
|
</div> |
||||
|
} |
||||
|
|
||||
|
return (<div > |
||||
|
<Spin spinning={loading} /* style={{ height: "calc(100vh - 70px)" }} */> |
||||
|
<Row gutter={16} /* style={{ overflow: "scroll" }} */> |
||||
|
<Col flex="260px" style={{ height: '100%' }}> |
||||
|
<Card title="部门" bordered={false} bodyStyle={{ padding: 8, paddingTop: 24, }}> |
||||
|
{ |
||||
|
user.username === "SuperAdmin" && <Button |
||||
|
type="primary" |
||||
|
key="primary" |
||||
|
style={{ margin: '16px 0px' }} |
||||
|
onClick={() => openDeptModal('create')} |
||||
|
>新建部门</Button> |
||||
|
} |
||||
|
{ |
||||
|
depMessage.length ? |
||||
|
<Tree |
||||
|
height={clientHeight - 95} |
||||
|
defaultExpandedKeys={[depMessage[0].id]} |
||||
|
selectedKeys={depSelectedKeys} |
||||
|
onSelect={(selectedKeys, e) => { |
||||
|
if (e.selected) { |
||||
|
setDepSelectedKeys(selectedKeys) |
||||
|
dispatch(getDepUser(selectedKeys[0])) |
||||
|
} |
||||
|
}} |
||||
|
// treeData={depMessage}
|
||||
|
// fieldNames={{
|
||||
|
// title: 'name',
|
||||
|
// key: 'id',
|
||||
|
// children: 'subordinate'
|
||||
|
// }}
|
||||
|
> |
||||
|
{ |
||||
|
depMessage.map((s, index) => { |
||||
|
return <TreeNode title={renderTree(s, s.id)} key={s.id} > |
||||
|
{ |
||||
|
s.subordinate.map(k => { |
||||
|
return <TreeNode title={renderTree(k, k.id)} key={k.id} onMouseOver={() => { setIShowIcon(k.id) }} onMouseOut={() => { setIShowIcon(null) }}> |
||||
|
</TreeNode> |
||||
|
}) |
||||
|
} |
||||
|
</TreeNode> |
||||
|
}) |
||||
|
} |
||||
|
</Tree> : '' |
||||
|
} |
||||
|
</Card> |
||||
|
</Col> |
||||
|
|
||||
|
<Col /* flex="auto" */ style={{ width: "calc(100% - 260px)", height: '100%', display: "black" }}> |
||||
|
<Card title="用户" bordered={false} height={clientHeight} bodyStyle={{ padding: 8, paddingTop: 24, overflow: "hidden", width: "100%" }}> |
||||
|
<ProTable |
||||
|
columns={columns} |
||||
|
dataSource={depUser} |
||||
|
style={{ width: "100% ", height: clientHeight - 95, overflow: "auto" }} |
||||
|
rowSelection={{ |
||||
|
selectedRowKeys: rowSelected, |
||||
|
onChange: (selectedRowKeys) => { |
||||
|
setRowSelected(selectedRowKeys); |
||||
|
|
||||
|
}, |
||||
|
getCheckboxProps: (record) => { |
||||
|
return { |
||||
|
disabled: record.username === 'SuperAdmin', |
||||
|
} |
||||
|
}, |
||||
|
}} |
||||
|
options={false} |
||||
|
search={false} |
||||
|
rowKey="id" |
||||
|
toolBarRender={() => [ |
||||
|
<span> |
||||
|
<Button |
||||
|
type="primary" |
||||
|
key="primary" |
||||
|
style={{ marginRight: 10 }} |
||||
|
onClick={() => openModal('create')} |
||||
|
>新建用户</Button> |
||||
|
<Button style={{ marginRight: 10 }} onClick={() => { dispatch(getDepUser(depSelectedKeys[0])); }}>刷新</Button> |
||||
|
<Popconfirm title="确认删除?" onConfirm={() => { delUsers(rowSelected, 'batch') }}> |
||||
|
<Button>批量删除</Button> |
||||
|
</Popconfirm> |
||||
|
</span> |
||||
|
]} |
||||
|
/> |
||||
|
</Card> |
||||
|
{ |
||||
|
deptModalVisible ? |
||||
|
<DeptModal |
||||
|
visible={deptModalVisible} |
||||
|
onVisibleChange={setDeptModalVisible} |
||||
|
modalType={deptModalType} |
||||
|
onConfirm={onDeptConfirm} |
||||
|
editData={deptModalRecord} |
||||
|
depts={depMessage} |
||||
|
/> |
||||
|
: '' |
||||
|
} |
||||
|
{ |
||||
|
depMessage.length && modalVisible ? |
||||
|
<UserModal |
||||
|
visible={modalVisible} |
||||
|
onVisibleChange={setModalVisible} |
||||
|
modalType={modalType} |
||||
|
onConfirm={onConfirm} |
||||
|
editData={modalRecord} |
||||
|
/> |
||||
|
: '' |
||||
|
} |
||||
|
{pwdModalVisible ? <ResetPwd visible={pwdModalVisible} |
||||
|
onVisibleChange={setPwdModalVisible} |
||||
|
onConfirm={onPwdConfirm} /> : ''} |
||||
|
|
||||
|
</Col> |
||||
|
</Row> |
||||
|
</Spin> |
||||
|
</div> |
||||
|
|
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function mapStateToProps(state) { |
||||
|
const { depMessage, depUser, global } = state; |
||||
|
return { |
||||
|
clientHeight: global.clientHeight, |
||||
|
loading: depMessage.isRequesting, |
||||
|
depMessage: depMessage.data || [], |
||||
|
depUser: depUser.data || [] |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(UserManage); |
@ -0,0 +1,15 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
import reducers from './reducers'; |
||||
|
import routes from './routes'; |
||||
|
import actions from './actions'; |
||||
|
import { getNavItem } from './nav-item'; |
||||
|
|
||||
|
export default { |
||||
|
key: 'organization', |
||||
|
name: '', |
||||
|
reducers: reducers, |
||||
|
routes: routes, |
||||
|
actions: actions, |
||||
|
getNavItem: getNavItem |
||||
|
}; |
@ -0,0 +1,22 @@ |
|||||
|
import React from 'react'; |
||||
|
import { Link } from 'react-router-dom'; |
||||
|
import { Menu } from 'antd'; |
||||
|
import { SettingOutlined } from '@ant-design/icons'; |
||||
|
|
||||
|
const SubMenu = Menu.SubMenu; |
||||
|
|
||||
|
export function getNavItem(user, dispatch) { |
||||
|
// if (!Func.isAuthorized("ORG_MANAGE")) {
|
||||
|
// return null
|
||||
|
// }
|
||||
|
return ( |
||||
|
<SubMenu key="organization" icon={<SettingOutlined />} title={'组织管理'}> |
||||
|
<Menu.Item key="userManage"> |
||||
|
<Link to="/organization/user">部门成员</Link> |
||||
|
</Menu.Item> |
||||
|
<Menu.Item key="authority"> |
||||
|
<Link to="/organization/authority">权限配置</Link> |
||||
|
</Menu.Item> |
||||
|
</SubMenu> |
||||
|
); |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
export default { |
||||
|
|
||||
|
}; |
@ -0,0 +1,26 @@ |
|||||
|
'use strict'; |
||||
|
import { UserManage, Authority } from './containers'; |
||||
|
|
||||
|
export default [{ |
||||
|
type: 'inner', |
||||
|
route: { |
||||
|
path: '/organization', |
||||
|
key: 'organization', |
||||
|
breadcrumb: '组织管理', |
||||
|
menuSelectKeys: ['userManage'], |
||||
|
menuOpenKeys: ['organization'], |
||||
|
childRoutes: [{ |
||||
|
path: '/user', |
||||
|
key: 'userManage', |
||||
|
menuSelectKeys: ['userManage'], |
||||
|
component: UserManage, |
||||
|
breadcrumb: '部门成员', |
||||
|
}, { |
||||
|
path: '/authority', |
||||
|
key: 'authority', |
||||
|
component: Authority, |
||||
|
menuSelectKeys: ['authority'], |
||||
|
breadcrumb: '权限配置', |
||||
|
}] |
||||
|
} |
||||
|
}]; |
Loading…
Reference in new issue