From f0ee5cbbfb9be5be779b6fd4ad7126e7644b66c1 Mon Sep 17 00:00:00 2001 From: liujiangyong Date: Mon, 16 Jan 2023 14:20:34 +0800 Subject: [PATCH 1/4] org mange --- .../lib/controllers/organization/authority.js | 87 ++++ api/app/lib/controllers/organization/user.js | 373 ++++++++++++++++++ api/app/lib/models/department.js | 4 +- api/app/lib/routes/organization/authority.js | 28 ++ api/app/lib/routes/organization/user.js | 41 ++ script/1.0.0/data/1.admin_user.sql | 2 +- script/1.0.0/data/2.updata_resource_data.sql | 11 + .../data/3.updata_user_resource_data.sql | 11 + script/1.0.0/schema/1.init_inspection.sql | 2 +- web/client/src/app.js | 3 +- .../organization/actions/authority.js | 51 +++ .../sections/organization/actions/index.js | 11 + .../src/sections/organization/actions/user.js | 113 ++++++ .../organization/components/deptModal.js | 88 +++++ .../organization/components/resetPwd.js | 74 ++++ .../organization/components/resource.js | 121 ++++++ .../organization/components/userModal.js | 171 ++++++++ .../organization/containers/authority.js | 149 +++++++ .../sections/organization/containers/index.js | 6 + .../sections/organization/containers/user.js | 331 ++++++++++++++++ web/client/src/sections/organization/index.js | 15 + .../src/sections/organization/nav-item.js | 22 ++ .../sections/organization/reducers/index.js | 5 + .../src/sections/organization/routes.js | 26 ++ web/client/src/utils/webapi.js | 17 + 25 files changed, 1757 insertions(+), 5 deletions(-) create mode 100644 api/app/lib/controllers/organization/authority.js create mode 100644 api/app/lib/controllers/organization/user.js create mode 100644 api/app/lib/routes/organization/authority.js create mode 100644 api/app/lib/routes/organization/user.js create mode 100644 script/1.0.0/data/2.updata_resource_data.sql create mode 100644 script/1.0.0/data/3.updata_user_resource_data.sql create mode 100644 web/client/src/sections/organization/actions/authority.js create mode 100644 web/client/src/sections/organization/actions/index.js create mode 100644 web/client/src/sections/organization/actions/user.js create mode 100644 web/client/src/sections/organization/components/deptModal.js create mode 100644 web/client/src/sections/organization/components/resetPwd.js create mode 100644 web/client/src/sections/organization/components/resource.js create mode 100644 web/client/src/sections/organization/components/userModal.js create mode 100644 web/client/src/sections/organization/containers/authority.js create mode 100644 web/client/src/sections/organization/containers/index.js create mode 100644 web/client/src/sections/organization/containers/user.js create mode 100644 web/client/src/sections/organization/index.js create mode 100644 web/client/src/sections/organization/nav-item.js create mode 100644 web/client/src/sections/organization/reducers/index.js create mode 100644 web/client/src/sections/organization/routes.js 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', From b06503b6b934e030e364369b0027055db7d70a7b Mon Sep 17 00:00:00 2001 From: Archer_cdm Date: Mon, 16 Jan 2023 15:24:00 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=EF=BC=88+=EF=BC=89=E5=B7=A1=E6=A3=80?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- weapp/.eslintrc.js | 31 ++++ weapp/app.js | 48 ++++++ weapp/app.json | 45 ++++++ weapp/app.wxss | 10 ++ weapp/images/avatar.svg | 1 + weapp/images/logo.png | Bin 0 -> 9593 bytes weapp/images/password.png | Bin 0 -> 1419 bytes weapp/images/right.svg | 2 + weapp/images/tabBar/icon_menu.png | Bin 0 -> 2296 bytes weapp/images/tabBar/icon_menu_active.png | Bin 0 -> 2140 bytes weapp/images/tabBar/icon_person.png | Bin 0 -> 2647 bytes weapp/images/tabBar/icon_person_active.png | Bin 0 -> 2540 bytes weapp/images/tabBar/icon_polling.png | Bin 0 -> 1867 bytes weapp/images/tabBar/icon_polling_active.png | Bin 0 -> 1830 bytes weapp/images/userName.png | Bin 0 -> 1612 bytes weapp/images/xunjian.svg | 1 + weapp/package/basic/basic.js | 66 +++++++++ weapp/package/basic/basic.json | 6 + weapp/package/basic/basic.wxml | 41 +++++ weapp/package/basic/basic.wxss | 60 ++++++++ weapp/package/polling/polling.js | 71 +++++++++ weapp/package/polling/polling.json | 6 + weapp/package/polling/polling.wxml | 11 ++ weapp/package/polling/polling.wxss | 33 +++++ weapp/pages/index/index.js | 66 +++++++++ weapp/pages/index/index.json | 6 + weapp/pages/index/index.wxml | 26 ++++ weapp/pages/index/index.wxss | 55 +++++++ weapp/pages/login/login.js | 91 ++++++++++++ weapp/pages/login/login.json | 6 + weapp/pages/login/login.wxml | 25 ++++ weapp/pages/login/login.wxss | 156 ++++++++++++++++++++ weapp/pages/myInfo/myInfo.js | 72 +++++++++ weapp/pages/myInfo/myInfo.json | 6 + weapp/pages/myInfo/myInfo.wxml | 25 ++++ weapp/pages/myInfo/myInfo.wxss | 100 +++++++++++++ weapp/pages/overview/overview.js | 73 +++++++++ weapp/pages/overview/overview.json | 6 + weapp/pages/overview/overview.wxml | 18 +++ weapp/pages/overview/overview.wxss | 35 +++++ weapp/project.config.json | 51 +++++++ weapp/project.private.config.json | 36 +++++ weapp/sitemap.json | 7 + weapp/utils/util.js | 19 +++ 44 files changed, 1311 insertions(+) create mode 100644 weapp/.eslintrc.js create mode 100644 weapp/app.js create mode 100644 weapp/app.json create mode 100644 weapp/app.wxss create mode 100644 weapp/images/avatar.svg create mode 100644 weapp/images/logo.png create mode 100644 weapp/images/password.png create mode 100644 weapp/images/right.svg create mode 100644 weapp/images/tabBar/icon_menu.png create mode 100644 weapp/images/tabBar/icon_menu_active.png create mode 100644 weapp/images/tabBar/icon_person.png create mode 100644 weapp/images/tabBar/icon_person_active.png create mode 100644 weapp/images/tabBar/icon_polling.png create mode 100644 weapp/images/tabBar/icon_polling_active.png create mode 100644 weapp/images/userName.png create mode 100644 weapp/images/xunjian.svg create mode 100644 weapp/package/basic/basic.js create mode 100644 weapp/package/basic/basic.json create mode 100644 weapp/package/basic/basic.wxml create mode 100644 weapp/package/basic/basic.wxss create mode 100644 weapp/package/polling/polling.js create mode 100644 weapp/package/polling/polling.json create mode 100644 weapp/package/polling/polling.wxml create mode 100644 weapp/package/polling/polling.wxss create mode 100644 weapp/pages/index/index.js create mode 100644 weapp/pages/index/index.json create mode 100644 weapp/pages/index/index.wxml create mode 100644 weapp/pages/index/index.wxss create mode 100644 weapp/pages/login/login.js create mode 100644 weapp/pages/login/login.json create mode 100644 weapp/pages/login/login.wxml create mode 100644 weapp/pages/login/login.wxss create mode 100644 weapp/pages/myInfo/myInfo.js create mode 100644 weapp/pages/myInfo/myInfo.json create mode 100644 weapp/pages/myInfo/myInfo.wxml create mode 100644 weapp/pages/myInfo/myInfo.wxss create mode 100644 weapp/pages/overview/overview.js create mode 100644 weapp/pages/overview/overview.json create mode 100644 weapp/pages/overview/overview.wxml create mode 100644 weapp/pages/overview/overview.wxss create mode 100644 weapp/project.config.json create mode 100644 weapp/project.private.config.json create mode 100644 weapp/sitemap.json create mode 100644 weapp/utils/util.js diff --git a/weapp/.eslintrc.js b/weapp/.eslintrc.js new file mode 100644 index 0000000..115cc02 --- /dev/null +++ b/weapp/.eslintrc.js @@ -0,0 +1,31 @@ +/* + * Eslint config file + * Documentation: https://eslint.org/docs/user-guide/configuring/ + * Install the Eslint extension before using this feature. + */ +module.exports = { + env: { + es6: true, + browser: true, + node: true, + }, + ecmaFeatures: { + modules: true, + }, + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + }, + globals: { + wx: true, + App: true, + Page: true, + getCurrentPages: true, + getApp: true, + Component: true, + requirePlugin: true, + requireMiniProgram: true, + }, + // extends: 'eslint:recommended', + rules: {}, +} diff --git a/weapp/app.js b/weapp/app.js new file mode 100644 index 0000000..dca5e21 --- /dev/null +++ b/weapp/app.js @@ -0,0 +1,48 @@ +// app.js +App({ + onLaunch() { + // // 展示本地存储能力 + // const logs = wx.getStorageSync('logs') || [] + // logs.unshift(Date.now()) + // wx.setStorageSync('logs', logs) + + // // 登录 + // wx.login({ + // success: res => { + // // 发送 res.code 到后台换取 openId, sessionKey, unionId + // } + // }) + }, + globalData: { + userInfo: null + }, + onShow(e) { + // 检查是否有更新 + const updateManager = wx.getUpdateManager(); + updateManager.onCheckForUpdate(function (res) { + // 请求完新版本信息的回调 + console.log(res.hasUpdate); + }); + updateManager.onUpdateReady(function () { + wx.showModal({ + title: "更新提示", + content: "新版本已经准备好,是否重启应用?", + success(res) { + if (res.confirm) { + // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启 + updateManager.applyUpdate(); + } + } + }); + }); + + updateManager.onUpdateFailed(function () { + // 新版本下载失败 + wx.showToast({ + title: "新版本下载失败", + icon: "none", + duration: 1000 + }); + }); + } +}) diff --git a/weapp/app.json b/weapp/app.json new file mode 100644 index 0000000..ca7ade1 --- /dev/null +++ b/weapp/app.json @@ -0,0 +1,45 @@ +{ + "pages": [ + "pages/index/index", + "pages/login/login", + "pages/myInfo/myInfo", + "pages/overview/overview" + ], + "subPackages": [{ + "root": "package", + "pages": [ + "polling/polling", + "basic/basic" + ] + }], + "window": { + "backgroundTextStyle": "dark", + "navigationBarBackgroundColor": "#1979ff", + "navigationBarTextStyle": "white" + }, + "tabBar": { + "color": "#000000", + "selectedColor": "#2F54FF", + "borderStyle": "black", + "backgroundColor": "#ffffff", + "list": [{ + "pagePath": "pages/index/index", + "iconPath": "images/tabBar/icon_polling.png", + "selectedIconPath": "images/tabBar/icon_polling_active.png", + "text": "巡检总览" + }, { + "pagePath": "pages/overview/overview", + "iconPath": "images/tabBar/icon_menu.png", + "selectedIconPath": "images/tabBar/icon_menu_active.png", + "text": "工作台" + }, + { + "pagePath": "pages/myInfo/myInfo", + "iconPath": "images/tabBar/icon_person.png", + "selectedIconPath": "images/tabBar/icon_person_active.png", + "text": "我的" + } + ] + }, + "sitemapLocation": "sitemap.json" +} \ No newline at end of file diff --git a/weapp/app.wxss b/weapp/app.wxss new file mode 100644 index 0000000..06c6fc9 --- /dev/null +++ b/weapp/app.wxss @@ -0,0 +1,10 @@ +/**app.wxss**/ +.container { + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + padding: 200rpx 0; + box-sizing: border-box; +} diff --git a/weapp/images/avatar.svg b/weapp/images/avatar.svg new file mode 100644 index 0000000..dd95046 --- /dev/null +++ b/weapp/images/avatar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/weapp/images/logo.png b/weapp/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a4345c275bda669685853ec191bb6198ca5a7a47 GIT binary patch literal 9593 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 literal 0 HcmV?d00001 diff --git a/weapp/images/password.png b/weapp/images/password.png new file mode 100644 index 0000000000000000000000000000000000000000..cac6ccdf15c1155b8c479a605fa9bf19ecff4220 GIT binary patch literal 1419 zcmeAS@N?(olHy`uVBq!ia0vp^azL!a!3HEfIxv4 zq}24xJX@vryZ0+8WTx0Eg`4^s_!c;)W@LI)6{QAO`Gq7`WhYyvDB0U7*i={n4aiL` zNmQuF&B-gas<2f8n`;GRgM{^!6u?SKvTcwn`Gt*5rFf&&$x70H< zH8(dg*HJJsFf`RSFxEFV&^0o)GBL0+F;aj6C7^9ZDQQ+gE^bh}fIM5JjFOT9D}DX) z@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7^KE~&-IMVSR9nfZANAQKal z@=Hr>m4GgVcpG8yO|TwcUn|eN;*!L?2a|Jy12L;Imnk+8X$Az_=@JH;I*q29!-c6 z{J3#v=j6qFUHUHUfB8!$C>>pyCAj+9tzWwfloYpoyLWHGN#=NekG#)!kDv5?eZj<6 zup>`^g?T~ixxEd^1q|N~JuH~?+>Ot#P(Fe!x2;(If#?q3+{FoevM2tP9ya28$z-AQ zQc;4%E`aw{L-#t}pme7PWw3zddB<%OrQYrJr&+5*HOLX8XW*36o;K!rKc$Yq~p353fk};$-}3amjkd zp%r&+9!VLnT}p7B*sbx@Q?AhZsjsVDm?nGWk=QBvscUDvW4WaM;(_3GX)_M(M~op! zb7PMliT`DsH!)&=ysKeh*haHcn(1Ag^EHm^3N6pvJNcRJWnb&w_GPVm8)qGm+%bK| zCz+>#+m0nnw>l{ET+8m8WBNROHjdRvM+$5fPMQ*WZ$c|;s7A!!FU^%x{cM_N3(XH* z`0ZEnQt|1*8})7W*t2l8_H%7qGC?rELEC5U{k%far%}6)YCdL5TppqI@2Jwl36-^{ zI`%HRJ}+Q}&?DUo-0$9qd1iAnK literal 0 HcmV?d00001 diff --git a/weapp/images/right.svg b/weapp/images/right.svg new file mode 100644 index 0000000..817a3ee --- /dev/null +++ b/weapp/images/right.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/weapp/images/tabBar/icon_menu.png b/weapp/images/tabBar/icon_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..b168366cbc7362cb48093b0393aedfb291fafdac GIT binary patch literal 2296 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 S%@Xhc0000+ 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 FV1h@{5-tD$ literal 0 HcmV?d00001 diff --git a/weapp/images/tabBar/icon_person_active.png b/weapp/images/tabBar/icon_person_active.png new file mode 100644 index 0000000000000000000000000000000000000000..1fabd32e66e1862e6c92b77f15acd1ea0ad03a0f GIT binary patch literal 2540 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 literal 0 HcmV?d00001 diff --git a/weapp/images/tabBar/icon_polling_active.png b/weapp/images/tabBar/icon_polling_active.png new file mode 100644 index 0000000000000000000000000000000000000000..15fb86a3c46d009f13ae722dfe2e46c5bef9231f GIT binary patch literal 1830 zcma)7`#02i82)_6n48=+iA+<%EHz{+WrrrwkTIr|K^nt2NVyc2r23j~P!b2*LnorxAM%}VY_ZeoXt6*ok_w7RM}2J7 zB2g19Tvu#)fUt+IVt50i-X!fkJAUkt8uA#EB8~10$KOi8LHbcldJmn~O2r@Avnk{m z0U3FZKHQQqDiF*@TkRbfE8w%6WwS$Le8J4eji0Lj#MxK*_jO$ZgIf>?DhL!%d&`{B zM6j1tI6Y9Npa$ofFu%+UKp1N8#`3kr8GtOD#tp{E!U2LArWj~_*%Cn6WJQnDqt)HR zRlI!s_h(7?lQm|YzT)jyM7ztLK_2KO#UM#Zf^8F}b5fkpVXo^J2m&G&_bQ6bTms(< z{ZTnRt`xt)x20J4SKM4uB_o!D*fQg9&MG{U?o^6`{b&(ea3-H**XhYA+&OKo2Apmz zC!%APfyTI`tEiQZc$ivJ9UyLmsRZ~Vp1#f+N&(19okw{}0P_2q6LnaU;0S!GeL0jN z8+EwqdQ~q025R6Ayi2=KVgJ!&{%@hGYHq)BBg1xSIfDNXqCnd$A;6d5VNn$2a|0SP zkgq~TWAu$`+2L@_#v+9m&>x)+RaxCoJbK@@14^N{T2S#M*7>cQfa}bs9WRc$_cb7e zE;X6cwXYQ7x+Xr_p+nD}a8RzCfS`3{-lIQ!G4sC&`;~HH)Ck^9R%IyIm3GiY zLKR&gEBTR^Cw)W{9XcU_KpS^FVzZirc`$>0zg?Slw*tXYZj z42z_W@||;o5YzTRmJ40>{P7JGKL{hl2daauafUU!^f;IMr63%}HpMxX($R$qlUE$& z_R?8yv!gR099Rl*3U81XG~JrL>tD;XkbTCXkxM0By1Q5MuL5y(8ZGaq@!O=w^L^dU z{XWyk$~RE1-a1nF*4WUZi+iG0y-EwtNhU;EaV@$M@jtA@j~9J0nmRYvpgVCAN9C7r z*Y4c=1@3q-rt7=#a7sH9A^Cm%;azE5$G*QczJu)ZHXu@$W!e5T&||>31iyxuqV>q5 z@4&^zK_&P_U&AW9P0$-~az&yToQQ?z$MI*JLB}FD)iKIa7_s^iO7QG|9OOxSh+H-H zsA-mOfgVxn60Ep(>g+TkO+~^FXk8}1{m-W#ssXz*fXwdoWVC5W42(j(SRt>9wEuc{ z-^hFEc8a9Zn8Dc`aymQfV4dUnsn97bNQq*U1bk^RiwUHCauO#N^(I>@OD=-Z;@IX9 zto5e$p>?`=>Eol9MT^z3s=r0}IhbLbh(C|1wC2ByUicc|HI%7m?#jORL99}6=KWnv zL829#(Ih5j9NspOiQ>>zFUB0`^o_b+H9t2ZvqqX;zrif+ldeFyL6_Bes@-iHW=wcb z)(c{0N9wh}N__&3V?ig8{S8l80%gUEbP*cMYiuLEEQ0tB)rcOxm2tRo2Kg##F{ z75l{sO}hD}PM&zzXVdLfwF+}q<@J9J2}S2Is;wWc6?|*7T+U`QV*yQ;(^ECoFRDNJ zc~*N5R#q8MVI>Sr?-dmA#&Z&kzC9;qu=XXpOUehgw|n6?Jy?0hT9^;~l#^^t7M@9L zUGRy&!fMz9hKN$BYP=~oIJX|WljTqvGPO5ey&3ahThwZdGdXGcg7T5pW29g{BF;SI zdm6;q-<2aE1dx8*rC@Q2?g3u~o&?_oJN7qM*2;VHANiazJA!h1F%BR6yL#ExyBRI@ zx?DFxmQK{U&BNTZr)H%Xyf3!p&e|BFAJpXTn0ReW1?QHWtSuq?D>u(+?f`W%!>##X zM~iJ8Rs)>6oRPu+>0aAMkXX3taTm=9beX0F@sL8-vB?rmcrvSV-ysBtAF|Mor7k%7 z<`JP9k;R%6NnA5{=#&bEXY*ph5vkuaUK!f|zcYWM@x^P+-rjXj<&O_I*fDGcHXPnR D11mKw literal 0 HcmV?d00001 diff --git a/weapp/images/userName.png b/weapp/images/userName.png new file mode 100644 index 0000000000000000000000000000000000000000..19197d1ca88e08356aa7cb2eb5b9c8ee07371595 GIT binary patch literal 1612 zcmaJ>drT8|96x9Qtzjx4I415m98sii+S1x8wJq348PbX+f^xK1T1$Ip?|_y$hoD5X zYJChfGTlQAYJ!N1b858J%_@o*bqF$*X^<&CaEh}L!>$OpKgKS(`#tjce7>(wt~xU# zEtD2b0{|dYxj>#pt|0kBph+)*mhe<8 z6(&QBrUhj-L|vAl(UqBXLOnEZE-1E(NC68%z@XhyWW_~x2{fcDBKQ7lCIk*a2(tuw zpOjXW3Cd6#0`eGqx{k#cfC3?d%@YWc1c@Mr#pW?tTqc)A=WsAW05BbWF!bo#AKG1mNH7Y4AfT0WDA8tCX2)5aOfn0jytRbY^PiCxDf?8g6nK1 zj4+{A(60y=pv8m)A~Stof(09uwc^8VA{)lE!x)pzVEIcL0jgC054BiE(KwNXe8~4d zg>j7oLzr0zjuzW=OXKfV{-j=uwZ0lIbt)FAo^4rY5|AJ7MaG(g`Ya6-Y{1`b}pOtR{=oaX{B7MvETlsX6b^((ugXrT3T0K zH*QKtP{f99)J666Ynvx!-idVU`;x$9o`uabFvaV~G3Hk6Yx*?!@9YsKou z_AN2mkTM|}f^;d?_nb@#y%@N}6MZe@y4%(AQIhdN8|!MZnPT=Vbd7t~Ic-g?kJC5) z34i_0d-;^9f4rFX7X(hPy)RDN-N~H3v%MQTb0Dno^EsW*gTbGq2|hPnyJZerCQv*Y;nEmiWn12azmn_a1q2NzvX(hk=Z_~-$} zt4rifo6dtZy?JW!Y|q=fM{1r>QEA|<@Q66nSJi8L4J_<%U%c}?m{QbYEt~AR@acgS z(wXm;-AGdP&>BN`H07Q0bZXpj_>{G8b1Kx2(i?8ZW0w`)*%=Mo%#Ah)ciyzU(;RW0EO%%UvV)qx zK3mf&=0yEi6$W~m%C~-*+v0pmeQ=uHeX@Lp>#}bd@7P1);jaQ<88jo$GRng9Q;RAk5-=I2-Z1I`F+K>z>% literal 0 HcmV?d00001 diff --git a/weapp/images/xunjian.svg b/weapp/images/xunjian.svg new file mode 100644 index 0000000..14be311 --- /dev/null +++ b/weapp/images/xunjian.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/weapp/package/basic/basic.js b/weapp/package/basic/basic.js new file mode 100644 index 0000000..9797171 --- /dev/null +++ b/weapp/package/basic/basic.js @@ -0,0 +1,66 @@ +// package/basic/basic.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/weapp/package/basic/basic.json b/weapp/package/basic/basic.json new file mode 100644 index 0000000..c445021 --- /dev/null +++ b/weapp/package/basic/basic.json @@ -0,0 +1,6 @@ +{ + "navigationBarBackgroundColor": "#1979ff", + "navigationBarTextStyle": "white", + "navigationBarTitleText": "基本信息", + "enablePullDownRefresh": false +} \ No newline at end of file diff --git a/weapp/package/basic/basic.wxml b/weapp/package/basic/basic.wxml new file mode 100644 index 0000000..2f46d51 --- /dev/null +++ b/weapp/package/basic/basic.wxml @@ -0,0 +1,41 @@ + + + + + + 超级管理 + + + + + 姓名: + + 管理员 + + + + 电话: + + 18965662365 + + + + 部门: + + 管理部门 + + + + 职务: + + 系统管理员 + + + + 邮箱: + + chendingming@free-sun.com.cn + + + + \ No newline at end of file diff --git a/weapp/package/basic/basic.wxss b/weapp/package/basic/basic.wxss new file mode 100644 index 0000000..6b6d410 --- /dev/null +++ b/weapp/package/basic/basic.wxss @@ -0,0 +1,60 @@ +/* package/basic/basic.wxss */ + +page { + background-color: rgb(242, 242, 245); +} + +.page { + padding: 30rpx; +} + +.header-item-container { + width: 100%; + height: 180rpx; + background: rgb(255, 255, 255); + border-radius: 10rpx; + flex-direction: row; + display: flex; + justify-content: start; + align-items: center; + box-shadow: 0rpx 0rpx 16rpx #ccc; +} + +.logo { + width: 120rpx; + height: 120rpx; + padding: 30rpx; +} + +.userName { + font-size: 36rpx; + font-weight: 600; +} + +.list { + color: #6C6C6C; + background: #fff; + padding: 40rpx; + box-sizing: border-box; + width: 100%; + margin: 40rpx auto; + border-radius: 10rpx; + box-shadow: 0rpx 0rpx 16rpx #ccc; +} + +.content { + width: 100%; + overflow: hidden; + margin: 20rpx auto; +} + +.title { + float: left; +} + +.value { + float: left; + margin-left: 80rpx; + width: 400rpx; + word-break: break-word; +} \ No newline at end of file diff --git a/weapp/package/polling/polling.js b/weapp/package/polling/polling.js new file mode 100644 index 0000000..2cee9c4 --- /dev/null +++ b/weapp/package/polling/polling.js @@ -0,0 +1,71 @@ +// package/polling/polling.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + + }, + + // 顶部tab切换 + clickTab(e) { + + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/weapp/package/polling/polling.json b/weapp/package/polling/polling.json new file mode 100644 index 0000000..e7563af --- /dev/null +++ b/weapp/package/polling/polling.json @@ -0,0 +1,6 @@ +{ + "navigationBarBackgroundColor": "#1979ff", + "navigationBarTextStyle": "white", + "navigationBarTitleText": "巡检", + "enablePullDownRefresh": false +} \ No newline at end of file diff --git a/weapp/package/polling/polling.wxml b/weapp/package/polling/polling.wxml new file mode 100644 index 0000000..245eab7 --- /dev/null +++ b/weapp/package/polling/polling.wxml @@ -0,0 +1,11 @@ + + + + + 巡检记录 + + + + 待巡检 + + \ No newline at end of file diff --git a/weapp/package/polling/polling.wxss b/weapp/package/polling/polling.wxss new file mode 100644 index 0000000..499c174 --- /dev/null +++ b/weapp/package/polling/polling.wxss @@ -0,0 +1,33 @@ +/* package/polling/polling.wxss */ + +.page { + min-height: 100vh; + background: #F7F7FA; + position: relative; +} + +/* 顶部tab */ +.swiper-tab { + display: flex; + height: 98rpx; + line-height: 98rpx; + width: 100%; + position: fixed; + top: 0; + z-index: 100; + background: #fff; + border-bottom: 2rpx solid #e8e8e8; +} + +.swiper-tab-item { + flex: 1; + font-size: 28rpx; + text-align: center; + color: #333333; + position: relative; +} + +.active { + color: #1979ff; + position: relative; +} \ No newline at end of file diff --git a/weapp/pages/index/index.js b/weapp/pages/index/index.js new file mode 100644 index 0000000..43c1b80 --- /dev/null +++ b/weapp/pages/index/index.js @@ -0,0 +1,66 @@ +// pages/index/index.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + dataList:[1,2,3,4] + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/weapp/pages/index/index.json b/weapp/pages/index/index.json new file mode 100644 index 0000000..9b25508 --- /dev/null +++ b/weapp/pages/index/index.json @@ -0,0 +1,6 @@ +{ + "navigationBarBackgroundColor": "#1979ff", + "navigationBarTextStyle": "white", + "navigationBarTitleText": "巡检总览", + "enablePullDownRefresh": false +} \ No newline at end of file diff --git a/weapp/pages/index/index.wxml b/weapp/pages/index/index.wxml new file mode 100644 index 0000000..c584a56 --- /dev/null +++ b/weapp/pages/index/index.wxml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + 结构物A + + 今日问题:12 + 未处理问题:12 + 已处理问题:12 + + + + + + + \ No newline at end of file diff --git a/weapp/pages/index/index.wxss b/weapp/pages/index/index.wxss new file mode 100644 index 0000000..0a8eca4 --- /dev/null +++ b/weapp/pages/index/index.wxss @@ -0,0 +1,55 @@ +/* pages/index/index.wxss */ +page { + background: rgb(242, 242, 245); +} + +.searchBoxs { + position: relative; + margin: 20rpx 0rpx; + height: 76rpx; +} + +.searchInps { + background-color: #fff; + width: 542rpx; + height: 76rpx; + border-radius: 8rpx; + padding-left: 32rpx; + padding-right: 144rpx; + border: 1px solid rgba(225, 225, 225, 0.44); + position: absolute; + top: -2rpx; + left: 16rpx; + font-size: 28rpx; +} + +.btnSearch { + width: 128rpx; + height: 68rpx; + line-height: 68rpx; + border-radius: 8rpx; + color: #fff; + font-size: 28rpx; + background: linear-gradient(180deg, #1979ff 0%, #1979ff 100%); + position: absolute; + top: 6rpx; + right: 28rpx; + z-index: 10; +} + +.searchFixed { + position: fixed; + top: 0; + width: 100%; + background-color: #fff; + box-shadow: 0rpx -4rpx 20rpx #c2c2c2; + z-index: 10; +} + +.box { + padding: 20rpx; + box-shadow: 0rpx 0rpx 10rpx #ccc; + overflow: hidden; + line-height: 50rpx; + background: #fff; +} \ No newline at end of file diff --git a/weapp/pages/login/login.js b/weapp/pages/login/login.js new file mode 100644 index 0000000..b7ffc4e --- /dev/null +++ b/weapp/pages/login/login.js @@ -0,0 +1,91 @@ +// pages/login/login.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + + }, + + setColor: function () { + this.setData({ + backgroundInput: this.data.userNameCan == true && this.data.passwordCan == true ? 'rgb(51, 133, 255)' : 'rgb(255,255,255)', + colorInput: this.data.userNameCan == true && this.data.passwordCan == true ? 'rgb(255, 255, 255)' : 'rgb(201,201,201)', + }) + }, + bindUserName: function (e) { + this.setData({ + userNameCan: e.detail.value.length > 0 ? true : false, + }) + this.setColor(); + }, + bindPassword: function (e) { + this.setData({ + passwordCan: e.detail.value.length > 0 ? true : false, + }) + this.setColor(); + }, + + getLogin: function (e) { + wx.switchTab({ + url: '/pages/index/index', + }) + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/weapp/pages/login/login.json b/weapp/pages/login/login.json new file mode 100644 index 0000000..03fe9a2 --- /dev/null +++ b/weapp/pages/login/login.json @@ -0,0 +1,6 @@ +{ + "navigationBarBackgroundColor": "#fff", + "navigationBarTextStyle": "white", + "navigationBarTitleText": "登录", + "enablePullDownRefresh": false +} \ No newline at end of file diff --git a/weapp/pages/login/login.wxml b/weapp/pages/login/login.wxml new file mode 100644 index 0000000..4292433 --- /dev/null +++ b/weapp/pages/login/login.wxml @@ -0,0 +1,25 @@ + + + + + + +
+ + + + + + + + + + + +
+
+ + + 仅提供内部人员使用 + ©飞尚科技 + \ No newline at end of file diff --git a/weapp/pages/login/login.wxss b/weapp/pages/login/login.wxss new file mode 100644 index 0000000..f91214d --- /dev/null +++ b/weapp/pages/login/login.wxss @@ -0,0 +1,156 @@ +/* pages/login/login.wxss */ +page { + background: rgb(255, 255, 255); +} + +.logo-container { + margin-top: 85rpx; + margin-bottom: 125rpx; + display: flex; + justify-content: center; + align-items: center; + text-align: center; +} + +.logo { + width: 180rpx; + height: 180rpx; +} + +.body-container { + display: flex; + justify-content: center; + align-items: center; +} + +.marginBottom { + margin-bottom: 30rpx; +} + +.userName-container { + width: 580rpx; + height: 95rpx; + background: rgb(245, 245, 247); + border-radius: 10rpx; + display: flex; + justify-content: center; + align-items: center; +} + +.userName-logo { + width: 30rpx; + height: 34rpx; + padding-right: 15rpx; + border-right: 1px dashed #8A8A8A; +} + +.password-logo { + width: 30rpx; + height: 34rpx; + padding-right: 15rpx; + border-right: 1px dashed #8A8A8A; +} + +.input { + width: 492rpx; + height: 95rpx; + padding-left: 15rpx; + font-size: 32rpx; +} + +.login-btn { + width: 580rpx !important; + height: 98rpx; + margin-top: 90rpx; + color: rgb(201, 201, 201); + background: rgb(255, 255, 255); + display: flex; + justify-content: center; + align-items: center; + border-radius: 10rpx; +} + +.backColor { + color: rgb(138, 138, 138); +} + + + +/* 按钮 */ +.cancle-sure { + width: 100%; + /* height: 100rpx; */ + background: white; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #E5E5E5; +} + +.sure { + color: rgb(36, 123, 255); + padding: 30rpx; + font-size: 36rpx; +} + +.picker-view-column-container { + display: flex; + justify-content: center; + align-items: center; +} + +.sitePicker { + width: 100%; + height: 240rpx; + font-size: 34rpx; + padding-left: 30rpx; + padding-right: 30rpx; +} + +.picker-item { + display: flex; + justify-content: center; + align-items: center; + font-size: 34rpx; + overflow: hidden; +} + +.sensorTypePicker { + width: 100%; + height: 240rpx; + font-size: 34rpx; + padding-left: 30rpx; + padding-right: 30rpx; +} + +.indecate { + display: flex; + justify-content: center; + align-items: center; + color: rgb(241, 241, 242); +} + + +.noSensor-container { + height: 800rpx; + flex-direction: column; + display: flex; + justify-content: center; + align-items: center; + /* background: rgb(0,0,0); */ +} + + +.selectIndex { + height: 80rpx; +} + +.co-info { + position: fixed; + bottom: 10px; + left: 0; + width: 100vw; + color: #ccc; + text-align: center; + font-size: 14px +} \ No newline at end of file diff --git a/weapp/pages/myInfo/myInfo.js b/weapp/pages/myInfo/myInfo.js new file mode 100644 index 0000000..8420c0d --- /dev/null +++ b/weapp/pages/myInfo/myInfo.js @@ -0,0 +1,72 @@ +// pages/myInfo/myInfo.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + + }, + + bindClick() { + wx.navigateTo({ + url: '/package/basic/basic', + }) + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/weapp/pages/myInfo/myInfo.json b/weapp/pages/myInfo/myInfo.json new file mode 100644 index 0000000..bbb9521 --- /dev/null +++ b/weapp/pages/myInfo/myInfo.json @@ -0,0 +1,6 @@ +{ + "navigationBarBackgroundColor": "#1979ff", + "navigationBarTextStyle": "white", + "navigationBarTitleText": "我的", + "enablePullDownRefresh": false +} \ No newline at end of file diff --git a/weapp/pages/myInfo/myInfo.wxml b/weapp/pages/myInfo/myInfo.wxml new file mode 100644 index 0000000..a516cd0 --- /dev/null +++ b/weapp/pages/myInfo/myInfo.wxml @@ -0,0 +1,25 @@ + + + + + + 超级管理 + + + + + + 基本信息 + + + + + + + + 退出登录 + + \ No newline at end of file diff --git a/weapp/pages/myInfo/myInfo.wxss b/weapp/pages/myInfo/myInfo.wxss new file mode 100644 index 0000000..6643e6f --- /dev/null +++ b/weapp/pages/myInfo/myInfo.wxss @@ -0,0 +1,100 @@ +/* pages/myInfo/myInfo.wxss */ + +page { + background-color: rgb(242, 242, 245); +} + +/* 容器 */ +.box { + padding: 30rpx; + font-family: 'PingFang SC-Medium'; +} + +.header-item-container { + width: 100%; + height: 180rpx; + background: rgb(255, 255, 255); + border-radius: 10rpx; + flex-direction: row; + display: flex; + justify-content: start; + align-items: center; +} + +.logo { + width: 120rpx; + height: 120rpx; + padding: 30rpx; +} + +.userName { + font-size: 36rpx; + font-weight: 600; +} + +.company { + font-size: 28rpx; + font-family: "PingFang SC"; + color: rgb(138, 138, 138); + margin-top: 14rpx; +} + +.body-container { + width: 100%; + background: rgb(255, 255, 255); + border-radius: 10rpx; + flex-direction: column; + display: flex; + margin-top: 30rpx; + margin-bottom: 30rpx; +} + +.body-item { + height: 110rpx; + flex-direction: row; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 30rpx; + border-bottom: 1px solid #EFEFF4; +} + +.body-info { + font-size: 32rpx; + font-family: "PingFang SC"; + font-weight: 600; +} + +.body-number { + font-size: 30rpx; + font-family: "PingFang SC"; + color: rgb(138, 138, 138); +} + +.foot-container { + width: 100%; + background: rgb(255, 255, 255); + border-radius: 10rpx; + flex-direction: column; + display: flex; + border: 1px #FFFFFF; +} + +.foot-item { + color: rgb(0, 0, 0); + display: flex; + justify-content: center; + align-items: center; + padding: 30rpx; + font-size: 32rpx; + font-family: "PingFang SC"; + font-weight: 600; +} + +.right { + width: 32rpx; + height: 32rpx; + display: block; + float: right; + margin: 38rpx 40rpx; +} \ No newline at end of file diff --git a/weapp/pages/overview/overview.js b/weapp/pages/overview/overview.js new file mode 100644 index 0000000..375a9d0 --- /dev/null +++ b/weapp/pages/overview/overview.js @@ -0,0 +1,73 @@ +// pages/overview/overview.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + + }, + + // 巡检 + bindPolling() { + wx.navigateTo({ + url: '/package/polling/polling', + }) + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/weapp/pages/overview/overview.json b/weapp/pages/overview/overview.json new file mode 100644 index 0000000..db1d7cd --- /dev/null +++ b/weapp/pages/overview/overview.json @@ -0,0 +1,6 @@ +{ + "navigationBarBackgroundColor": "#1979ff", + "navigationBarTextStyle": "white", + "navigationBarTitleText": "工作台", + "enablePullDownRefresh": false +} \ No newline at end of file diff --git a/weapp/pages/overview/overview.wxml b/weapp/pages/overview/overview.wxml new file mode 100644 index 0000000..8360bb5 --- /dev/null +++ b/weapp/pages/overview/overview.wxml @@ -0,0 +1,18 @@ + + + + + 巡检 + + + + \ No newline at end of file diff --git a/weapp/pages/overview/overview.wxss b/weapp/pages/overview/overview.wxss new file mode 100644 index 0000000..36b2a22 --- /dev/null +++ b/weapp/pages/overview/overview.wxss @@ -0,0 +1,35 @@ +/* pages/overview/overview.wxss */ + +page { + background-color: rgb(242, 242, 245); +} + +.box { + width: 672rpx; + height: 178rpx; + margin: 42rpx auto 21rpx; + background: #fff; + box-shadow: 0rpx 0rpx 10rpx #ccc; + border-radius: 8rpx; +} + +.logo { + width: 90rpx; + height: 90rpx; + float: left; + margin: 48rpx 50rpx 0 50rpx; +} + +.txt { + float: left; + line-height: 112rpx; + margin: 34rpx; +} + +.right { + width: 32rpx; + height: 32rpx; + display: block; + float: right; + margin: 74rpx 40rpx; +} \ No newline at end of file diff --git a/weapp/project.config.json b/weapp/project.config.json new file mode 100644 index 0000000..a674783 --- /dev/null +++ b/weapp/project.config.json @@ -0,0 +1,51 @@ +{ + "description": "项目配置文件", + "packOptions": { + "ignore": [], + "include": [] + }, + "setting": { + "bundle": false, + "userConfirmedBundleSwitch": false, + "urlCheck": true, + "scopeDataCheck": false, + "coverView": true, + "es6": true, + "postcss": true, + "compileHotReLoad": false, + "lazyloadPlaceholderEnable": false, + "preloadBackgroundData": false, + "minified": true, + "autoAudits": false, + "newFeature": false, + "uglifyFileName": false, + "uploadWithSourceMap": true, + "useIsolateContext": true, + "nodeModules": false, + "enhance": true, + "useMultiFrameRuntime": true, + "useApiHook": true, + "useApiHostProcess": true, + "showShadowRootInWxmlPanel": true, + "packNpmManually": false, + "enableEngineNative": false, + "packNpmRelationList": [], + "minifyWXSS": true, + "showES6CompileOption": false, + "minifyWXML": true, + "babelSetting": { + "ignore": [], + "disablePlugins": [], + "outputPath": "" + } + }, + "compileType": "miniprogram", + "libVersion": "2.19.4", + "appid": "wxe9595234589a0147", + "projectname": "miniprogram-92", + "condition": {}, + "editorSetting": { + "tabIndent": "insertSpaces", + "tabSize": 2 + } +} \ No newline at end of file diff --git a/weapp/project.private.config.json b/weapp/project.private.config.json new file mode 100644 index 0000000..9e505b5 --- /dev/null +++ b/weapp/project.private.config.json @@ -0,0 +1,36 @@ +{ + "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", + "projectname": "%E5%B7%A1%E6%A3%80%E5%B0%8F%E7%A8%8B%E5%BA%8F", + "setting": { + "compileHotReLoad": false, + "urlCheck": false + }, + "condition": { + "miniprogram": { + "list": [ + { + "name": "", + "pathName": "pages/login/login", + "query": "", + "launchMode": "default", + "scene": null + }, + { + "name": "", + "pathName": "package/polling/polling", + "query": "", + "launchMode": "default", + "scene": null + }, + { + "name": "", + "pathName": "package/basic/basic", + "query": "", + "launchMode": "default", + "scene": null + } + ] + } + }, + "libVersion": "2.29.0" +} \ No newline at end of file diff --git a/weapp/sitemap.json b/weapp/sitemap.json new file mode 100644 index 0000000..ca02add --- /dev/null +++ b/weapp/sitemap.json @@ -0,0 +1,7 @@ +{ + "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", + "rules": [{ + "action": "allow", + "page": "*" + }] +} \ No newline at end of file diff --git a/weapp/utils/util.js b/weapp/utils/util.js new file mode 100644 index 0000000..764bc2c --- /dev/null +++ b/weapp/utils/util.js @@ -0,0 +1,19 @@ +const formatTime = date => { + const year = date.getFullYear() + const month = date.getMonth() + 1 + const day = date.getDate() + const hour = date.getHours() + const minute = date.getMinutes() + const second = date.getSeconds() + + return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}` +} + +const formatNumber = n => { + n = n.toString() + return n[1] ? n : `0${n}` +} + +module.exports = { + formatTime +} From ac40727ed349fb94db5a2873a54fe44e0424483e Mon Sep 17 00:00:00 2001 From: Archer_cdm Date: Mon, 16 Jan 2023 18:34:32 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=EF=BC=88*=EF=BC=89=E7=99=BB=E5=BD=95+?= =?UTF-8?q?=E7=99=BB=E5=87=BA+=E5=9F=BA=E6=9C=AC=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- weapp/app.js | 18 ++------- weapp/common.js | 73 ++++++++++++++++++++++++++++++++++ weapp/package/basic/basic.js | 6 ++- weapp/package/basic/basic.wxml | 10 ++--- weapp/pages/index/index.js | 16 ++++++-- weapp/pages/login/login.js | 32 +++++++++++++-- weapp/pages/myInfo/myInfo.js | 32 ++++++++++++++- weapp/pages/myInfo/myInfo.wxml | 2 +- weapp/utils/getApiUrl.js | 9 +++++ 9 files changed, 170 insertions(+), 28 deletions(-) create mode 100644 weapp/common.js create mode 100644 weapp/utils/getApiUrl.js diff --git a/weapp/app.js b/weapp/app.js index dca5e21..a30c895 100644 --- a/weapp/app.js +++ b/weapp/app.js @@ -1,20 +1,10 @@ // app.js App({ - onLaunch() { - // // 展示本地存储能力 - // const logs = wx.getStorageSync('logs') || [] - // logs.unshift(Date.now()) - // wx.setStorageSync('logs', logs) - - // // 登录 - // wx.login({ - // success: res => { - // // 发送 res.code 到后台换取 openId, sessionKey, unionId - // } - // }) - }, + onLaunch() { }, globalData: { - userInfo: null + userInfo: null, + baseUrl: 'http://10.8.16.221:4900', //api 本地环境 + // imgUrl: 'http://10.8.16.221:5000/_file-server/', //本地环境 }, onShow(e) { // 检查是否有更新 diff --git a/weapp/common.js b/weapp/common.js new file mode 100644 index 0000000..a8abae1 --- /dev/null +++ b/weapp/common.js @@ -0,0 +1,73 @@ +const app = getApp(); +const { baseUrl } = app.globalData; + +// 全局配置 请求拦截, 长时间 +const buildRequest = (type, url, data) => { + return new Promise((resolve, reject) => { + if (url.indexOf('token') == -1) { + let token = wx.getStorageSync('token'); + if (token) { + url += url.indexOf('?') == -1 ? '?' : '&'; + url += `token=${token}`; + } + } + if (url.indexOf('http') != 0) { + url = baseUrl + url; + } + + wx.request({ + url, + data, + method: type, + success: res => { + if (res.statusCode == 200 || res.statusCode == 204) { + resolve(res.data); + return; + } + if (res.statusCode == 400) { + console.error("400报错" + url, res); + wx.showToast({ + title: res.data.message, + icon: "none", + duration: 1500 + }); + // reject(res); + } + if (res.statusCode == 401) { + wx.clearStorageSync(); + wx.reLaunch({ + url: '/pages/login/login' + }); + } + }, + fail: err => { + wx.showToast({ + title: '网络异常', + icon: 'none', + duration: 1500 + }) + console.error('网络异常' + url, err); + reject(err); + } + }); + }); +} + +// 请求拦截 +let Request = {}; +Request.get = (url, query) => { + return buildRequest('GET', url, query); +} +Request.post = (url, data) => { + return buildRequest('POST', url, data); +} +Request.put = (url, data) => { + return buildRequest('PUT', url, data); +} +Request.del = (url, data) => { + return buildRequest('DELETE', url, data); +} + +module.exports = { + Request +} \ No newline at end of file diff --git a/weapp/package/basic/basic.js b/weapp/package/basic/basic.js index 9797171..80023ae 100644 --- a/weapp/package/basic/basic.js +++ b/weapp/package/basic/basic.js @@ -12,7 +12,11 @@ Page({ * 生命周期函数--监听页面加载 */ onLoad(options) { - + let that = this; + let userInfo = wx.getStorageSync('userInfo'); + that.setData({ + userInfo + }) }, /** diff --git a/weapp/package/basic/basic.wxml b/weapp/package/basic/basic.wxml index 2f46d51..b308372 100644 --- a/weapp/package/basic/basic.wxml +++ b/weapp/package/basic/basic.wxml @@ -3,20 +3,20 @@ - 超级管理 + {{userInfo.name || '--'}} 姓名: - 管理员 + {{userInfo.name || '--'}} 电话: - 18965662365 + {{userInfo.phone || '--'}} @@ -28,13 +28,13 @@ 职务: - 系统管理员 + {{userInfo.post || '--'}} 邮箱: - chendingming@free-sun.com.cn + {{userInfo.email || '--'}} diff --git a/weapp/pages/index/index.js b/weapp/pages/index/index.js index 43c1b80..f02309b 100644 --- a/weapp/pages/index/index.js +++ b/weapp/pages/index/index.js @@ -5,14 +5,19 @@ Page({ * 页面的初始数据 */ data: { - dataList:[1,2,3,4] + dataList: [1, 2, 3, 4] }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { - + const userInfo = wx.getStorageSync('userInfo'); + if (!userInfo || !userInfo.id) { + wx.reLaunch({ + url: '/pages/login/login' + }); + } }, /** @@ -26,7 +31,12 @@ Page({ * 生命周期函数--监听页面显示 */ onShow() { - + const userInfo = wx.getStorageSync('userInfo'); + if (!userInfo || !userInfo.id) { + wx.reLaunch({ + url: '/pages/login/login' + }); + } }, /** diff --git a/weapp/pages/login/login.js b/weapp/pages/login/login.js index b7ffc4e..8589e83 100644 --- a/weapp/pages/login/login.js +++ b/weapp/pages/login/login.js @@ -1,11 +1,15 @@ // pages/login/login.js +import { loginUrl } from "../../utils/getApiUrl"; +import { Request } from "../../common"; + Page({ /** * 页面的初始数据 */ data: { - + userNameCan: false, + passwordCan: false, }, setColor: function () { @@ -27,9 +31,31 @@ Page({ this.setColor(); }, + // 登录 getLogin: function (e) { - wx.switchTab({ - url: '/pages/index/index', + if (e.detail.value.username.length == 0 || e.detail.value.password == 0) { + wx.showToast({ + title: '请输入用户名密码', + icon: 'none', + }) + return + } + wx.showLoading() + Request.post(loginUrl(), { + "username": e.detail.value.username, + "password": e.detail.value.password + }).then((res) => { + if (!res.authorized) { + wx.showToast({ title: "登录失败", icon: "none" }); + return; + } + wx.setStorageSync('token', res.token); + wx.setStorageSync("userInfo", res); + getApp().globalData.userInfo = res + wx.switchTab({ + url: '/pages/index/index', + }) + wx.hideLoading() }) }, diff --git a/weapp/pages/myInfo/myInfo.js b/weapp/pages/myInfo/myInfo.js index 8420c0d..634e481 100644 --- a/weapp/pages/myInfo/myInfo.js +++ b/weapp/pages/myInfo/myInfo.js @@ -1,4 +1,7 @@ // pages/myInfo/myInfo.js +import { logoutUrl } from "../../utils/getApiUrl"; +import { Request } from "../../common"; + Page({ /** @@ -14,11 +17,38 @@ Page({ }) }, + // 登出 + logout() { + wx.showModal({ + title: '切换用户', + content: '将退出当前用户,重新登录', + confirmText: '切换用户', + confirmColor: '#1979ff', + success: res => { + if (res.confirm) { + wx.showLoading() + Request.put(logoutUrl(), {}).then((res) => { + wx.clearStorage(); + getApp().globalData.userInfo = null; + wx.reLaunch({ + url: '../login/login', + }) + wx.hideLoading() + }) + } + } + }) + }, + /** * 生命周期函数--监听页面加载 */ onLoad(options) { - + let that = this; + let userInfo = wx.getStorageSync('userInfo'); + that.setData({ + userInfo + }) }, /** diff --git a/weapp/pages/myInfo/myInfo.wxml b/weapp/pages/myInfo/myInfo.wxml index a516cd0..d52f06e 100644 --- a/weapp/pages/myInfo/myInfo.wxml +++ b/weapp/pages/myInfo/myInfo.wxml @@ -3,7 +3,7 @@ - 超级管理 + {{userInfo.name}} diff --git a/weapp/utils/getApiUrl.js b/weapp/utils/getApiUrl.js new file mode 100644 index 0000000..c98a4d0 --- /dev/null +++ b/weapp/utils/getApiUrl.js @@ -0,0 +1,9 @@ +// 登录 +exports.loginUrl = () => { + return `/login` +} + +// 登出 +exports.logoutUrl = () => { + return `/logout` +} \ No newline at end of file From b1dc22ed99533875a2a323734a2acdf1856a1d14 Mon Sep 17 00:00:00 2001 From: liujiangyong Date: Mon, 16 Jan 2023 18:37:43 +0800 Subject: [PATCH 4/4] =?UTF-8?q?(*)=20=E7=99=BB=E5=BD=95=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E9=83=A8=E9=97=A8=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/auth/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/app/lib/controllers/auth/index.js b/api/app/lib/controllers/auth/index.js index a03c824..85a6ab1 100644 --- a/api/app/lib/controllers/auth/index.js +++ b/api/app/lib/controllers/auth/index.js @@ -61,7 +61,8 @@ async function login(ctx, next) { authorized: true, token: token, userResources: userRes ? userRes.userResources.map(r => r.resourceId) : [], - type: deptInfo ? deptInfo.type : '' + type: deptInfo ? deptInfo.type : '', + deptName: deptInfo ? deptInfo.name : '', }); await models.UserToken.create({ token: token,