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