diff --git a/api/app/lib/controllers/organization/authority.js b/api/app/lib/controllers/organization/authority.js
new file mode 100644
index 0000000..bcb5a68
--- /dev/null
+++ b/api/app/lib/controllers/organization/authority.js
@@ -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
+};
\ No newline at end of file
diff --git a/api/app/lib/controllers/organization/user.js b/api/app/lib/controllers/organization/user.js
new file mode 100644
index 0000000..aa7e2e9
--- /dev/null
+++ b/api/app/lib/controllers/organization/user.js
@@ -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
+}
\ No newline at end of file
diff --git a/api/app/lib/models/department.js b/api/app/lib/models/department.js
index 2657f84..db844db 100644
--- a/api/app/lib/models/department.js
+++ b/api/app/lib/models/department.js
@@ -35,9 +35,9 @@ module.exports = dc => {
},
type: {
type: DataTypes.INTEGER,
- allowNull: false,
+ allowNull: true,
defaultValue: null,
- comment: "市1,区县2,乡镇3,村4",
+ comment: "",
primaryKey: false,
field: "type",
autoIncrement: false
diff --git a/api/app/lib/routes/organization/authority.js b/api/app/lib/routes/organization/authority.js
new file mode 100644
index 0000000..99de6df
--- /dev/null
+++ b/api/app/lib/routes/organization/authority.js
@@ -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);
+};
\ No newline at end of file
diff --git a/api/app/lib/routes/organization/user.js b/api/app/lib/routes/organization/user.js
new file mode 100644
index 0000000..5b63e32
--- /dev/null
+++ b/api/app/lib/routes/organization/user.js
@@ -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);
+};
\ No newline at end of file
diff --git a/script/1.0.0/data/1.admin_user.sql b/script/1.0.0/data/1.admin_user.sql
index b779175..c492d71 100644
--- a/script/1.0.0/data/1.admin_user.sql
+++ b/script/1.0.0/data/1.admin_user.sql
@@ -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);
diff --git a/script/1.0.0/data/2.updata_resource_data.sql b/script/1.0.0/data/2.updata_resource_data.sql
new file mode 100644
index 0000000..de022a8
--- /dev/null
+++ b/script/1.0.0/data/2.updata_resource_data.sql
@@ -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');
\ No newline at end of file
diff --git a/script/1.0.0/data/3.updata_user_resource_data.sql b/script/1.0.0/data/3.updata_user_resource_data.sql
new file mode 100644
index 0000000..cf2c69b
--- /dev/null
+++ b/script/1.0.0/data/3.updata_user_resource_data.sql
@@ -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');
\ No newline at end of file
diff --git a/script/1.0.0/schema/1.init_inspection.sql b/script/1.0.0/schema/1.init_inspection.sql
index b3b0c57..83480a9 100644
--- a/script/1.0.0/schema/1.init_inspection.sql
+++ b/script/1.0.0/schema/1.init_inspection.sql
@@ -69,7 +69,7 @@ CREATE TABLE "public"."department" (
"id" int4 NOT NULL DEFAULT nextval('department_id_seq'::regclass),
"name" varchar(128) COLLATE "pg_catalog"."default" NOT NULL,
"dependence" int4,
- "type" int4 NOT NULL
+ "type" int4
);
COMMENT ON COLUMN "public"."department"."dependence" IS '上级部门/从属';
-- COMMENT ON COLUMN "public"."department"."type" IS '市1,区县2,乡镇3,村4';
diff --git a/web/client/src/app.js b/web/client/src/app.js
index fd3f9f1..b1073a0 100644
--- a/web/client/src/app.js
+++ b/web/client/src/app.js
@@ -5,6 +5,7 @@ import Layout from './layout';
import Auth from './sections/auth';
import Safetymanage from './sections/safetymanage';
import ProjectRegime from './sections/projectRegime';
+import Organization from './sections/organization';
const App = props => {
const { projectName } = props
@@ -16,7 +17,7 @@ const App = props => {
return (
)
diff --git a/web/client/src/sections/organization/actions/authority.js b/web/client/src/sections/organization/actions/authority.js
new file mode 100644
index 0000000..d5f0719
--- /dev/null
+++ b/web/client/src/sections/organization/actions/authority.js
@@ -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
+}
\ No newline at end of file
diff --git a/web/client/src/sections/organization/actions/index.js b/web/client/src/sections/organization/actions/index.js
new file mode 100644
index 0000000..b44cd45
--- /dev/null
+++ b/web/client/src/sections/organization/actions/index.js
@@ -0,0 +1,11 @@
+'use strict';
+
+import * as authority from './authority'
+import { getDepMessage, getDepUser, createUser } from './user'
+
+export default {
+ ...authority,
+ getDepMessage,
+ getDepUser,
+ createUser,
+}
\ No newline at end of file
diff --git a/web/client/src/sections/organization/actions/user.js b/web/client/src/sections/organization/actions/user.js
new file mode 100644
index 0000000..ef2b452
--- /dev/null
+++ b/web/client/src/sections/organization/actions/user.js
@@ -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
+}
\ No newline at end of file
diff --git a/web/client/src/sections/organization/components/deptModal.js b/web/client/src/sections/organization/components/deptModal.js
new file mode 100644
index 0000000..9947081
--- /dev/null
+++ b/web/client/src/sections/organization/components/deptModal.js
@@ -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 (
+
+
+ {
+ let t = modalType === 'edit' ? deptOptions.filter(i => i.value !== editData.id) : deptOptions
+ return t
+ }}
+ disabled={modalType === 'edit' ? editData.subordinate?.length === 0 ? false : true : false}
+ />
+
+ )
+}
+
+function mapStateToProps(state) {
+ return {
+ };
+}
+
+export default connect(mapStateToProps)(DeptModal);
\ No newline at end of file
diff --git a/web/client/src/sections/organization/components/resetPwd.js b/web/client/src/sections/organization/components/resetPwd.js
new file mode 100644
index 0000000..14135e0
--- /dev/null
+++ b/web/client/src/sections/organization/components/resetPwd.js
@@ -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 (
+
+
+
+ {
+ const pwd = formRef.current.getFieldValue('password');
+ if (!value) {
+ callback();
+ }
+ if (pwd == value) {
+ callback();
+ } else {
+ callback('两次输入的密码不一致');
+ }
+ }
+ }
+ ]}
+ />
+
+
+ )
+}
+
+function mapStateToProps(state) {
+ return {};
+}
+
+export default connect(mapStateToProps)(ResetPwd);
\ No newline at end of file
diff --git a/web/client/src/sections/organization/components/resource.js b/web/client/src/sections/organization/components/resource.js
new file mode 100644
index 0000000..5e336f0
--- /dev/null
+++ b/web/client/src/sections/organization/components/resource.js
@@ -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 (
+
{
+ const parentCode = record.code
+ return {
+ 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}
+
+ }
+ }, {
+ 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 {
+ 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)
+ }}
+ />
+ }
+ }]}
+ >
+ )
+}
+export default Resource
\ No newline at end of file
diff --git a/web/client/src/sections/organization/components/userModal.js b/web/client/src/sections/organization/components/userModal.js
new file mode 100644
index 0000000..73a082a
--- /dev/null
+++ b/web/client/src/sections/organization/components/userModal.js
@@ -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 (
+
+
+
+
+ {
+ 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: "请输入正确的手机号" }
+ ]}
+ />
+
+
+ {
+ 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="请输入职位"
+ />
+
+
+
+ {modalType == 'edit' ? null : }
+
+
+
+
+
+
+ )
+}
+
+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);
\ No newline at end of file
diff --git a/web/client/src/sections/organization/containers/authority.js b/web/client/src/sections/organization/containers/authority.js
new file mode 100644
index 0000000..ad46746
--- /dev/null
+++ b/web/client/src/sections/organization/containers/authority.js
@@ -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 (
+
+
+
+
+ {
+ depMessage.length ?
+ {
+ 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'
+ }}
+ /> : ''
+ }
+
+
+
+
+ {
+ depUser.length ?
+ {
+ 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'
+ }}
+ /> :
+ }
+
+
+
+ {depUser.length ?
+
+
+
+
+
+
+
+ :
+
+
+ }
+
+
+
+ )
+}
+
+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);
\ No newline at end of file
diff --git a/web/client/src/sections/organization/containers/index.js b/web/client/src/sections/organization/containers/index.js
new file mode 100644
index 0000000..e1a69b0
--- /dev/null
+++ b/web/client/src/sections/organization/containers/index.js
@@ -0,0 +1,6 @@
+'use strict';
+
+import Authority from './authority';
+import UserManage from './user';
+
+export { Authority, UserManage };
\ No newline at end of file
diff --git a/web/client/src/sections/organization/containers/user.js b/web/client/src/sections/organization/containers/user.js
new file mode 100644
index 0000000..9c3eeec
--- /dev/null
+++ b/web/client/src/sections/organization/containers/user.js
@@ -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
+ }
+ }, {
+ title: '操作',
+ dataIndex: 'action',
+ render: (dom, record) => {
+
+ return record.username == 'SuperAdmin' ? '' : [
+ ,
+ {
+ delUsers([record.id])
+ }}
+ >
+
+ ,
+
+ ]
+ },
+ },
+ ];
+
+ //弹窗确认
+ 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
+
+ {item.name}
+
+
+ {
+ depSelectedKeys == id && user.username === "SuperAdmin" ?
+ <>
+
{
+ setDeptModalRecord(item)
+ setDeptModalVisible(true)
+ setDeptModalType('edit')
+ }} />
+ {
+ { delDepartment(id) }}>
+
+
+ }
+ > : null
+ }
+
+
+ }
+
+ return (
+
+
|
+
+
+ {
+ user.username === "SuperAdmin" &&
+ }
+ {
+ depMessage.length ?
+ {
+ if (e.selected) {
+ setDepSelectedKeys(selectedKeys)
+ dispatch(getDepUser(selectedKeys[0]))
+ }
+ }}
+ // treeData={depMessage}
+ // fieldNames={{
+ // title: 'name',
+ // key: 'id',
+ // children: 'subordinate'
+ // }}
+ >
+ {
+ depMessage.map((s, index) => {
+ return
+ {
+ s.subordinate.map(k => {
+ return { setIShowIcon(k.id) }} onMouseOut={() => { setIShowIcon(null) }}>
+
+ })
+ }
+
+ })
+ }
+ : ''
+ }
+
+
+
+
+
+ {
+ setRowSelected(selectedRowKeys);
+
+ },
+ getCheckboxProps: (record) => {
+ return {
+ disabled: record.username === 'SuperAdmin',
+ }
+ },
+ }}
+ options={false}
+ search={false}
+ rowKey="id"
+ toolBarRender={() => [
+
+
+
+ { delUsers(rowSelected, 'batch') }}>
+
+
+
+ ]}
+ />
+
+ {
+ deptModalVisible ?
+
+ : ''
+ }
+ {
+ depMessage.length && modalVisible ?
+
+ : ''
+ }
+ {pwdModalVisible ?
: ''}
+
+
+
+
+
+
+ )
+}
+
+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);
\ No newline at end of file
diff --git a/web/client/src/sections/organization/index.js b/web/client/src/sections/organization/index.js
new file mode 100644
index 0000000..412ced6
--- /dev/null
+++ b/web/client/src/sections/organization/index.js
@@ -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
+};
\ No newline at end of file
diff --git a/web/client/src/sections/organization/nav-item.js b/web/client/src/sections/organization/nav-item.js
new file mode 100644
index 0000000..6b25267
--- /dev/null
+++ b/web/client/src/sections/organization/nav-item.js
@@ -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 (
+ } title={'组织管理'}>
+
+ 部门成员
+
+
+ 权限配置
+
+
+ );
+}
\ No newline at end of file
diff --git a/web/client/src/sections/organization/reducers/index.js b/web/client/src/sections/organization/reducers/index.js
new file mode 100644
index 0000000..0203d01
--- /dev/null
+++ b/web/client/src/sections/organization/reducers/index.js
@@ -0,0 +1,5 @@
+'use strict';
+
+export default {
+
+};
\ No newline at end of file
diff --git a/web/client/src/sections/organization/routes.js b/web/client/src/sections/organization/routes.js
new file mode 100644
index 0000000..d6675f5
--- /dev/null
+++ b/web/client/src/sections/organization/routes.js
@@ -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: '权限配置',
+ }]
+ }
+}];
\ No newline at end of file
diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js
index 2d494cc..8d70541 100644
--- a/web/client/src/utils/webapi.js
+++ b/web/client/src/utils/webapi.js
@@ -7,6 +7,23 @@ export const ApiTable = {
validatePhone: 'validate/phone',
getUserSiteList: 'user/site/list',
+ // 组织管理-用户管理
+ getDepMessage: 'organization/department',
+ createDept: '/organization/dept/add',
+ updateDept: '/organization/dept/{id}/modify',
+ delDept: '/organization/dept/{id}',
+
+ getDepUser: 'organization/department/{depId}/user',
+ createUser: 'organization/department/user',
+ updateUser: 'organization/department/user/{id}',
+ delUser: 'organization/department/user/{ids}',
+ resetPwd: '/organization/department/user/resetPwd/{id}',
+
+ // 用户权限
+ getResource: 'resource',
+ getUserResource: 'user/resource',
+ postUserRes: 'user/resource',
+
//安全风险预报
getSiteWeekRegiste: 'sites/report',
getRiskReportList: 'risk/report',