mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 08:52:28 +08:00
Compare commits
80 Commits
v3.6.0
...
v3.6.2last
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a857680d0 | |||
| a47d0984dc | |||
| e333b126b6 | |||
| 3618842f44 | |||
| fd8c848c9e | |||
| 09614a0239 | |||
| 6fe8f1d81a | |||
| 0bd7f715c4 | |||
| 041d88161e | |||
| 79a62aa056 | |||
| b86b4d9676 | |||
| aeaac80012 | |||
| e0ef20cf08 | |||
| 169a66f5dd | |||
| 7e39b31123 | |||
| 18765450a6 | |||
| dff8c84d9c | |||
| d962c34846 | |||
| cd9794d818 | |||
| 5034b7cf18 | |||
| fdde84c68a | |||
| 4c54ff6f52 | |||
| de3285dc1b | |||
| 7f0c035c4c | |||
| 43593e8def | |||
| 48b0b608d8 | |||
| 69287a772b | |||
| 337d5a9489 | |||
| cfeb81ee1e | |||
| 09f92f01aa | |||
| 6d1094936b | |||
| 8836a2793a | |||
| c36ece8923 | |||
| a82213b90c | |||
| 98facdd2ee | |||
| d080b0b5ea | |||
| 338902ca0c | |||
| 7ae6a11cf0 | |||
| cdbe1cb1a9 | |||
| 232037ec58 | |||
| b18c1120ab | |||
| f6a7831963 | |||
| 08a4473bbc | |||
| 9008ddafa4 | |||
| 7012ed4c2c | |||
| 1d8c8c30d0 | |||
| 090f790df4 | |||
| 82d051f388 | |||
| 5a3631c332 | |||
| c00b5526c3 | |||
| 2e35abd3a3 | |||
| 9bc3f6c56e | |||
| 5588912b62 | |||
| 37cf913d6d | |||
| 94ba767090 | |||
| a406c7cd81 | |||
| 480878a3db | |||
| a85499119d | |||
| 4cbe9cad8e | |||
| 2dfc06c679 | |||
| a591ad9fed | |||
| 5420e69b59 | |||
| f157c96f65 | |||
| 9588ace87f | |||
| cc57ac379b | |||
| 074920552a | |||
| 2a00a24058 | |||
| 06cc4ec0fe | |||
| decea393a5 | |||
| 65b0fab80d | |||
| 1d4098ae14 | |||
| 5c4f303a0d | |||
| 8dcc5bdf8a | |||
| b3e4a73a34 | |||
| 60b4a038f6 | |||
| 4e3738100a | |||
| 8216889078 | |||
| 6ab4ee6a91 | |||
| a8dde73a8c | |||
| b2b11611c1 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -10,3 +10,5 @@ rebel.xml
|
||||
## front
|
||||
**/*.lock
|
||||
os_del.cmd
|
||||
os_del_doc.cmd
|
||||
.svn
|
||||
|
||||
14
README-EN.md
14
README-EN.md
@ -7,13 +7,13 @@
|
||||
JEECG BOOT Low Code Development Platform
|
||||
===============
|
||||
|
||||
当前最新版本: 3.6.0(发布日期:2023-10-23)
|
||||
当前最新版本: 3.6.2(发布日期:2024-01-08)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://www.jeecg.com)
|
||||
[](https://jeecg.blog.csdn.net)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
@ -58,13 +58,12 @@ Download the source code
|
||||
| `jeecg-boot` | SpringBoot background source code (support microservices) |
|
||||
| `jeecgboot-vue3` | Vue3+TS new front-end source code|
|
||||
| `jeecg-uniapp` | [APP development framework, a code multi terminal adaptation, and support APP, small program, H5](https://github.com/jeecgboot/jeecg-uniapp) |
|
||||
| `jeecg-boot-starter` | [Stater relies on the project to be maintained separately. Click Download](https://gitee.com/jeecg/jeecg-boot-starter) |
|
||||
| `SpringBoot3+JDK17` | [BranchSourceCode](https://github.com/jeecgboot/jeecg-boot/tree/springboot3) [UpgradeBlog](https://blog.csdn.net/zhangdaiscott/article/details/134805602) |
|
||||
| `More` | [Download more source code](http://jeecg.com/download) |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
For the project
|
||||
-----------------------------------
|
||||
Jeecg-Boot low code development platform can be applied in the development of any J2EE project, especially for SAAS projects, enterprise information management system (MIS), internal office system (OA), enterprise resource planning system (ERP), customer relationship management system (CRM), etc. Its semi-intelligent manual Merge development method, Can significantly improve the development efficiency of more than 70%, greatly reduce the development cost.
|
||||
@ -88,12 +87,17 @@ Technical documentation
|
||||
- Doc: [http://help.jeecg.com](http://help.jeecg.com)
|
||||
- Newbie guide: [Quick start](http://www.jeecg.com/doc/quickstart) | [video](https://space.bilibili.com/454617261/channel/series) | [Q&A ](http://www.jeecg.com/doc/qa) | [help](http://jeecg.com/doc/help) | [1 minute experience](https://my.oschina.net/jeecg/blog/3083313)
|
||||
- Microservice Development: [Monomer upgrade to microservice](https://help.jeecg.com/java/springcloud/switchcloud/monomer.html)
|
||||
- QQ group : ⑦791696430、⑥730954414、683903138、⑤860162132(full)、④774126647(full)、③816531124(full)、②769925425(full)、①284271917(full)
|
||||
- QQ group : ⑧825232878、⑦791696430、⑥730954414(full)、683903138(full)、⑤860162132(full)、④774126647(full)、③816531124(full)、②769925425(full)、①284271917(full)
|
||||
- Demo : [Vue3](http://boot3.jeecg.com) | [Vue2](http://boot.jeecg.com) | [APP](http://jeecg.com/appIndex)
|
||||
> [please click obtain account password to obtain](http://jeecg.com/doc/demo)
|
||||
|
||||
|
||||
|
||||
Thinking
|
||||
-----------------------------------
|
||||
> We are pursuing the goal of implementing complex business systems without writing code! That has been done so far
|
||||
- https://www.qiaoqiaoyun.com
|
||||
|
||||
|
||||
Star charts
|
||||
-----------------------------------
|
||||
|
||||
26
README.md
26
README.md
@ -7,13 +7,13 @@
|
||||
JEECG BOOT 低代码开发平台
|
||||
===============
|
||||
|
||||
当前最新版本: 3.6.0(发布日期:2023-10-23)
|
||||
当前最新版本: 3.6.2(发布日期:2024-01-08)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://jeecg.com/aboutusIndex)
|
||||
[](https://jeecg.blog.csdn.net)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
@ -49,16 +49,17 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
| Github | [jeecgboot-vue3](https://github.com/jeecgboot/jeecgboot-vue3) | [jeecg-boot](https://github.com/jeecgboot/jeecg-boot) |
|
||||
| 码云 | [jeecgboot-vue3](https://gitee.com/jeecg/jeecgboot-vue3) | [jeecg-boot](https://gitee.com/jeecg/jeecg-boot) |
|
||||
|
||||
> 官方已推出 `SpringBoot3+JDK17版本` [分支源码下载](https://github.com/jeecgboot/jeecg-boot/tree/springboot3) | [升级SpringBoot3博客](https://blog.csdn.net/zhangdaiscott/article/details/134805602)
|
||||
|
||||
#### 项目说明
|
||||
|
||||
| 项目名 | 说明 |
|
||||
|--------------------|------------------------|
|
||||
| `jeecg-boot` | JAVA后台源码(支持微服务) |
|
||||
| `jeecgboot-vue3` | 前端源码 (Vue3版本) |
|
||||
| `jeecg-boot` | 后端JAVA源码(支持微服务) |
|
||||
| `jeecg-uniapp` | [APP开发框架,一份代码多终端适配,同时支持APP、小程序、H5](https://github.com/jeecgboot/jeecg-uniapp) |
|
||||
| `jeecg-boot-starter` | [Stater依赖项目单独维护,点击下载](https://gitee.com/jeecg/jeecg-boot-starter) |
|
||||
| `更多开源项目` | [更多源码下载](http://jeecg.com/download) |
|
||||
| `更多开源项目` | [更多底层源码下载](http://jeecg.com/download) |
|
||||
|
||||
|
||||
|
||||
快速搭建开发环境
|
||||
@ -82,16 +83,22 @@ Docker快速启动项目
|
||||
-----------------------------------
|
||||
|
||||
- 项目官网: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
- 开发文档: [http://help.jeecg.com](http://help.jeecg.com)
|
||||
- 开发文档: [https://help.jeecg.com](https://help.jeecg.com)
|
||||
- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [常见问题 ](http://www.jeecg.com/doc/qa) | [视频教程](https://space.bilibili.com/454617261/channel/series) | [1分钟低代码体验](https://my.oschina.net/jeecg/blog/3083313)
|
||||
|
||||
- 在线演示 : [Vue3演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex) | [敲敲云零代码](https://qiaoqiaoyun.com)
|
||||
> 演示系统的登录账号密码,请点击 [获取账号密码](http://jeecg.com/doc/demo) 获取
|
||||
>
|
||||
- QQ交流群 : ⑦791696430、⑥730954414、VUE3群683903138、⑤860162132(满)、④774126647(满)、③816531124(满)、②769925425(满)、①284271917(满)
|
||||
- QQ交流群 : ⑧825232878、⑦791696430(满)、⑥730954414(满)、683903138(满)、⑤860162132(满)、④774126647(满)、③816531124(满)、②769925425(满)、①284271917(满)
|
||||
> ` 提醒:【QQ群是自助服务群,建议给帮助您解决问题的同学发送指定红包,表示感谢!】 `
|
||||
|
||||
|
||||
大龄码农的思考
|
||||
-----------------------------------
|
||||
> 作为码农年纪大了写不动代码了怎么办??哎!!
|
||||
所以我们团队在追求不写代码也可实现复杂业务系统!目前已经做到了,不信你到敲敲云零代码试试(通过流程串联修改业务数据)
|
||||
|
||||
- https://www.qiaoqiaoyun.com
|
||||
|
||||
|
||||
技术支持
|
||||
@ -104,8 +111,6 @@ Docker快速启动项目
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
VUE2版本专题介绍
|
||||
-----------------------------------
|
||||
#### 项目介绍
|
||||
@ -462,8 +467,11 @@ Star走势图
|
||||
|
||||
```
|
||||
|
||||
### 流程引擎推荐
|
||||
|
||||
JeecgBoot企业版本默认集成了activiti和flowable两套方案,大家在使用本开源项目时,如果想进一步集成流程引擎,推荐结合贺波老师的书 [《深入Activiti流程引擎:核心原理与高阶实战》](https://item.m.jd.com/product/13928958.html?gx=RnAomTM2bmCImZxDqYAkVCoIHuIYVqc)
|
||||
|
||||
<img src="https://jeecgos.oss-cn-beijing.aliyuncs.com/files/tuijian20231220161656.png" width="25%" height="auto">
|
||||
|
||||
|
||||
### 系统效果
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,155 +0,0 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- 新增用户职位表关系表
|
||||
CREATE TABLE sys_user_position (
|
||||
id varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键',
|
||||
user_id varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户id',
|
||||
position_id varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '职位id',
|
||||
create_by varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人',
|
||||
create_time datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
|
||||
update_by varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改人',
|
||||
update_time datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (id) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
ALTER TABLE sys_user_position
|
||||
ADD INDEX idx_sup_user_id(user_id) USING BTREE,
|
||||
ADD INDEX idx_sup_position_id(position_id) USING BTREE,
|
||||
ADD INDEX idx_sup_user_position_id(user_id, position_id) USING BTREE;
|
||||
|
||||
-- 删除用户表的职位
|
||||
ALTER TABLE sys_user DROP COLUMN post;
|
||||
|
||||
|
||||
|
||||
-- 用户租户关系表修改索引
|
||||
ALTER TABLE `sys_user_tenant`
|
||||
DROP INDEX `uniq_sut_user_rel_tenant`,
|
||||
ADD INDEX `idx_sut_user_rel_tenant`(`user_id`, `tenant_id`) USING BTREE;
|
||||
|
||||
ALTER TABLE `sys_user_depart`
|
||||
DROP INDEX `idx_sud_user_dep_id`,
|
||||
ADD UNIQUE INDEX `idx_sud_user_dep_id`(`user_id`, `dep_id`) USING BTREE;
|
||||
|
||||
|
||||
-- 新增企业微信和钉钉配置表,通过租户模式隔离
|
||||
CREATE TABLE sys_third_app_config (
|
||||
id varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
tenant_id int(10) NOT NULL DEFAULT 0 COMMENT '租户id',
|
||||
agent_id varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '钉钉/企业微信应用id',
|
||||
client_id varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '钉钉/企业微信 应用id',
|
||||
client_secret varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '钉钉/企业微信应用id对应的秘钥',
|
||||
third_type varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '第三方类别(dingtalk 钉钉 wechat_enterprise 企业微信)',
|
||||
agent_app_secret varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '自建应用Secret',
|
||||
status int(1) NULL DEFAULT 1 COMMENT '是否启用(0-否,1-是)',
|
||||
create_time datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
|
||||
update_time datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (id) USING BTREE,
|
||||
UNIQUE INDEX uniq_stac_third_type_tenant_id(tenant_id, third_type) USING BTREE,
|
||||
INDEX idx_stac_tenant_id(tenant_id) USING BTREE,
|
||||
INDEX idx_stac_third_type(third_type) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '租户第三方配置表' ROW_FORMAT = Dynamic;
|
||||
|
||||
ALTER TABLE sys_third_account
|
||||
ADD UNIQUE INDEX uniq_sta_user_id_third_type(sys_user_id, third_type) USING BTREE,
|
||||
ADD UNIQUE INDEX uniq_sta_third_user_id_third_type(third_user_id, third_type) USING BTREE,
|
||||
ADD UNIQUE INDEX uniq_sta_third_user_uuid_third_type(third_user_uuid, third_type) USING BTREE;
|
||||
|
||||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) VALUES ('1629109281748291586', 'd7d6e2e4e2934f2c9385a623fd98c6f3', '第三方配置', '/third/app', 'system/appconfig/ThirdAppConfigList', 1, '', NULL, 1, NULL, '0', 13.00, 0, 'ant-design:setting-outlined', 1, 0, 0, 0, NULL, 'admin', '2023-02-24 21:21:35', 'admin', '2023-02-24 21:51:05', 0, 0, NULL, 0);
|
||||
|
||||
ALTER TABLE sys_third_account
|
||||
ADD COLUMN tenant_id int(10) NULL DEFAULT 0 COMMENT '租户id' AFTER realname;
|
||||
update sys_third_account set tenant_id = 0;
|
||||
|
||||
ALTER TABLE sys_third_account
|
||||
DROP INDEX uniq_sta_third_user_id_third_type,
|
||||
DROP INDEX uniq_sta_third_user_uuid_third_type,
|
||||
DROP INDEX uniq_sta_user_id_third_type,
|
||||
ADD UNIQUE INDEX uniq_sta_third_user_id_third_type(third_user_id, third_type, tenant_id) USING BTREE,
|
||||
ADD UNIQUE INDEX uniq_sta_third_user_uuid_third_type(third_user_uuid, third_type, tenant_id) USING BTREE;
|
||||
|
||||
ALTER TABLE `sys_third_app_config`
|
||||
DROP INDEX `uniq_stac_third_type_tenant_id`;
|
||||
|
||||
|
||||
-- 新增租户默认产品包
|
||||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) VALUES ('1674708136602542082', '', '我的租户', '/mytenant', 'layouts/RouteView', 1, '', NULL, 0, NULL, '0', 4.20, 0, 'ant-design:user-outlined', 0, 0, 0, 0, NULL, 'admin', '2023-06-30 17:15:09', 'admin', '2023-06-30 18:35:40', 0, 0, NULL, 0);
|
||||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) VALUES ('1663816667704500225', '1674708136602542082', '我的租户', '/tenant/MyTenantList', 'system/tenant/MyTenantList', 1, '', NULL, 1, NULL, '0', 1.00, 0, 'ant-design:user-outlined', 1, 0, 0, 0, NULL, 'admin', '2023-05-31 15:56:20', 'admin', '2023-06-30 18:37:26', 0, 0, NULL, 0);
|
||||
UPDATE sys_permission SET parent_id = '1674708136602542082' WHERE component = 'system/user/TenantUserList';
|
||||
UPDATE sys_permission SET parent_id = '1674708136602542082' WHERE component = 'system/role/TenantRoleList';
|
||||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) VALUES ('1661572802889007106', '', '租户管理', '/tenant/setting', 'layouts/RouteView', 1, NULL, NULL, 0, NULL, '1', 4.10, 0, 'ant-design:setting-outlined', 0, 0, 0, 0, NULL, 'admin', '2023-05-25 11:20:01', 'admin', '2023-06-30 18:37:04', 0, 0, '1', 0);
|
||||
UPDATE sys_permission SET parent_id = '1661572802889007106' WHERE component = 'system/tenant/index';
|
||||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) VALUES ('1668174661456171010', '1661572802889007106', '租户默认套餐', '/tenant/TenantDefaultPack', 'system/tenant/TenantDefaultPackList', 1, '', NULL, 1, NULL, '0', 5.00, 0, 'ant-design:folder-filled', 1, 0, 0, 0, NULL, 'admin', '2023-06-12 16:33:27', 'admin', '2023-06-30 19:09:24', 0, 0, NULL, 0);
|
||||
ALTER TABLE sys_tenant_pack
|
||||
ADD COLUMN pack_type varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'custom' COMMENT '产品包类型(default 默认产品包 custom 自定义产品包)' AFTER pack_code;
|
||||
update sys_tenant_pack set pack_type = 'custom';
|
||||
|
||||
ALTER TABLE sys_user_tenant
|
||||
MODIFY COLUMN status varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态(1 正常 2 离职 3 待审核 4 拒绝 5 邀请加入)' AFTER tenant_id;
|
||||
|
||||
UPDATE sys_permission SET component = 'system/tenant/my/MyTenantList' WHERE component = 'system/tenant/MyTenantList';
|
||||
UPDATE sys_permission SET component = 'system/tenant/pack/TenantDefaultPackList' WHERE component = 'system/tenant/TenantDefaultPackList';
|
||||
UPDATE sys_permission SET component = 'system/tenant/TenantUserList', url='/system/tenant/TenantUserList' WHERE component = 'system/user/TenantUserList';
|
||||
|
||||
|
||||
-- 系统通知类型新增租户邀请
|
||||
ALTER TABLE sys_announcement
|
||||
MODIFY COLUMN bus_type varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '业务类型(email:邮件 bpm:流程 tenant_invite:租户邀请)' AFTER del_flag;
|
||||
|
||||
|
||||
-- 修改部门表org_category字段的注释
|
||||
ALTER TABLE `sys_depart`
|
||||
MODIFY COLUMN `org_category` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '1' COMMENT '机构类别 1公司,2组织机构,3岗位' AFTER `description`;
|
||||
|
||||
|
||||
-- 日志显示实际名称 ---
|
||||
ALTER TABLE `sys_data_log`
|
||||
ADD COLUMN `create_name` varchar(100) NULL COMMENT '创建人真实名称' AFTER `create_by`;
|
||||
|
||||
UPDATE sys_data_log
|
||||
SET create_name = (SELECT sys_user.realname FROM sys_user WHERE sys_user.username = sys_data_log.create_by)
|
||||
WHERE create_name = '' OR create_name IS NULL;
|
||||
|
||||
|
||||
-- 新增表字典白名单配置表
|
||||
CREATE TABLE `sys_table_white_list` (
|
||||
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键id',
|
||||
`table_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '允许的表名',
|
||||
`field_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '允许的字段名,多个用逗号分割',
|
||||
`status` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '状态,1=启用,0=禁用',
|
||||
`create_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人',
|
||||
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人',
|
||||
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uniq_sys_table_white_list_table_name`(`table_name`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典表白名单' ROW_FORMAT = DYNAMIC;
|
||||
-- 默认数据
|
||||
INSERT INTO `sys_table_white_list` (`id`, `table_name`, `field_name`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1701578033271521282', 'sys_user', 'id,realname,username', '1', 'admin', '2023-09-12 10:46:32', NULL, NULL);
|
||||
INSERT INTO `sys_table_white_list` (`id`, `table_name`, `field_name`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1701581935488385025', 'oa_officialdoc_organcode', 'id,organ_name', '1', 'admin', '2023-09-12 11:02:02', NULL, NULL);
|
||||
INSERT INTO `sys_table_white_list` (`id`, `table_name`, `field_name`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1701581977733414913', 'demo', 'id,name', '1', 'admin', '2023-09-12 11:02:12', NULL, NULL);
|
||||
INSERT INTO `sys_table_white_list` (`id`, `table_name`, `field_name`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1701582035472203777', 'sys_permission', 'id,name', '1', 'admin', '2023-09-12 11:02:26', NULL, NULL);
|
||||
INSERT INTO `sys_table_white_list` (`id`, `table_name`, `field_name`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1701582087619985409', 'onl_drag_comp', 'id,comp_name', '1', 'admin', '2023-09-12 11:02:38', NULL, NULL);
|
||||
INSERT INTO `sys_table_white_list` (`id`, `table_name`, `field_name`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1701582136420712450', 'sys_depart', 'id,depart_name', '1', 'admin', '2023-09-12 11:02:50', NULL, NULL);
|
||||
INSERT INTO `sys_table_white_list` (`id`, `table_name`, `field_name`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1701582163599802370', 'design_form', 'id,desform_name,desform_code', '1', 'admin', '2023-09-12 11:02:56', NULL, NULL);
|
||||
INSERT INTO `sys_table_white_list` (`id`, `table_name`, `field_name`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1701582190187495426', 'onl_cgform_head', 'table_txt,table_name', '1', 'admin', '2023-09-12 11:03:03', NULL, NULL);
|
||||
INSERT INTO `sys_table_white_list` (`id`, `table_name`, `field_name`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1701582254301626370', 'oa_wps_file', 'id,name', '1', 'admin', '2023-09-12 11:03:18', NULL, NULL);
|
||||
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1701575168519839746', 'd7d6e2e4e2934f2c9385a623fd98c6f3', '字典表白名单', '/system/tableWhiteList', 'system/tableWhiteList/SysTableWhiteListList', 1, '', NULL, 1, NULL, '0', 13.00, 0, 'ant-design:table-outlined', 1, 0, 0, 0, NULL, 'admin', '2023-09-12 20:35:09', 'admin', '2023-09-12 20:45:08', 0, 0, NULL, 0);
|
||||
|
||||
|
||||
-- 系统通知卡顿问题性能优化 ---
|
||||
ALTER TABLE `sys_announcement_send`
|
||||
MODIFY COLUMN `read_flag` int(2) NULL DEFAULT NULL COMMENT '阅读状态(0未读,1已读)' AFTER `user_id`;
|
||||
|
||||
ALTER TABLE `sys_announcement`
|
||||
MODIFY COLUMN `msg_abstract` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '摘要/扩展业务参数' AFTER `user_ids`;
|
||||
|
||||
|
||||
-- 字典表 加颜色配置---
|
||||
ALTER TABLE sys_dict_item
|
||||
ADD COLUMN item_color varchar(10) NULL COMMENT '字典项颜色' AFTER item_value;
|
||||
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
@ -1,11 +0,0 @@
|
||||
版本升级方法?
|
||||
|
||||
JeecgBoot属于平台级产品,每次升级改动内容较多,目前做不到平滑升级。
|
||||
|
||||
升级方案建议:
|
||||
1.代码升级 => 本地版本通过svn或者git做好主干,在分支上做业务开发,jeecg每次版本发布,可以手工覆盖主干的代码,对比合并代码;
|
||||
2.数据库升级 => 针对数据库我们每次发布会提供增量升级SQL,可以通过执行增量SQL实现数据库的升级。
|
||||
3.兼容问题 => 每次版本发布会针对不兼容地方标注说明,需要手工修改不兼容的代码。
|
||||
|
||||
注意: 升级sql目前只提供mysql版本,执行完脚步后,新菜单需要手工进行角色授权,刷新首页才会出现。
|
||||
【20230820 放开了系统管理等模块权限注解,如果没权限请通过角色授权授权对应的按钮权限】
|
||||
15
db/版本升级说明.md
Normal file
15
db/版本升级说明.md
Normal file
@ -0,0 +1,15 @@
|
||||
# 版本升级方法
|
||||
|
||||
> JeecgBoot属于平台级产品,每次升级改动较大,目前做不到平滑升级。
|
||||
|
||||
### 增量升级方案
|
||||
#### 1.代码合并
|
||||
本地通过svn或git做好主干,在分支上做业务开发,jeecg每次版本发布,可以手工覆盖主干的代码,对比合并代码;
|
||||
|
||||
#### 2.数据库升级
|
||||
- 从3.6.2+版本增加flyway自动升级数据库机制,支持 mysql5.7、mysql8;
|
||||
- 其他库请手工执行SQL, 目录: `jeecg-module-system\jeecg-system-start\src\main\resources\flyway\sql\mysql`
|
||||
> 注意: 升级sql只提供mysql版本;如果有权限升级, 还需要手工角色授权,退出重新登录才好使。
|
||||
|
||||
#### 3.兼容问题
|
||||
每次发版,会针对不兼容地方重点说明。
|
||||
@ -19,6 +19,8 @@ services:
|
||||
--default-authentication-plugin=caching_sha2_password
|
||||
ports:
|
||||
- 3306:3306
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-redis:
|
||||
image: redis:5.0
|
||||
@ -27,6 +29,8 @@ services:
|
||||
restart: always
|
||||
hostname: jeecg-boot-redis
|
||||
container_name: jeecg-boot-redis
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-system:
|
||||
build:
|
||||
@ -40,3 +44,9 @@ services:
|
||||
hostname: jeecg-boot-system
|
||||
ports:
|
||||
- 8080:8080
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
networks:
|
||||
jeecg-boot:
|
||||
name: jeecg_boot
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jeecg-boot-base-core</artifactId>
|
||||
@ -256,6 +256,15 @@
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
</dependency>
|
||||
<!--加载hutool-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-crypto</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -117,14 +117,17 @@ public interface CommonAPI {
|
||||
*/
|
||||
Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys);
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 15 字典表的 翻译,可批量
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys 多个用逗号分割
|
||||
* @param dataSource 数据源
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys);
|
||||
List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys, String dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
}
|
||||
|
||||
@ -140,11 +140,15 @@ public class DictAspect {
|
||||
String code = field.getAnnotation(Dict.class).dicCode();
|
||||
String text = field.getAnnotation(Dict.class).dicText();
|
||||
String table = field.getAnnotation(Dict.class).dictTable();
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
String dataSource = field.getAnnotation(Dict.class).ds();
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
List<String> dataList;
|
||||
String dictCode = code;
|
||||
if (!StringUtils.isEmpty(table)) {
|
||||
dictCode = String.format("%s,%s,%s", table, text, code);
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
dictCode = String.format("%s,%s,%s,%s", table, text, code, dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
}
|
||||
dataList = dataListMap.computeIfAbsent(dictCode, k -> new ArrayList<>());
|
||||
this.listAddAllDeduplicate(dataList, Arrays.asList(value.split(",")));
|
||||
@ -169,10 +173,15 @@ public class DictAspect {
|
||||
String code = field.getAnnotation(Dict.class).dicCode();
|
||||
String text = field.getAnnotation(Dict.class).dicText();
|
||||
String table = field.getAnnotation(Dict.class).dictTable();
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
// 自定义的字典表数据源
|
||||
String dataSource = field.getAnnotation(Dict.class).ds();
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
String fieldDictCode = code;
|
||||
if (!StringUtils.isEmpty(table)) {
|
||||
fieldDictCode = String.format("%s,%s,%s", table, text, code);
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
fieldDictCode = String.format("%s,%s,%s,%s", table, text, code, dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
}
|
||||
|
||||
String value = record.getString(field.getName());
|
||||
@ -274,9 +283,25 @@ public class DictAspect {
|
||||
String[] arr = dictCode.split(",");
|
||||
String table = arr[0], text = arr[1], code = arr[2];
|
||||
String values = String.join(",", needTranslDataTable);
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
// 自定义的数据源
|
||||
String dataSource = null;
|
||||
if (arr.length > 3) {
|
||||
dataSource = arr[3];
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
log.debug("translateDictFromTableByKeys.dictCode:" + dictCode);
|
||||
log.debug("translateDictFromTableByKeys.values:" + values);
|
||||
List<DictModel> texts = commonApi.translateDictFromTableByKeys(table, text, code, values);
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
//update-begin---author:wangshuai---date:2024-01-09---for:微服务下为空报错没有参数需要传递空字符串---
|
||||
if(null == dataSource){
|
||||
dataSource = "";
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-01-09---for:微服务下为空报错没有参数需要传递空字符串---
|
||||
|
||||
List<DictModel> texts = commonApi.translateDictFromTableByKeys(table, text, code, values, dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
log.debug("translateDictFromTableByKeys.result:" + texts);
|
||||
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
|
||||
list.addAll(texts);
|
||||
|
||||
@ -39,4 +39,16 @@ public @interface Dict {
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String dictTable() default "";
|
||||
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 方法描述: 数据字典表所在数据源名称
|
||||
* 作 者: chenrui
|
||||
* 日 期: 2023年12月20日-下午4:58
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String ds() default "";
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
}
|
||||
|
||||
@ -69,6 +69,8 @@ public interface CommonConstant {
|
||||
|
||||
/** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */
|
||||
Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
|
||||
/** {@code 404 Not Found} (HTTP/1.0 - RFC 1945) */
|
||||
Integer SC_INTERNAL_NOT_FOUND_404 = 404;
|
||||
/** {@code 200 OK} (HTTP/1.0 - RFC 1945) */
|
||||
Integer SC_OK_200 = 200;
|
||||
|
||||
|
||||
@ -18,6 +18,9 @@ public interface DataBaseConstant {
|
||||
/**postgreSQL达梦数据库*/
|
||||
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
||||
|
||||
/**人大金仓数据库*/
|
||||
public static final String DB_TYPE_KINGBASEES = "KINGBASEES";
|
||||
|
||||
/**sqlserver数据库*/
|
||||
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package org.jeecg.common.exception;
|
||||
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
|
||||
/**
|
||||
* @Description: jeecg-boot自定义异常
|
||||
* @author: jeecg-boot
|
||||
@ -7,10 +9,24 @@ package org.jeecg.common.exception;
|
||||
public class JeecgBootException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 返回给前端的错误code
|
||||
*/
|
||||
private int errCode = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
|
||||
|
||||
public JeecgBootException(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JeecgBootException(String message, int errCode){
|
||||
super(message);
|
||||
this.errCode = errCode;
|
||||
}
|
||||
|
||||
public int getErrCode() {
|
||||
return errCode;
|
||||
}
|
||||
|
||||
public JeecgBootException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
|
||||
@ -33,7 +33,7 @@ public class JeecgBootExceptionHandler {
|
||||
@ExceptionHandler(JeecgBootException.class)
|
||||
public Result<?> handleJeecgBootException(JeecgBootException e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
return Result.error(e.getErrCode(), e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -19,6 +19,8 @@ public class SysFilesModel {
|
||||
private String storeType;
|
||||
/**文件大小(kb)*/
|
||||
private Double fileSize;
|
||||
/**租户id*/
|
||||
private String tenantId;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
@ -67,4 +69,12 @@ public class SysFilesModel {
|
||||
public void setFileSize(Double fileSize) {
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(String tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
}
|
||||
@ -302,7 +302,7 @@ public class CommonUtils {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_SQLSERVER)>=0||dbType.indexOf(sqlserver)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_POSTGRESQL)>=0) {
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_POSTGRESQL)>=0 || dbType.indexOf(DataBaseConstant.DB_TYPE_KINGBASEES)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_MARIADB)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
|
||||
|
||||
@ -29,6 +29,17 @@ public class SqlInjectionUtil {
|
||||
* 字典专用—sql注入关键词
|
||||
*/
|
||||
private static String specialDictSqlXssStr = "exec |peformance_schema|information_schema|extractvalue|updatexml|geohash|gtid_subset|gtid_subtract|insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|+|--";
|
||||
/**
|
||||
* 完整匹配的key,不需要考虑前空格
|
||||
*/
|
||||
private static List<String> FULL_MATCHING_KEYWRODS = new ArrayList<>();
|
||||
static {
|
||||
FULL_MATCHING_KEYWRODS.add(";");
|
||||
FULL_MATCHING_KEYWRODS.add("+");
|
||||
FULL_MATCHING_KEYWRODS.add("--");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sql注入风险的 正则关键字
|
||||
*
|
||||
@ -50,6 +61,8 @@ public class SqlInjectionUtil {
|
||||
* sql注释的正则
|
||||
*/
|
||||
private final static Pattern SQL_ANNOTATION = Pattern.compile("/\\*[\\s\\S]*\\*/");
|
||||
private final static String SQL_ANNOTATION2 = "--";
|
||||
|
||||
/**
|
||||
* sql注入提示语
|
||||
*/
|
||||
@ -128,7 +141,13 @@ public class SqlInjectionUtil {
|
||||
if (sql.startsWith(keyword.trim())) {
|
||||
return true;
|
||||
} else if (sql.contains(keyword)) {
|
||||
if (sql.contains(" " + keyword)) {
|
||||
// 需要匹配的,sql注入关键词
|
||||
String matchingText = " " + keyword;
|
||||
if(FULL_MATCHING_KEYWRODS.contains(keyword)){
|
||||
matchingText = keyword;
|
||||
}
|
||||
|
||||
if (sql.contains(matchingText)) {
|
||||
return true;
|
||||
} else {
|
||||
String regularStr = "\\s+\\S+" + keyword;
|
||||
@ -244,6 +263,13 @@ public class SqlInjectionUtil {
|
||||
* @return
|
||||
*/
|
||||
public static void checkSqlAnnotation(String str){
|
||||
if(str.contains(SQL_ANNOTATION2)){
|
||||
String error = "请注意,SQL中不允许含注释,有安全风险!";
|
||||
log.error(error);
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
|
||||
|
||||
Matcher matcher = SQL_ANNOTATION.matcher(str);
|
||||
if(matcher.find()){
|
||||
String error = "请注意,值可能存在SQL注入风险---> \\*.*\\";
|
||||
@ -260,7 +286,7 @@ public class SqlInjectionUtil {
|
||||
*
|
||||
* @param table
|
||||
*/
|
||||
private static Pattern tableNamePattern = Pattern.compile("^[a-zA-Z][a-zA-Z0-9_]{0,63}$");
|
||||
private static Pattern tableNamePattern = Pattern.compile("^[a-zA-Z][a-zA-Z0-9_\\$]{0,63}$");
|
||||
public static String getSqlInjectTableName(String table) {
|
||||
if(oConvertUtils.isEmpty(table)){
|
||||
return table;
|
||||
|
||||
@ -61,6 +61,10 @@ public class SsrfFileTypeFilter {
|
||||
FILE_TYPE_WHITE_LIST.add("7z");
|
||||
FILE_TYPE_WHITE_LIST.add("tar");
|
||||
|
||||
//app文件后缀
|
||||
FILE_TYPE_WHITE_LIST.add("apk");
|
||||
FILE_TYPE_WHITE_LIST.add("wgt");
|
||||
|
||||
//设置禁止文件的头部标记
|
||||
FILE_TYPE_MAP.put("3c25402070616765206c", "jsp");
|
||||
FILE_TYPE_MAP.put("3c3f7068700a0a2f2a2a0a202a205048", "php");
|
||||
|
||||
@ -31,7 +31,7 @@ public class WebSocketConfig {
|
||||
FilterRegistrationBean bean = new FilterRegistrationBean();
|
||||
bean.setFilter(websocketFilter());
|
||||
//TODO 临时注释掉,测试下线上socket总断的问题
|
||||
bean.addUrlPatterns("/websocket/*","/eoaSocket/*","/eoaNewChatSocket/*", "/newsWebsocket/*", "/vxeSocket/*");
|
||||
bean.addUrlPatterns("/taskCountSocket/*", "/websocket/*","/eoaSocket/*","/eoaNewChatSocket/*", "/newsWebsocket/*", "/vxeSocket/*");
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
||||
@ -9,10 +9,7 @@ import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.crazycake.shiro.IRedisManager;
|
||||
import org.crazycake.shiro.RedisCacheManager;
|
||||
import org.crazycake.shiro.RedisClusterManager;
|
||||
import org.crazycake.shiro.RedisManager;
|
||||
import org.crazycake.shiro.*;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
@ -25,6 +22,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisCluster;
|
||||
@ -49,6 +48,8 @@ public class ShiroConfig {
|
||||
private Environment env;
|
||||
@Resource
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
@Autowired(required = false)
|
||||
private RedisProperties redisProperties;
|
||||
|
||||
/**
|
||||
* Filter Chain定义说明
|
||||
@ -74,6 +75,7 @@ public class ShiroConfig {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 配置不会被拦截的链接 顺序判断
|
||||
filterChainDefinitionMap.put("/sys/cas/client/validateLogin", "anon"); //cas验证登录
|
||||
filterChainDefinitionMap.put("/sys/randomImage/**", "anon"); //登录验证码接口排除
|
||||
@ -92,6 +94,9 @@ public class ShiroConfig {
|
||||
filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
|
||||
filterChainDefinitionMap.put("/sys/common/static/**", "anon");//图片预览 &下载文件不限制token
|
||||
filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
|
||||
|
||||
//filterChainDefinitionMap.put("/sys/common/view/**", "anon");//图片预览不限制token
|
||||
//filterChainDefinitionMap.put("/sys/common/download/**", "anon");//文件下载不限制token
|
||||
filterChainDefinitionMap.put("/generic/**", "anon");//pdf预览需要文件
|
||||
|
||||
filterChainDefinitionMap.put("/sys/getLoginQrcode/**", "anon"); //登录二维码
|
||||
@ -99,6 +104,7 @@ public class ShiroConfig {
|
||||
filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除
|
||||
|
||||
|
||||
//update-begin--Author:scott Date:20221116 for:排除静态资源后缀
|
||||
filterChainDefinitionMap.put("/", "anon");
|
||||
filterChainDefinitionMap.put("/doc.html", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.js", "anon");
|
||||
@ -113,6 +119,7 @@ public class ShiroConfig {
|
||||
filterChainDefinitionMap.put("/**/*.ttf", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.woff", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.woff2", "anon");
|
||||
//update-end--Author:scott Date:20221116 for:排除静态资源后缀
|
||||
|
||||
filterChainDefinitionMap.put("/druid/**", "anon");
|
||||
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
|
||||
@ -120,7 +127,9 @@ public class ShiroConfig {
|
||||
filterChainDefinitionMap.put("/webjars/**", "anon");
|
||||
filterChainDefinitionMap.put("/v2/**", "anon");
|
||||
|
||||
// update-begin--Author:sunjianlei Date:20210510 for:排除消息通告查看详情页面(用于第三方APP)
|
||||
filterChainDefinitionMap.put("/sys/annountCement/show/**", "anon");
|
||||
// update-end--Author:sunjianlei Date:20210510 for:排除消息通告查看详情页面(用于第三方APP)
|
||||
|
||||
//积木报表排除
|
||||
filterChainDefinitionMap.put("/jmreport/**", "anon");
|
||||
@ -151,10 +160,10 @@ public class ShiroConfig {
|
||||
//测试模块排除
|
||||
filterChainDefinitionMap.put("/test/seata/**", "anon");
|
||||
|
||||
// update-begin--author:liusq Date:20230522 for:[issues/4829]访问不存在的url时会提示Token失效,请重新登录呢
|
||||
//错误路径排除
|
||||
filterChainDefinitionMap.put("/error", "anon");
|
||||
// update-end--author:liusq Date:20230522 for:[issues/4829]访问不存在的url时会提示Token失效,请重新登录呢
|
||||
// 企业微信证书排除
|
||||
filterChainDefinitionMap.put("/WW_verify*", "anon");
|
||||
|
||||
// 添加自己的过滤器并且取名为jwt
|
||||
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
|
||||
@ -249,6 +258,19 @@ public class ShiroConfig {
|
||||
public IRedisManager redisManager() {
|
||||
log.info("===============(2)创建RedisManager,连接Redis..");
|
||||
IRedisManager manager;
|
||||
// sentinel cluster redis(【issues/5569】shiro集成 redis 不支持 sentinel 方式部署的redis集群 #5569)
|
||||
if (Objects.nonNull(redisProperties)
|
||||
&& Objects.nonNull(redisProperties.getSentinel())
|
||||
&& !CollectionUtils.isEmpty(redisProperties.getSentinel().getNodes())) {
|
||||
RedisSentinelManager sentinelManager = new RedisSentinelManager();
|
||||
sentinelManager.setMasterName(redisProperties.getSentinel().getMaster());
|
||||
sentinelManager.setHost(String.join(",", redisProperties.getSentinel().getNodes()));
|
||||
sentinelManager.setPassword(redisProperties.getSentinel().getPassword());
|
||||
sentinelManager.setDatabase(redisProperties.getDatabase());
|
||||
|
||||
return sentinelManager;
|
||||
}
|
||||
|
||||
// redis 单机支持,在集群为空,或者集群无机器时候使用 add by jzyadmin@163.com
|
||||
if (lettuceConnectionFactory.getClusterConfiguration() == null || lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().isEmpty()) {
|
||||
RedisManager redisManager = new RedisManager();
|
||||
|
||||
@ -35,4 +35,5 @@ public class Firewall {
|
||||
public void setLowCodeMode(String lowCodeMode) {
|
||||
this.lowCodeMode = lowCodeMode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
</div>
|
||||
<div style="width: 600px; margin: 0 auto; margin-top: 50px; font-size: 12px; -webkit-font-smoothing: subpixel-antialiased; text-size-adjust: 100%;">
|
||||
<p style="text-align: center; line-height: 20.4px; text-size-adjust: 100%; font-family: 'Microsoft YaHei'!important; padding: 0px !important; margin: 0px !important; color: #7e8890 !important;">
|
||||
<span class="appleLinks">Copyright © 2023-2024 北京国炬科技股份有限公司. 保留所有权利。</span>
|
||||
<span class="appleLinks">Copyright © 2023-2024 北京国炬信息技术有限公司. 保留所有权利。</span>
|
||||
</p>
|
||||
<p style="text-align: center;line-height: 20.4px; text-size-adjust: 100%; font-family: 'Microsoft YaHei'!important; padding: 0px !important; margin: 0px; color: #7e8890 !important; margin-top: 10px;">
|
||||
<span class="appleLinks">邮件由系统自动发送,请勿直接回复本邮件!</span>
|
||||
|
||||
@ -6,7 +6,10 @@
|
||||
<body>
|
||||
<div class="box-content">
|
||||
<div class="info-top">
|
||||
<img src="https://jeecgdev.oss-cn-beijing.aliyuncs.com/temp/logo(1)_1697180761742.png" style="float: left; margin: 0 10px 0 0; width: 32px;height:32px" /><div style="color:#fff"><strong>【重要】新数据提醒</strong></div>
|
||||
<img src="https://qiaoqiaoyun.oss-cn-beijing.aliyuncs.com/site/qqyunemaillogo.png" style="width: 35px;height:35px; background: #5e8ee5; border-radius: 5px;" />
|
||||
<div style="color:#fff;">
|
||||
<strong>【重要】新数据提醒</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<div class="tips" style="padding:15px;">
|
||||
@ -23,12 +26,12 @@
|
||||
<a style="color: #006eff;" href="${moreLink}" target="_blank" rel="noopener">[查看所有数据]</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="footer">北京国炬平台</div>
|
||||
<div class="footer">敲敲云平台</div>
|
||||
<div class="footer" id="currentTime"></div>
|
||||
</div>
|
||||
<div style="width: 600px; margin: 0 auto; margin-top: 50px; font-size: 12px; -webkit-font-smoothing: subpixel-antialiased; text-size-adjust: 100%;">
|
||||
<p style="text-align: center; line-height: 20.4px; text-size-adjust: 100%; font-family: 'Microsoft YaHei'!important; padding: 0px !important; margin: 0px !important; color: #7e8890 !important;">
|
||||
<span class="appleLinks">Copyright © 2023-2024 北京国炬科技股份有限公司. 保留所有权利。</span>
|
||||
<span class="appleLinks">Copyright © 2023-2024 北京敲敲云科技有限公司. 保留所有权利。</span>
|
||||
</p>
|
||||
<p style="text-align: center;line-height: 20.4px; text-size-adjust: 100%; font-family: 'Microsoft YaHei'!important; padding: 0px !important; margin: 0px; color: #7e8890 !important; margin-top: 10px;">
|
||||
<span class="appleLinks">邮件由系统自动发送,请勿直接回复本邮件!</span>
|
||||
@ -46,6 +49,8 @@
|
||||
}
|
||||
|
||||
.info-top{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 15px 25px;
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ public class JcloudDemoProviderController {
|
||||
private JcloudDemoService jcloudDemoService;
|
||||
|
||||
@GetMapping("/getMessage")
|
||||
public String getMessage(@RequestParam String name) {
|
||||
public String getMessage(@RequestParam(name = "name") String name) {
|
||||
String msg = jcloudDemoService.getMessage(name);
|
||||
log.info(" 微服务被调用:{} ",msg);
|
||||
return msg;
|
||||
|
||||
@ -45,11 +45,11 @@ public class JeecgDemo extends JeecgEntity implements Serializable {
|
||||
private java.util.Date punchTime;
|
||||
/** 工资 */
|
||||
@ApiModelProperty(value = "工资",example = "0")
|
||||
@Excel(name="工资",width=15)
|
||||
@Excel(name="工资",type = 4,width=15)
|
||||
private java.math.BigDecimal salaryMoney;
|
||||
/** 奖金 */
|
||||
@ApiModelProperty(value = "奖金",example = "0")
|
||||
@Excel(name="奖金",width=15)
|
||||
@Excel(name="奖金",type = 4,width=15)
|
||||
private java.lang.Double bonusMoney;
|
||||
/** 性别 {男:1,女:2} */
|
||||
@ApiModelProperty(value = "性别")
|
||||
@ -57,7 +57,7 @@ public class JeecgDemo extends JeecgEntity implements Serializable {
|
||||
private java.lang.String sex;
|
||||
/** 年龄 */
|
||||
@ApiModelProperty(value = "年龄",example = "0")
|
||||
@Excel(name="年龄",width=15)
|
||||
@Excel(name="年龄",type = 4,width=15)
|
||||
private java.lang.Integer age;
|
||||
/** 生日 */
|
||||
@ApiModelProperty(value = "生日")
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jeecg-system-api</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -94,6 +94,22 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
@GetMapping("/sys/api/getDepartIdsByUsername")
|
||||
List<String> getDepartIdsByUsername(@RequestParam("username") String username);
|
||||
|
||||
/**
|
||||
* 8.2 通过用户账号查询部门父ID集合
|
||||
* @param username
|
||||
* @return 部门 parentIds
|
||||
*/
|
||||
@GetMapping("/sys/api/getDepartParentIdsByUsername")
|
||||
Set<String> getDepartParentIdsByUsername(@RequestParam("username")String username);
|
||||
|
||||
/**
|
||||
* 8.3 查询部门父ID集合
|
||||
* @param depIds
|
||||
* @return 部门 parentIds
|
||||
*/
|
||||
@GetMapping("/sys/api/getDepartParentIdsByDepIds")
|
||||
Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set<String> depIds);
|
||||
|
||||
/**
|
||||
* 9通过用户账号查询部门 name
|
||||
* @param username
|
||||
@ -197,7 +213,7 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryAllUser")
|
||||
public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) int pageSize);
|
||||
public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) Integer pageSize);
|
||||
|
||||
|
||||
/**
|
||||
@ -481,6 +497,14 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
@GetMapping("/sys/api/loadCategoryDictItem")
|
||||
List<String> loadCategoryDictItem(@RequestParam("ids") String ids);
|
||||
|
||||
/**
|
||||
* 44 反向翻译分类字典,用于导入
|
||||
*
|
||||
* @param names 名称,逗号分割
|
||||
*/
|
||||
@GetMapping("/sys/api/loadCategoryDictItemByNames")
|
||||
List<String> loadCategoryDictItemByNames(@RequestParam("names") String names, @RequestParam("delNotExist") boolean delNotExist);
|
||||
|
||||
/**
|
||||
* 43 根据字典code加载字典text
|
||||
*
|
||||
@ -551,17 +575,20 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
@GetMapping("/sys/api/translateManyDict")
|
||||
Map<String, List<DictModel>> translateManyDict(@RequestParam("dictCodes") String dictCodes, @RequestParam("keys") String keys);
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 49 字典表的 翻译,可批量
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys 多个用逗号分割
|
||||
* @param ds
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/translateDictFromTableByKeys")
|
||||
List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys);
|
||||
List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys, @RequestParam("ds") String ds);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
/**
|
||||
* 发送模板消息
|
||||
@ -734,7 +761,7 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
@GetMapping("/sys/api/dictTableWhiteListCheckByDict")
|
||||
boolean dictTableWhiteListCheckByDict(
|
||||
@RequestParam("tableOrDictCode") String tableOrDictCode,
|
||||
@RequestParam(value = "fields", required = false) String[] fields
|
||||
@RequestParam(value = "fields", required = false) String... fields
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@ -65,6 +65,16 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDepartParentIdsByUsername(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDepartParentIdsByDepIds(Set depIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDepartNamesByUsername(String username) {
|
||||
return null;
|
||||
@ -123,7 +133,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject queryAllUser(String userIds, Integer pageNo, int pageSize) {
|
||||
public JSONObject queryAllUser(String userIds, Integer pageNo, Integer pageSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -275,10 +285,12 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
||||
return null;
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
@Override
|
||||
public List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys) {
|
||||
public List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys, String dataSource) {
|
||||
return null;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
@Override
|
||||
public void sendTemplateMessage(MessageDTO message) {
|
||||
@ -319,6 +331,11 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> loadCategoryDictItemByNames(String names, boolean delNotExist) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> loadDictItem(String dictCode, String keys) {
|
||||
return null;
|
||||
@ -429,7 +446,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dictTableWhiteListCheckByDict(String tableOrDictCode, String[] fields) {
|
||||
public boolean dictTableWhiteListCheckByDict(String tableOrDictCode, String... fields) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jeecg-system-api</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -89,6 +89,20 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
*/
|
||||
List<String> getDepartIdsByUsername(String username);
|
||||
|
||||
/**
|
||||
* 8.2 通过用户账号查询部门父ID集合
|
||||
* @param username
|
||||
* @return 部门 parentIds
|
||||
*/
|
||||
Set<String> getDepartParentIdsByUsername(String username);
|
||||
|
||||
/**
|
||||
* 8.2 查询部门父ID集合
|
||||
* @param depIds
|
||||
* @return 部门 parentIds
|
||||
*/
|
||||
Set<String> getDepartParentIdsByDepIds(Set depIds);
|
||||
|
||||
/**
|
||||
* 9通过用户账号查询部门 name
|
||||
* @param username
|
||||
@ -373,6 +387,13 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
*/
|
||||
List<String> loadCategoryDictItem(String ids);
|
||||
|
||||
/**
|
||||
* 反向翻译分类字典,用于导入
|
||||
*
|
||||
* @param names 名称,逗号分割
|
||||
*/
|
||||
List<String> loadCategoryDictItemByNames(String names, boolean delNotExist);
|
||||
|
||||
/**
|
||||
* 根据字典code加载字典text
|
||||
*
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jeecg-module-system</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-module-system</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -35,9 +35,9 @@
|
||||
<artifactId>jimureport-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>drag-free</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<groupId>org.jeecgframework.jimureport</groupId>
|
||||
<artifactId>jimureport-drag</artifactId>
|
||||
<version>2.0.1</version>
|
||||
</dependency>
|
||||
<!-- 积木报表 mongo redis 支持包
|
||||
<dependency>
|
||||
|
||||
@ -100,8 +100,8 @@ public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler
|
||||
// 针对转义字符进行解码
|
||||
dictCodeString = URLDecoder.decode(dictCodeString, "UTF-8");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
this.throwException("字典code解码失败,可能是使用了非法字符,请检查!");
|
||||
log.warn(e.getMessage());
|
||||
//this.throwException("字典code解码失败,可能是使用了非法字符,请检查!");
|
||||
}
|
||||
dictCodeString = dictCodeString.trim();
|
||||
String[] arr = dictCodeString.split(SymbolConstant.COMMA);
|
||||
|
||||
@ -140,6 +140,26 @@ public class SystemApiController {
|
||||
return sysBaseApi.getDepartIdsByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门父ID集合
|
||||
* @param username
|
||||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/getDepartParentIdsByUsername")
|
||||
Set<String> getDepartParentIdsByUsername(@RequestParam("username") String username){
|
||||
return sysBaseApi.getDepartParentIdsByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询部门父ID集合
|
||||
* @param depIds
|
||||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/getDepartParentIdsByDepIds")
|
||||
Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set depIds){
|
||||
return sysBaseApi.getDepartParentIdsByDepIds(depIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门 name
|
||||
* @param username
|
||||
@ -327,7 +347,7 @@ public class SystemApiController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllUser")
|
||||
public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) int pageSize){
|
||||
public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) Integer pageSize){
|
||||
return sysBaseApi.queryAllUser(userIds, pageNo, pageSize);
|
||||
}
|
||||
|
||||
@ -527,6 +547,17 @@ public class SystemApiController {
|
||||
return sysBaseApi.loadCategoryDictItem(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 反向翻译分类字典,用于导入
|
||||
*
|
||||
* @param names 名称,逗号分割
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/loadCategoryDictItemByNames")
|
||||
List<String> loadCategoryDictItemByNames(@RequestParam("names") String names, @RequestParam("delNotExist") boolean delNotExist) {
|
||||
return sysBaseApi.loadCategoryDictItemByNames(names, delNotExist);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典code加载字典text
|
||||
*
|
||||
@ -547,7 +578,7 @@ public class SystemApiController {
|
||||
* @param tenantId 新的租户ID
|
||||
* @return Map<String, String> Map<原字典编码, 新字典编码>
|
||||
*/
|
||||
@GetMapping("/sys/api/copyLowAppDict")
|
||||
@GetMapping("/copyLowAppDict")
|
||||
Map<String, String> copyLowAppDict(@RequestParam("originalAppId") String originalAppId, @RequestParam("appId") String appId, @RequestParam("tenantId") String tenantId) {
|
||||
return sysBaseApi.copyLowAppDict(originalAppId, appId, tenantId);
|
||||
}
|
||||
@ -655,6 +686,7 @@ public class SystemApiController {
|
||||
}
|
||||
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 【接口签名验证】
|
||||
* 49 字典表的 翻译,可批量
|
||||
@ -663,12 +695,14 @@ public class SystemApiController {
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys 多个用逗号分割
|
||||
* @param ds 数据源
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/translateDictFromTableByKeys")
|
||||
public List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys) {
|
||||
return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys);
|
||||
public List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys, @RequestParam("ds") String ds) {
|
||||
return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys, ds);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
/**
|
||||
* 发送模板信息
|
||||
@ -698,14 +732,6 @@ public class SystemApiController {
|
||||
this.sysBaseApi.saveDataLog(dataLogDto);
|
||||
}
|
||||
|
||||
@PostMapping("/addSysFiles")
|
||||
public void addSysFiles(@RequestBody SysFilesModel sysFilesModel){this.sysBaseApi.addSysFiles(sysFilesModel);}
|
||||
|
||||
@GetMapping("/getFileUrl")
|
||||
public String getFileUrl(@RequestParam(name="fileId") String fileId){
|
||||
return this.sysBaseApi.getFileUrl(fileId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新头像
|
||||
* @param loginUser
|
||||
@ -824,7 +850,7 @@ public class SystemApiController {
|
||||
* @param deptIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserIdsByDeptIds")
|
||||
@GetMapping("/queryUserIdsByDeptIds")
|
||||
public List<String> queryUserIdsByDeptIds(@RequestParam("deptIds") List<String> deptIds){
|
||||
return sysBaseApi.queryUserIdsByDeptIds(deptIds);
|
||||
}
|
||||
@ -834,7 +860,7 @@ public class SystemApiController {
|
||||
* @param deptIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserAccountsByDeptIds")
|
||||
@GetMapping("/queryUserAccountsByDeptIds")
|
||||
public List<String> queryUserAccountsByDeptIds(@RequestParam("deptIds") List<String> deptIds){
|
||||
return sysBaseApi.queryUserAccountsByDeptIds(deptIds);
|
||||
}
|
||||
@ -844,7 +870,7 @@ public class SystemApiController {
|
||||
* @param roleCodes
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserIdsByRoleds")
|
||||
@GetMapping("/queryUserIdsByRoleds")
|
||||
public List<String> queryUserIdsByRoleds(@RequestParam("roleCodes") List<String> roleCodes){
|
||||
return sysBaseApi.queryUserIdsByRoleds(roleCodes);
|
||||
}
|
||||
@ -854,7 +880,7 @@ public class SystemApiController {
|
||||
* @param positionIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserIdsByPositionIds")
|
||||
@GetMapping("/queryUserIdsByPositionIds")
|
||||
public List<String> queryUserIdsByPositionIds(@RequestParam("positionIds") List<String> positionIds){
|
||||
return sysBaseApi.queryUserIdsByPositionIds(positionIds);
|
||||
}
|
||||
@ -866,7 +892,7 @@ public class SystemApiController {
|
||||
* @param orgCode 部门编码
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getUserAccountsByDepCode")
|
||||
@GetMapping("/getUserAccountsByDepCode")
|
||||
public List<String> getUserAccountsByDepCode(String orgCode){
|
||||
return sysBaseApi.getUserAccountsByDepCode(orgCode);
|
||||
}
|
||||
@ -877,7 +903,7 @@ public class SystemApiController {
|
||||
* @param selectSql
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/dictTableWhiteListCheckBySql")
|
||||
@GetMapping("/dictTableWhiteListCheckBySql")
|
||||
public boolean dictTableWhiteListCheckBySql(@RequestParam("selectSql") String selectSql) {
|
||||
return sysBaseApi.dictTableWhiteListCheckBySql(selectSql);
|
||||
}
|
||||
@ -889,10 +915,10 @@ public class SystemApiController {
|
||||
* @param fields 如果传的是dictCode,则该参数必须传null
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/dictTableWhiteListCheckByDict")
|
||||
@GetMapping("/dictTableWhiteListCheckByDict")
|
||||
public boolean dictTableWhiteListCheckByDict(
|
||||
@RequestParam("tableOrDictCode") String tableOrDictCode,
|
||||
@RequestParam(value = "fields", required = false) String[] fields
|
||||
@RequestParam(value = "fields", required = false) String... fields
|
||||
) {
|
||||
return sysBaseApi.dictTableWhiteListCheckByDict(tableOrDictCode, fields);
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ public class QuartzJobController {
|
||||
* @param quartzJob
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:add")
|
||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||
public Result<?> add(@RequestBody QuartzJob quartzJob) {
|
||||
@ -93,7 +93,7 @@ public class QuartzJobController {
|
||||
* @param quartzJob
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:edit")
|
||||
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
|
||||
public Result<?> eidt(@RequestBody QuartzJob quartzJob) {
|
||||
@ -112,7 +112,7 @@ public class QuartzJobController {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:delete")
|
||||
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
@ -131,7 +131,7 @@ public class QuartzJobController {
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:deleteBatch")
|
||||
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
@ -151,7 +151,7 @@ public class QuartzJobController {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:pause")
|
||||
@GetMapping(value = "/pause")
|
||||
@ApiOperation(value = "停止定时任务")
|
||||
@ -170,7 +170,7 @@ public class QuartzJobController {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:resume")
|
||||
@GetMapping(value = "/resume")
|
||||
@ApiOperation(value = "启动定时任务")
|
||||
@ -271,7 +271,7 @@ public class QuartzJobController {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:execute")
|
||||
@GetMapping("/execute")
|
||||
public Result<?> execute(@RequestParam(name = "id", required = true) String id) {
|
||||
|
||||
@ -72,7 +72,7 @@ public class LoginController {
|
||||
|
||||
@ApiOperation("登录接口")
|
||||
@RequestMapping(value = "/login", method = RequestMethod.POST)
|
||||
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){
|
||||
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel, HttpServletRequest request){
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String username = sysLoginModel.getUsername();
|
||||
String password = sysLoginModel.getPassword();
|
||||
@ -132,7 +132,7 @@ public class LoginController {
|
||||
}
|
||||
|
||||
//用户登录信息
|
||||
userInfo(sysUser, result);
|
||||
userInfo(sysUser, result, request);
|
||||
//update-begin--Author:liusq Date:20210126 for:登录成功,删除redis中的验证码
|
||||
redisUtil.del(realKey);
|
||||
//update-begin--Author:liusq Date:20210126 for:登录成功,删除redis中的验证码
|
||||
@ -158,10 +158,10 @@ public class LoginController {
|
||||
JSONObject obj=new JSONObject();
|
||||
|
||||
//update-begin---author:scott ---date:2022-06-20 for:vue3前端,支持自定义首页-----------
|
||||
String version = request.getHeader(CommonConstant.VERSION);
|
||||
String vue3Version = request.getHeader(CommonConstant.VERSION);
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
|
||||
SysRoleIndex roleIndex = sysUserService.getDynamicIndexByUserRole(username, version);
|
||||
if (oConvertUtils.isNotEmpty(version) && roleIndex != null && oConvertUtils.isNotEmpty(roleIndex.getUrl())) {
|
||||
SysRoleIndex roleIndex = sysUserService.getDynamicIndexByUserRole(username, vue3Version);
|
||||
if (oConvertUtils.isNotEmpty(vue3Version) && roleIndex != null && oConvertUtils.isNotEmpty(roleIndex.getUrl())) {
|
||||
String homePath = roleIndex.getUrl();
|
||||
if (!homePath.startsWith(SymbolConstant.SINGLE_SLASH)) {
|
||||
homePath = SymbolConstant.SINGLE_SLASH + homePath;
|
||||
@ -173,6 +173,7 @@ public class LoginController {
|
||||
|
||||
obj.put("userInfo",sysUser);
|
||||
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
|
||||
|
||||
result.setResult(obj);
|
||||
result.success("");
|
||||
}
|
||||
@ -397,7 +398,7 @@ public class LoginController {
|
||||
*/
|
||||
@ApiOperation("手机号登录接口")
|
||||
@PostMapping("/phoneLogin")
|
||||
public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject) {
|
||||
public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String phone = jsonObject.getString("mobile");
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
@ -427,7 +428,7 @@ public class LoginController {
|
||||
return result;
|
||||
}
|
||||
//用户信息
|
||||
userInfo(sysUser, result);
|
||||
userInfo(sysUser, result, request);
|
||||
//添加日志
|
||||
baseCommonService.addLog("用户名: " + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null);
|
||||
|
||||
@ -442,7 +443,7 @@ public class LoginController {
|
||||
* @param result
|
||||
* @return
|
||||
*/
|
||||
private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result) {
|
||||
private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result, HttpServletRequest request) {
|
||||
String username = sysUser.getUsername();
|
||||
String syspassword = sysUser.getPassword();
|
||||
// 获取用户部门信息
|
||||
@ -482,7 +483,15 @@ public class LoginController {
|
||||
// update-end--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
|
||||
obj.put("multi_depart", 2);
|
||||
}
|
||||
|
||||
//update-begin---author:scott ---date:2024-01-05 for:【QQYUN-7802】前端在登录时加载了两次数据字典,建议优化下,避免数据字典太多时可能产生的性能问题 #956---
|
||||
// login接口,在vue3前端下不加载字典数据,vue2下加载字典
|
||||
String vue3Version = request.getHeader(CommonConstant.VERSION);
|
||||
if(oConvertUtils.isEmpty(vue3Version)){
|
||||
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
|
||||
}
|
||||
//end-begin---author:scott ---date:2024-01-05 for:【QQYUN-7802】前端在登录时加载了两次数据字典,建议优化下,避免数据字典太多时可能产生的性能问题 #956---
|
||||
|
||||
result.setResult(obj);
|
||||
result.success("登录成功");
|
||||
return result;
|
||||
|
||||
@ -25,6 +25,7 @@ import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.service.ISysDepartService;
|
||||
import org.jeecg.modules.system.service.ISysUserDepartService;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.jeecg.modules.system.vo.SysDepartExportVo;
|
||||
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
@ -350,24 +351,33 @@ public class SysDepartController {
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
// Step.1 组装查询条件
|
||||
QueryWrapper<SysDepart> queryWrapper = QueryGenerator.initQueryWrapper(sysDepart, request.getParameterMap());
|
||||
//Step.2 AutoPoi 导出Excel
|
||||
//update-begin---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
//// Step.1 组装查询条件
|
||||
//QueryWrapper<SysDepart> queryWrapper = QueryGenerator.initQueryWrapper(sysDepart, request.getParameterMap());
|
||||
//Step.1 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
List<SysDepart> pageList = sysDepartService.list(queryWrapper);
|
||||
//List<SysDepart> pageList = sysDepartService.list(queryWrapper);
|
||||
//按字典排序
|
||||
Collections.sort(pageList, new Comparator<SysDepart>() {
|
||||
@Override
|
||||
public int compare(SysDepart arg0, SysDepart arg1) {
|
||||
return arg0.getOrgCode().compareTo(arg1.getOrgCode());
|
||||
}
|
||||
});
|
||||
//Collections.sort(pageList, new Comparator<SysDepart>() {
|
||||
//@Override
|
||||
//public int compare(SysDepart arg0, SysDepart arg1) {
|
||||
//return arg0.getOrgCode().compareTo(arg1.getOrgCode());
|
||||
//}
|
||||
//});
|
||||
//step.2 组装导出数据
|
||||
List<SysDepartExportVo> sysDepartExportVos = sysDepartService.getExportDepart(sysDepart.getTenantId());
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "部门列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysDepart.class);
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysDepartExportVo.class);
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("部门列表数据", "导出人:"+user.getRealname(), "导出信息"));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("导入规则:\n" +
|
||||
"1、标题为第三行,部门路径和部门名称的标题不允许修改,否则会匹配失败;第四行为数据填写范围;\n" +
|
||||
"2、部门路径用英文字符/分割,部门名称为部门路径的最后一位;\n" +
|
||||
"3、部门从一级名称开始创建,如果有同级就需要多添加一行,如研发部/研发一部;研发部/研发二部;\n" +
|
||||
"4、自定义的部门编码需要满足规则才能导入。如一级部门编码为A01,那么子部门为A01A01,同级子部门为A01A02,编码固定为三位,首字母为A-Z,后两位为数字0-99,依次递增;", "导出人:"+user.getRealname(), "导出信息"));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, sysDepartExportVos);
|
||||
//update-end---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
|
||||
return mv;
|
||||
}
|
||||
|
||||
@ -386,7 +396,8 @@ public class SysDepartController {
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
List<String> errorMessageList = new ArrayList<>();
|
||||
List<SysDepart> listSysDeparts = null;
|
||||
//List<SysDepart> listSysDeparts = null;
|
||||
List<SysDepartExportVo> listSysDeparts = null;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 获取上传文件对象
|
||||
@ -396,51 +407,59 @@ public class SysDepartController {
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
// orgCode编码长度
|
||||
int codeLength = YouBianCodeUtil.ZHANWEI_LENGTH;
|
||||
listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), SysDepart.class, params);
|
||||
//按长度排序
|
||||
Collections.sort(listSysDeparts, new Comparator<SysDepart>() {
|
||||
@Override
|
||||
public int compare(SysDepart arg0, SysDepart arg1) {
|
||||
return arg0.getOrgCode().length() - arg1.getOrgCode().length();
|
||||
}
|
||||
});
|
||||
//update-begin---author:wangshuai---date:2023-10-20---for: 注释掉原来的导入部门的逻辑---
|
||||
// // orgCode编码长度
|
||||
// int codeLength = YouBianCodeUtil.ZHANWEI_LENGTH;
|
||||
// listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), SysDepart.class, params);
|
||||
// //按长度排序
|
||||
// Collections.sort(listSysDeparts, new Comparator<SysDepart>() {
|
||||
// @Override
|
||||
// public int compare(SysDepart arg0, SysDepart arg1) {
|
||||
// return arg0.getOrgCode().length() - arg1.getOrgCode().length();
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// int num = 0;
|
||||
// for (SysDepart sysDepart : listSysDeparts) {
|
||||
// String orgCode = sysDepart.getOrgCode();
|
||||
// if(orgCode.length() > codeLength) {
|
||||
// String parentCode = orgCode.substring(0, orgCode.length()-codeLength);
|
||||
// QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<SysDepart>();
|
||||
// queryWrapper.eq("org_code", parentCode);
|
||||
// try {
|
||||
// SysDepart parentDept = sysDepartService.getOne(queryWrapper);
|
||||
// if(!parentDept.equals(null)) {
|
||||
// sysDepart.setParentId(parentDept.getId());
|
||||
// //更新父级部门不是叶子结点
|
||||
// sysDepartService.updateIzLeaf(parentDept.getId(),CommonConstant.NOT_LEAF);
|
||||
// } else {
|
||||
// sysDepart.setParentId("");
|
||||
// }
|
||||
// }catch (Exception e) {
|
||||
// //没有查找到parentDept
|
||||
// }
|
||||
// }else{
|
||||
// sysDepart.setParentId("");
|
||||
// }
|
||||
// //update-begin---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
|
||||
// sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
|
||||
// //update-end---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
|
||||
// sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
// //update-begin---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
// if(oConvertUtils.isEmpty(sysDepart.getOrgCategory())){
|
||||
// sysDepart.setOrgCategory("1");
|
||||
// }
|
||||
// //update-end---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
// ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
|
||||
// num++;
|
||||
// }
|
||||
//update-end---author:wangshuai---date:2023-10-20---for: 注释掉原来的导入部门的逻辑---
|
||||
|
||||
//update-begin---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), SysDepartExportVo.class, params);
|
||||
sysDepartService.importSysDepart(listSysDeparts,errorMessageList);
|
||||
//update-end---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
|
||||
int num = 0;
|
||||
for (SysDepart sysDepart : listSysDeparts) {
|
||||
String orgCode = sysDepart.getOrgCode();
|
||||
if(orgCode.length() > codeLength) {
|
||||
String parentCode = orgCode.substring(0, orgCode.length()-codeLength);
|
||||
QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<SysDepart>();
|
||||
queryWrapper.eq("org_code", parentCode);
|
||||
try {
|
||||
SysDepart parentDept = sysDepartService.getOne(queryWrapper);
|
||||
if(!parentDept.equals(null)) {
|
||||
sysDepart.setParentId(parentDept.getId());
|
||||
//更新父级部门不是叶子结点
|
||||
sysDepartService.updateIzLeaf(parentDept.getId(),CommonConstant.NOT_LEAF);
|
||||
} else {
|
||||
sysDepart.setParentId("");
|
||||
}
|
||||
}catch (Exception e) {
|
||||
//没有查找到parentDept
|
||||
}
|
||||
}else{
|
||||
sysDepart.setParentId("");
|
||||
}
|
||||
//update-begin---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
|
||||
sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
|
||||
//update-end---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
|
||||
sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
//update-begin---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
if(oConvertUtils.isEmpty(sysDepart.getOrgCategory())){
|
||||
sysDepart.setOrgCategory("1");
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
|
||||
num++;
|
||||
}
|
||||
//清空部门缓存
|
||||
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||
@ -544,7 +563,7 @@ public class SysDepartController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryByIds", method = RequestMethod.GET)
|
||||
public Result<Collection<SysDepart>> queryByIds(@RequestParam String deptIds) {
|
||||
public Result<Collection<SysDepart>> queryByIds(@RequestParam(name = "deptIds") String deptIds) {
|
||||
Result<Collection<SysDepart>> result = new Result<>();
|
||||
String[] ids = deptIds.split(",");
|
||||
Collection<String> idList = Arrays.asList(ids);
|
||||
|
||||
@ -79,8 +79,8 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<SysDepartRole> queryWrapper = QueryGenerator.initQueryWrapper(sysDepartRole, req.getParameterMap());
|
||||
Page<SysDepartRole> page = new Page<SysDepartRole>(pageNo, pageSize);
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
List<String> deptIds = null;
|
||||
// LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
// List<String> deptIds = null;
|
||||
// if(oConvertUtils.isEmpty(deptId)){
|
||||
// if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals(CommonConstant.USER_IDENTITY_2) ){
|
||||
// deptIds = sysDepartService.getMySubDepIdsByDepId(user.getDepartIds());
|
||||
@ -93,7 +93,10 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
|
||||
// queryWrapper.in("depart_id",deptIds);
|
||||
|
||||
//我的部门,选中部门只能看当前部门下的角色
|
||||
if(oConvertUtils.isNotEmpty(deptId)){
|
||||
queryWrapper.eq("depart_id",deptId);
|
||||
}
|
||||
|
||||
IPage<SysDepartRole> pageList = sysDepartRoleService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import java.util.Arrays;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
@ -54,6 +55,7 @@ public class SysLogController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
//@RequiresPermissions("system:log:list")
|
||||
public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
|
||||
Result<IPage<SysLog>> result = new Result<IPage<SysLog>>();
|
||||
@ -84,6 +86,7 @@ public class SysLogController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
|
||||
//@RequiresPermissions("system:log:delete")
|
||||
public Result<SysLog> delete(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysLog> result = new Result<SysLog>();
|
||||
SysLog sysLog = sysLogService.getById(id);
|
||||
@ -104,6 +107,7 @@ public class SysLogController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
|
||||
//@RequiresPermissions("system:log:deleteBatch")
|
||||
public Result<SysRole> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
Result<SysRole> result = new Result<SysRole>();
|
||||
if(ids==null || "".equals(ids.trim())) {
|
||||
|
||||
@ -123,9 +123,13 @@ public class SysRoleController {
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
//update-begin---author:wangshuai---date:2023-11-20---for:【QQYUN-7089】低代码模式 选择组织角色没有数据 在租户角色中添加数据后,列表也无数据展示---
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
//此接口必须通过租户来隔离查询
|
||||
role.setTenantId(oConvertUtils.getInt(!"0".equals(TenantContext.getTenant()) ? TenantContext.getTenant() : "", -1));
|
||||
}
|
||||
//update-end---author:wangshuai---date:2023-11-20---for:【QQYUN-7089】低代码模式 选择组织角色没有数据 在租户角色中添加数据后,列表也无数据展示---
|
||||
|
||||
QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
|
||||
Page<SysRole> page = new Page<SysRole>(pageNo, pageSize);
|
||||
@ -527,7 +531,6 @@ public class SysRoleController {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO 权限未完成(敲敲云接口,租户应用)
|
||||
* 分页获取全部角色列表(包含每个角色的数量)
|
||||
* @return
|
||||
*/
|
||||
|
||||
@ -42,7 +42,7 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(
|
||||
SysTableWhiteList sysTableWhiteList,
|
||||
@ -64,7 +64,7 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
|
||||
*/
|
||||
@AutoLog(value = "系统表白名单-添加")
|
||||
@ApiOperation(value = "系统表白名单-添加", notes = "系统表白名单-添加")
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysTableWhiteList sysTableWhiteList) {
|
||||
if (sysTableWhiteListService.add(sysTableWhiteList)) {
|
||||
@ -82,7 +82,7 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
|
||||
*/
|
||||
@AutoLog(value = "系统表白名单-编辑")
|
||||
@ApiOperation(value = "系统表白名单-编辑", notes = "系统表白名单-编辑")
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysTableWhiteList sysTableWhiteList) {
|
||||
if (sysTableWhiteListService.edit(sysTableWhiteList)) {
|
||||
@ -100,7 +100,7 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
|
||||
*/
|
||||
@AutoLog(value = "系统表白名单-通过id删除")
|
||||
@ApiOperation(value = "系统表白名单-通过id删除", notes = "系统表白名单-通过id删除")
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id") String id) {
|
||||
if (sysTableWhiteListService.deleteByIds(id)) {
|
||||
@ -118,7 +118,7 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
|
||||
*/
|
||||
@AutoLog(value = "系统表白名单-批量删除")
|
||||
@ApiOperation(value = "系统表白名单-批量删除", notes = "系统表白名单-批量删除")
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids") String ids) {
|
||||
if (sysTableWhiteListService.deleteByIds(ids)) {
|
||||
@ -136,7 +136,7 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
|
||||
*/
|
||||
@AutoLog(value = "系统表白名单-通过id查询")
|
||||
@ApiOperation(value = "系统表白名单-通过id查询", notes = "系统表白名单-通过id查询")
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresRoles("admin")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
SysTableWhiteList sysTableWhiteList = sysTableWhiteListService.getById(id);
|
||||
|
||||
@ -858,16 +858,19 @@ public class SysTenantController {
|
||||
@GetMapping("/getTenantCount")
|
||||
public Result<Map<String,Long>> getTenantCount(HttpServletRequest request){
|
||||
Map<String,Long> map = new HashMap<>();
|
||||
Integer tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request),0);
|
||||
LambdaQueryWrapper<SysUserTenant> userTenantQuery = new LambdaQueryWrapper<>();
|
||||
userTenantQuery.eq(SysUserTenant::getTenantId,tenantId);
|
||||
userTenantQuery.eq(SysUserTenant::getStatus,CommonConstant.USER_TENANT_NORMAL);
|
||||
long userCount = relationService.count(userTenantQuery);
|
||||
//update-begin---author:wangshuai---date:2023-11-24---for:【QQYUN-7177】用户数量显示不正确---
|
||||
if(oConvertUtils.isEmpty(TokenUtils.getTenantIdByRequest(request))){
|
||||
return Result.error("当前租户为空,禁止访问!");
|
||||
}
|
||||
Integer tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request));
|
||||
Long userCount = relationService.getUserCount(tenantId,CommonConstant.USER_TENANT_NORMAL);
|
||||
//update-end---author:wangshuai---date:2023-11-24---for:【QQYUN-7177】用户数量显示不正确---
|
||||
map.put("userCount",userCount);
|
||||
LambdaQueryWrapper<SysDepart> departQuery = new LambdaQueryWrapper<>();
|
||||
departQuery.eq(SysDepart::getDelFlag,String.valueOf(CommonConstant.DEL_FLAG_0));
|
||||
departQuery.eq(SysDepart::getTenantId,tenantId);
|
||||
departQuery.eq(SysDepart::getStatus,CommonConstant.STATUS_1);
|
||||
//部门状态暂时没用,先注释掉
|
||||
//departQuery.eq(SysDepart::getStatus,CommonConstant.STATUS_1);
|
||||
long departCount = sysDepartService.count(departQuery);
|
||||
map.put("departCount",departCount);
|
||||
return Result.ok(map);
|
||||
|
||||
@ -437,12 +437,13 @@ public class SysUserController {
|
||||
@RequestParam(name = "departId", required = false) String departId,
|
||||
@RequestParam(name="realname",required=false) String realname,
|
||||
@RequestParam(name="username",required=false) String username,
|
||||
@RequestParam(name="isMultiTranslate",required=false) String isMultiTranslate,
|
||||
@RequestParam(name="id",required = false) String id) {
|
||||
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
|
||||
String[] arr = new String[]{departId, realname, username, id};
|
||||
SqlInjectionUtil.filterContent(arr, SymbolConstant.SINGLE_QUOTATION_MARK);
|
||||
//update-end-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
|
||||
IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo,id);
|
||||
IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo,id,isMultiTranslate);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
@ -568,7 +569,7 @@ public class SysUserController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryByIds", method = RequestMethod.GET)
|
||||
public Result<Collection<SysUser>> queryByIds(@RequestParam String userIds) {
|
||||
public Result<Collection<SysUser>> queryByIds(@RequestParam(name = "userIds") String userIds) {
|
||||
Result<Collection<SysUser>> result = new Result<>();
|
||||
String[] userId = userIds.split(",");
|
||||
Collection<String> idList = Arrays.asList(userId);
|
||||
@ -585,7 +586,7 @@ public class SysUserController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryByNames", method = RequestMethod.GET)
|
||||
public Result<Collection<SysUser>> queryByNames(@RequestParam String userNames) {
|
||||
public Result<Collection<SysUser>> queryByNames(@RequestParam(name = "userNames") String userNames) {
|
||||
Result<Collection<SysUser>> result = new Result<>();
|
||||
String[] names = userNames.split(",");
|
||||
QueryWrapper<SysUser> queryWrapper=new QueryWrapper();
|
||||
@ -1427,7 +1428,7 @@ public class SysUserController {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
String tenantId = TokenUtils.getTenantIdByRequest(request);
|
||||
String tenantId = oConvertUtils.getString(TokenUtils.getTenantIdByRequest(request),"-1");
|
||||
//update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
List<String> userIds = userTenantService.getUserIdsByTenantId(Integer.valueOf(tenantId));
|
||||
if (oConvertUtils.listIsNotEmpty(userIds)) {
|
||||
|
||||
@ -14,6 +14,7 @@ import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.TokenUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.system.entity.SysThirdAccount;
|
||||
@ -22,6 +23,8 @@ import org.jeecg.modules.system.service.ISysThirdAccountService;
|
||||
import org.jeecg.modules.system.service.ISysThirdAppConfigService;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
|
||||
import org.jeecg.modules.system.vo.thirdapp.JwSysUserDepartVo;
|
||||
import org.jeecg.modules.system.vo.thirdapp.JwUserDepartVo;
|
||||
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -424,10 +427,6 @@ public class ThirdAppController {
|
||||
@GetMapping("/getThirdConfigByTenantId")
|
||||
public Result<SysThirdAppConfig> getThirdAppByTenantId(@RequestParam(name = "tenantId", required = false) Integer tenantId,
|
||||
@RequestParam(name = "thirdType") String thirdType) {
|
||||
Result<SysThirdAppConfig> result = new Result<>();
|
||||
LambdaQueryWrapper<SysThirdAppConfig> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysThirdAppConfig::getThirdType,thirdType);
|
||||
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
if (tenantId == null) {
|
||||
return Result.error("开启多租户模式,租户ID参数不允许为空!");
|
||||
@ -438,7 +437,9 @@ public class ThirdAppController {
|
||||
tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
Result<SysThirdAppConfig> result = new Result<>();
|
||||
LambdaQueryWrapper<SysThirdAppConfig> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysThirdAppConfig::getThirdType,thirdType);
|
||||
query.eq(SysThirdAppConfig::getTenantId,tenantId);
|
||||
SysThirdAppConfig sysThirdAppConfig = appConfigService.getOne(query);
|
||||
result.setSuccess(true);
|
||||
@ -520,4 +521,46 @@ public class ThirdAppController {
|
||||
return Result.ok("解绑成功");
|
||||
}
|
||||
//========================end 应用低代码账号设置第三方账号绑定 ================================
|
||||
|
||||
/**
|
||||
* 获取企业微信绑定的用户信息
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getThirdUserByWechat")
|
||||
public Result<JwSysUserDepartVo> getThirdUserByWechat(HttpServletRequest request){
|
||||
//获取企业微信配置
|
||||
Integer tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request),0);
|
||||
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.QYWX.getType());
|
||||
if (null != config) {
|
||||
JwSysUserDepartVo list = wechatEnterpriseService.getThirdUserByWechat(tenantId);
|
||||
return Result.ok(list);
|
||||
}
|
||||
return Result.error("企业微信尚未配置,请配置企业微信");
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步企业微信部门和用户到本地
|
||||
* @param jwUserDepartJson
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sync/wechatEnterprise/departAndUser/toLocal")
|
||||
public Result<SyncInfoVo> syncWechatEnterpriseDepartAndUserToLocal(@RequestParam(name = "jwUserDepartJson") String jwUserDepartJson,HttpServletRequest request){
|
||||
int tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request), 0);
|
||||
SyncInfoVo syncInfoVo = wechatEnterpriseService.syncWechatEnterpriseDepartAndUserToLocal(jwUserDepartJson,tenantId);
|
||||
return Result.ok(syncInfoVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询被绑定的企业微信用户
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getThirdUserBindByWechat")
|
||||
public Result<List<JwUserDepartVo>> getThirdUserBindByWechat(HttpServletRequest request){
|
||||
int tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request), 0);
|
||||
List<JwUserDepartVo> jwSysUserDepartVos = wechatEnterpriseService.getThirdUserBindByWechat(tenantId);
|
||||
return Result.ok(jwSysUserDepartVos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @Description: 企业微信证书验证
|
||||
* @author: wangshuai
|
||||
* @date: 2023/12/6 10:42
|
||||
*/
|
||||
@RestController
|
||||
@Slf4j
|
||||
public class WechatVerifyController {
|
||||
|
||||
/**
|
||||
* 企业微信验证
|
||||
*/
|
||||
@RequestMapping(value = "/WW_verify_{code}.txt")
|
||||
public void mpVerify(@PathVariable("code") String code, HttpServletResponse response) {
|
||||
try {
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.write(code);
|
||||
writer.close();
|
||||
} catch (Exception e) {
|
||||
log.error("企业微信证书验证失败!");
|
||||
log.error(e.getMessage(), e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ public class SysTenantPackUser implements Serializable {
|
||||
private transient String packCode;
|
||||
|
||||
/**
|
||||
* 状态(1 正常 2 离职 3 待审核 4 拒绝 5 邀请加入)
|
||||
* 状态(申请状态0 正常状态1)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
|
||||
@ -48,6 +48,4 @@ public class SysUserRole implements Serializable {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.model.TreeModel;
|
||||
import org.jeecg.modules.system.vo.SysDepartExportVo;
|
||||
import org.jeecg.modules.system.vo.SysUserDepVo;
|
||||
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
@ -161,4 +162,12 @@ public interface SysDepartMapper extends BaseMapper<SysDepart> {
|
||||
* @return
|
||||
*/
|
||||
List<SysDepart> getDepartPageByName(@Param("page") Page<SysDepart> page, @Param("departName") String departName, @Param("tenantId") Integer tenantId, @Param("parentId") String parentId);
|
||||
|
||||
/**
|
||||
* 获取租户id和部门父id获取的部门数据
|
||||
* @param tenantId
|
||||
* @param parentId
|
||||
* @return
|
||||
*/
|
||||
List<SysDepartExportVo> getSysDepartList(@Param("parentId") String parentId,@Param("tenantId") Integer tenantId);
|
||||
}
|
||||
|
||||
@ -120,4 +120,11 @@ public interface SysTenantMapper extends BaseMapper<SysTenant> {
|
||||
*/
|
||||
Long getApplySuperAdminCount(@Param("userId") String userId, @Param("tenantId") Integer tenantId);
|
||||
|
||||
/**
|
||||
* 租户是否存在
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
@Select("select count(1) from sys_tenant where id = #{tenantId} and del_flag = 0")
|
||||
Long tenantIzExist(@Param("tenantId") Integer tenantId);
|
||||
}
|
||||
|
||||
@ -25,4 +25,11 @@ public interface SysTenantPackUserMapper extends BaseMapper<SysTenantPackUser> {
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
List<String> queryTenantPackUserNameList(@Param("tenantId") Integer tenantId, @Param("packCodeList") List<String> packCodeList);
|
||||
|
||||
/**
|
||||
* 判断当前用户在该租户下是否拥有管理员的权限
|
||||
* @param userId
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
Long izHaveBuyAuth(@Param("userId") String userId, @Param("tenantId") String tenantId);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package org.jeecg.modules.system.mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.system.entity.SysThirdAccount;
|
||||
import org.jeecg.modules.system.vo.thirdapp.JwUserDepartVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -23,4 +24,11 @@ public interface SysThirdAccountMapper extends BaseMapper<SysThirdAccount> {
|
||||
*/
|
||||
List<SysThirdAccount> selectThirdIdsByUsername(@Param("sysUsernameArr") String[] sysUsernameArr, @Param("thirdType") String thirdType, @Param("tenantId") Integer tenantId);
|
||||
|
||||
/**
|
||||
* 查询被绑定的用户
|
||||
* @param tenantId
|
||||
* @param thirdType
|
||||
* @return
|
||||
*/
|
||||
List<JwUserDepartVo> getThirdUserBindByWechat(@Param("tenantId") int tenantId, @Param("thirdType") String thirdType);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package org.jeecg.modules.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
@ -64,6 +65,7 @@ public interface SysUserPositionMapper extends BaseMapper<SysUserPosition> {
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
List<String> getPositionIdByUserTenantId(@Param("userId")String userId, @Param("tenantId")Integer tenantId);
|
||||
|
||||
/**
|
||||
|
||||
@ -12,6 +12,7 @@ import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.entity.SysUserTenant;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.jeecg.modules.system.vo.SysUserTenantVo;
|
||||
import org.jeecg.modules.system.vo.thirdapp.JwUserDepartVo;
|
||||
|
||||
/**
|
||||
* @Description: sys_user_tenant_relation
|
||||
@ -149,4 +150,20 @@ public interface SysUserTenantMapper extends BaseMapper<SysUserTenant> {
|
||||
* @param tenantIds
|
||||
*/
|
||||
void deleteUserByTenantId(@Param("tenantIds") List<Integer> tenantIds);
|
||||
|
||||
/**
|
||||
* 获取租户下的成员数量
|
||||
*
|
||||
* @param tenantId
|
||||
* @param tenantStatus
|
||||
* @return
|
||||
*/
|
||||
Long getUserCount(Integer tenantId, String tenantStatus);
|
||||
|
||||
/**
|
||||
* 根据租户id和名称获取用户数据
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
List<JwUserDepartVo> getUsersByTenantIdAndName(@Param("tenantId") Integer tenantId);
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
|
||||
<select id="querySysCementListByUserId" parameterType="String" resultMap="SysAnnouncement">
|
||||
select * from sys_announcement
|
||||
select id,titile,create_time,priority,bus_id,open_type,open_page,sender,send_time,msg_content from sys_announcement
|
||||
where send_status = '1'
|
||||
and del_flag = '0'
|
||||
and msg_category = #{msgCategory}
|
||||
|
||||
@ -114,7 +114,9 @@
|
||||
SELECT id,depart_name,org_code,parent_id FROM sys_depart
|
||||
where
|
||||
depart_name = #{departName}
|
||||
<if test="null != tenantId and 0 != tenantId">
|
||||
and tenant_id = #{tenantId}
|
||||
</if>
|
||||
<if test="parentId != null and parentId != ''">
|
||||
and parent_id = #{parentId}
|
||||
</if>
|
||||
@ -154,4 +156,24 @@
|
||||
</foreach>
|
||||
)
|
||||
</select>
|
||||
|
||||
<!--系统后台导出,根据父级id和租户id查询部门数据-->
|
||||
<select id="getSysDepartList" resultType="org.jeecg.modules.system.vo.SysDepartExportVo">
|
||||
SELECT id,depart_name,parent_id,depart_name_en,depart_order,description,org_category,org_code,mobile,fax,address,memo FROM sys_depart
|
||||
WHERE
|
||||
1=1
|
||||
<if test="null != tenantId and 0 != tenantId">
|
||||
AND tenant_id = #{tenantId}
|
||||
</if>
|
||||
AND
|
||||
<choose>
|
||||
<when test="parentId != null and parentId != ''">
|
||||
parent_id = #{parentId}
|
||||
</when>
|
||||
<otherwise>
|
||||
parent_id IS NULL OR parent_id=''
|
||||
</otherwise>
|
||||
</choose>
|
||||
ORDER BY depart_order DESC
|
||||
</select>
|
||||
</mapper>
|
||||
@ -43,6 +43,7 @@
|
||||
<select id="queryTenantPackUserCount" resultType="org.jeecg.modules.system.vo.tenant.TenantPackUserCount">
|
||||
SELECT pack_code, count(*) as user_count FROM sys_tenant_pack a
|
||||
join sys_tenant_pack_user b on a.id = b.pack_id
|
||||
join sys_user_tenant sut on a.tenant_id = sut.tenant_id and b.user_id = sut.user_id and sut.status = 1
|
||||
where a.tenant_id = #{tenantId}
|
||||
and a.pack_code in ('superAdmin', 'accountAdmin', 'appAdmin')
|
||||
and b.status = 1
|
||||
@ -74,6 +75,7 @@
|
||||
SELECT c.id, c.username, c.realname, c.phone, c.avatar, a.pack_name, a.id as pack_id FROM sys_user c
|
||||
join sys_tenant_pack_user b on c.id = b.user_id
|
||||
join sys_tenant_pack a on a.id = b.pack_id
|
||||
join sys_user_tenant sut on a.tenant_id = sut.tenant_id and b.user_id = sut.user_id and sut.status = 1
|
||||
where c.status = 1
|
||||
and c.del_flag = 0
|
||||
and b.status = #{packUserStatus}
|
||||
|
||||
@ -15,4 +15,12 @@
|
||||
)
|
||||
</select>
|
||||
|
||||
<!-- 判断当前用户在该租户下是否拥有管理员的权限 -->
|
||||
<select id="izHaveBuyAuth" resultType="java.lang.Long">
|
||||
SELECT count(1) from sys_tenant_pack_user stpu
|
||||
left join sys_tenant_pack stp on stpu.pack_id = stp.id
|
||||
WHERE stpu.tenant_id = #{tenantId}
|
||||
and stpu.user_id = #{userId}
|
||||
and stp.pack_code in('superAdmin','accountAdmin')
|
||||
</select>
|
||||
</mapper>
|
||||
@ -15,4 +15,13 @@
|
||||
<foreach collection="sysUsernameArr" item="item" open=" sys_user.username IN (" close=")" separator=",">#{item}</foreach>
|
||||
</select>
|
||||
|
||||
<!--查询被绑定的用户-->
|
||||
<select id="getThirdUserBindByWechat" resultType="org.jeecg.modules.system.vo.thirdapp.JwUserDepartVo">
|
||||
SELECT su.id userId, su.realname, su.avatar, sta.realname as wechatRealName, sta.third_user_id as wechatUserId, sta.id as thirdId
|
||||
FROM sys_third_account sta
|
||||
LEFT JOIN sys_user su on sta.sys_user_id = su.id
|
||||
WHERE sta.tenant_id = #{tenantId}
|
||||
AND sta.third_type = #{thirdType}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -26,7 +26,9 @@
|
||||
LEFT JOIN sys_position sp ON sup.position_id = sp.id
|
||||
WHERE
|
||||
sup.user_id = #{userId}
|
||||
<if test="tenantId != null and tenantId != 0">
|
||||
AND sp.tenant_id = #{tenantId}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!--职位列表移除成员-->
|
||||
|
||||
@ -39,9 +39,9 @@
|
||||
|
||||
<!--通过用户id获取租户列表-->
|
||||
<select id="getTenantListByUserId" resultType="org.jeecg.modules.system.vo.SysUserTenantVo">
|
||||
SELECT st.id as tenantUserId,st.name,st.trade,st.house_number,st.create_by,sut.status as userTenantStatus
|
||||
SELECT st.id as tenantUserId,st.name,st.trade,st.house_number,st.create_by,sut.status as userTenantStatus,sut.user_id as id
|
||||
FROM sys_user_tenant sut
|
||||
JOIN sys_tenant st ON sut.tenant_id = st.id
|
||||
LEFT JOIN sys_tenant st ON sut.tenant_id = st.id
|
||||
WHERE st.status = 1
|
||||
AND st.del_flag = 0
|
||||
AND sut.user_id = #{userId}
|
||||
@ -164,4 +164,22 @@
|
||||
#{tenantId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<!-- 获取租户下的成员数量 -->
|
||||
<select id="getUserCount" resultType="java.lang.Long">
|
||||
SELECT count(1) FROM sys_user_tenant sut JOIN sys_user su on sut.user_id = su.id and su.del_flag = 0 and su.status = 1
|
||||
WHERE sut.status = #{tenantStatus}
|
||||
AND sut.tenant_id = #{tenantId}
|
||||
</select>
|
||||
|
||||
<!--根据租户id和名称获取用户数据-->
|
||||
<select id="getUsersByTenantIdAndName" resultType="org.jeecg.modules.system.vo.thirdapp.JwUserDepartVo">
|
||||
SELECT su.id userId,su.realname,su.avatar
|
||||
FROM sys_user_tenant sut
|
||||
JOIN sys_tenant st ON sut.tenant_id = st.id and st.status = 1 and st.del_flag = 0
|
||||
JOIN sys_user su ON sut.user_id = su.id and su.status = 1 and su.del_flag = 0
|
||||
WHERE
|
||||
sut.status = 1
|
||||
AND sut.tenant_id = #{tenantId}
|
||||
</select>
|
||||
</mapper>
|
||||
@ -89,4 +89,13 @@ public interface ISysCategoryService extends IService<SysCategory> {
|
||||
*/
|
||||
List<String> loadDictItem(String ids, boolean delNotExist);
|
||||
|
||||
/**
|
||||
* 【仅导入使用】分类字典控件反向翻译
|
||||
*
|
||||
* @param names
|
||||
* @param delNotExist 是否移除不存在的项,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||
* @return
|
||||
*/
|
||||
List<String> loadDictItemByNames(String names, boolean delNotExist);
|
||||
|
||||
}
|
||||
|
||||
@ -5,8 +5,10 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysUserDepart;
|
||||
import org.jeecg.modules.system.model.DepartIdModel;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.vo.SysDepartExportVo;
|
||||
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@ -216,4 +218,17 @@ public interface ISysDepartService extends IService<SysDepart>{
|
||||
|
||||
void importExcel(List<ExportDepartVo> listSysDeparts, List<String> errorMessageList);
|
||||
|
||||
/**
|
||||
* 根据租户id导出部门
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
List<SysDepartExportVo> getExportDepart(int tenantId);
|
||||
|
||||
/**
|
||||
* 导出系统部门excel
|
||||
* @param listSysDeparts
|
||||
* @param errorMessageList
|
||||
*/
|
||||
void importSysDepart(List<SysDepartExportVo> listSysDeparts, List<String> errorMessageList);
|
||||
}
|
||||
|
||||
@ -107,6 +107,7 @@ public interface ISysDictService extends IService<SysDict> {
|
||||
@Deprecated
|
||||
String queryTableDictTextByKey(String table, String text, String code, String key);
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 通过查询指定table的 text code key 获取字典值,可批量查询
|
||||
*
|
||||
@ -114,9 +115,11 @@ public interface ISysDictService extends IService<SysDict> {
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys
|
||||
* @param dataSource 数据源
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> keys);
|
||||
List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> keys, String dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
/**
|
||||
* 通过查询指定table的 text code key 获取字典值,包含value
|
||||
|
||||
@ -75,7 +75,8 @@ public interface ISysThirdAccountService extends IService<SysThirdAccount> {
|
||||
* @param unionid
|
||||
* @param thirdType
|
||||
* @param tenantId
|
||||
* @param thirdUserId
|
||||
* @return
|
||||
*/
|
||||
SysThirdAccount getOneByUuidAndThirdType(String unionid, String thirdType,Integer tenantId);
|
||||
SysThirdAccount getOneByUuidAndThirdType(String unionid, String thirdType,Integer tenantId,String thirdUserId);
|
||||
}
|
||||
|
||||
@ -51,9 +51,10 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
|
||||
* @param pageNo
|
||||
* @param realname
|
||||
* @param id
|
||||
* @param isMultiTranslate 是否多字段翻译
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id);
|
||||
IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id,String isMultiTranslate);
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
|
||||
@ -120,4 +120,12 @@ public interface ISysUserTenantService extends IService<SysUserTenant> {
|
||||
* @return
|
||||
*/
|
||||
SysUserTenant getUserTenantByTenantId(String userId, Integer tenantId);
|
||||
|
||||
/**
|
||||
* 获取租户下的成员数量
|
||||
* @param tenantId
|
||||
* @param tenantStatus
|
||||
* @return
|
||||
*/
|
||||
Long getUserCount(Integer tenantId, String tenantStatus);
|
||||
}
|
||||
|
||||
@ -24,4 +24,9 @@ public class ImportFileServiceImpl implements ImportFileServiceI {
|
||||
public String doUpload(byte[] data) {
|
||||
return CommonUtils.uploadOnlineImage(data, upLoadPath, "import", uploadType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doUpload(byte[] data, String saveUrl) {
|
||||
return CommonUtils.uploadOnlineImage(data, upLoadPath, "import", uploadType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
@ -61,7 +62,12 @@ public class SysAnnouncementServiceImpl extends ServiceImpl<SysAnnouncementMappe
|
||||
sysAnnouncementMapper.insert(sysAnnouncement);
|
||||
// 2.插入用户通告阅读标记表记录
|
||||
String userId = sysAnnouncement.getUserIds();
|
||||
String[] userIds = userId.substring(0, (userId.length()-1)).split(",");
|
||||
//update-begin-author:liusq---date:2023-10-31--for:[issues/5503]【公告】通知无法接收
|
||||
if(StringUtils.isNotBlank(userId) && userId.endsWith(",")){
|
||||
userId = userId.substring(0, (userId.length()-1));
|
||||
}
|
||||
String[] userIds = userId.split(",");
|
||||
//update-end-author:liusq---date:2023-10-31--for:[issues/5503]【公告】通知无法接收
|
||||
String anntId = sysAnnouncement.getId();
|
||||
Date refDate = new Date();
|
||||
for(int i=0;i<userIds.length;i++) {
|
||||
|
||||
@ -34,7 +34,8 @@ import org.jeecg.common.system.query.QueryCondition;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.system.vo.*;
|
||||
import org.jeecg.common.util.*;
|
||||
import org.jeecg.common.util.HTMLUtils;
|
||||
import org.jeecg.common.util.YouBianCodeUtil;
|
||||
import org.jeecg.common.util.dynamic.db.FreemarkerParseFactory;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.firewall.SqlInjection.IDictTableWhiteListHandler;
|
||||
@ -57,6 +58,7 @@ import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.PathMatcher;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -323,6 +325,30 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDepartParentIdsByUsername(String username) {
|
||||
List<SysDepart> list = sysDepartService.queryDepartsByUsername(username);
|
||||
Set<String> result = new HashSet<>(list.size());
|
||||
for (SysDepart depart : list) {
|
||||
result.add(depart.getParentId());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDepartParentIdsByDepIds(Set depIds) {
|
||||
LambdaQueryWrapper<SysDepart> departQuery = new LambdaQueryWrapper<SysDepart>().in(SysDepart::getId, depIds);
|
||||
List<SysDepart> departList = departMapper.selectList(departQuery);
|
||||
|
||||
if(CollectionUtils.isEmpty(departList)){
|
||||
return null;
|
||||
}
|
||||
Set<String> parentIds = departList.stream()
|
||||
.map(SysDepart::getParentId)
|
||||
.collect(Collectors.toSet());
|
||||
return parentIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDepartNamesByUsername(String username) {
|
||||
List<SysDepart> list = sysDepartService.queryDepartsByUsername(username);
|
||||
@ -1388,6 +1414,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
return sysCategoryService.loadDictItem(ids, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> loadCategoryDictItemByNames(String names, boolean delNotExist) {
|
||||
return sysCategoryService.loadDictItemByNames(names, delNotExist);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典code加载字典text
|
||||
*
|
||||
@ -1461,13 +1492,17 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
public Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys) {
|
||||
List<String> dictCodeList = Arrays.asList(dictCodes.split(","));
|
||||
List<String> values = Arrays.asList(keys.split(","));
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
return sysDictService.queryManyDictByKeys(dictCodeList, values);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
@Override
|
||||
public List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys) {
|
||||
return sysDictService.queryTableDictTextByKeys(table, text, code, Arrays.asList(keys.split(",")));
|
||||
public List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys, String dataSource) {
|
||||
return sysDictService.queryTableDictTextByKeys(table, text, code, Arrays.asList(keys.split(",")), dataSource);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
//-------------------------------------流程节点发送模板消息-----------------------------------------------
|
||||
@Autowired
|
||||
|
||||
@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.FillRuleConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
@ -18,10 +17,7 @@ import org.jeecg.modules.system.service.ISysCategoryService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -235,4 +231,22 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa
|
||||
return textList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> loadDictItemByNames(String names, boolean delNotExist) {
|
||||
List<String> nameList = Arrays.asList(names.split(SymbolConstant.COMMA));
|
||||
LambdaQueryWrapper<SysCategory> query = new LambdaQueryWrapper<>();
|
||||
query.select(SysCategory::getId, SysCategory::getName);
|
||||
query.in(SysCategory::getName, nameList);
|
||||
// 查询数据
|
||||
List<SysCategory> list = super.list(query);
|
||||
// 取出id并返回
|
||||
return nameList.stream().map(name -> {
|
||||
SysCategory res = list.stream().filter(i -> name.equals(i.getName())).findFirst().orElse(null);
|
||||
if (res == null) {
|
||||
return delNotExist ? null : name;
|
||||
}
|
||||
return res.getId();
|
||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
@ -28,9 +29,9 @@ import org.jeecg.modules.system.model.DepartIdModel;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.service.ISysDepartService;
|
||||
import org.jeecg.modules.system.util.FindsDepartsChildrenUtil;
|
||||
import org.jeecg.modules.system.vo.SysDepartExportVo;
|
||||
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -69,6 +70,11 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
//根据部门id获取所负责部门
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
||||
String[] codeArr = this.getMyDeptParentOrgCode(departIds);
|
||||
//update-begin---author:wangshuai---date:2023-12-01---for:【QQYUN-7320】查询部门没数据,导致报错空指针---
|
||||
if(ArrayUtil.isEmpty(codeArr)){
|
||||
return null;
|
||||
}
|
||||
//update-end---author:wangshuai---date:2023-12-01---for:【QQYUN-7320】查询部门没数据,导致报错空指针---
|
||||
for(int i=0;i<codeArr.length;i++){
|
||||
query.or().likeRight(SysDepart::getOrgCode,codeArr[i]);
|
||||
}
|
||||
@ -197,6 +203,14 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
//新添加的部门是叶子节点
|
||||
sysDepart.setIzLeaf(CommonConstant.IS_LEAF);
|
||||
// 【QQYUN-7172】数据库默认值兼容
|
||||
if (oConvertUtils.isEmpty(sysDepart.getOrgCategory())) {
|
||||
if (oConvertUtils.isEmpty(sysDepart.getParentId())) {
|
||||
sysDepart.setOrgCategory("1");
|
||||
} else {
|
||||
sysDepart.setOrgCategory("2");
|
||||
}
|
||||
}
|
||||
this.save(sysDepart);
|
||||
//update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
|
||||
//新增部门的时候新增负责部门
|
||||
@ -485,7 +499,10 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
//根据部门id查询所负责部门
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
||||
query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
|
||||
if(oConvertUtils.isNotEmpty(departIds)){
|
||||
query.in(SysDepart::getId, Arrays.asList(departIds.split(",")));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
@ -1195,4 +1212,169 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//========================begin 系统下部门与人员导入 ==================================================================
|
||||
/**
|
||||
* 系统部门导出
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<SysDepartExportVo> getExportDepart(int tenantId) {
|
||||
//获取父级部门
|
||||
List<SysDepartExportVo> parentDepart = departMapper.getSysDepartList("", tenantId);
|
||||
//子部门
|
||||
List<SysDepartExportVo> childrenDepart = new ArrayList<>();
|
||||
//把一级部门名称放在里面
|
||||
List<SysDepartExportVo> exportDepartVoList = new ArrayList<>();
|
||||
//存放部门一级id避免重复
|
||||
List<String> departIdList = new ArrayList<>();
|
||||
for (SysDepartExportVo sysDepart : parentDepart) {
|
||||
//step 1.添加第一级部门
|
||||
departIdList.add(sysDepart.getId());
|
||||
sysDepart.setDepartNameUrl(sysDepart.getDepartName());
|
||||
exportDepartVoList.add(sysDepart);
|
||||
//step 2.添加自己部门路径,用/分离
|
||||
//创建路径
|
||||
List<String> path = new ArrayList<>();
|
||||
path.add(sysDepart.getDepartName());
|
||||
//创建子部门路径
|
||||
findSysDepartPath(sysDepart, path, tenantId, childrenDepart, departIdList);
|
||||
path.clear();
|
||||
}
|
||||
exportDepartVoList.addAll(childrenDepart);
|
||||
childrenDepart.clear();
|
||||
departIdList.clear();
|
||||
return exportDepartVoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统部门导入
|
||||
* @param listSysDeparts
|
||||
* @param errorMessageList
|
||||
*/
|
||||
@Override
|
||||
public void importSysDepart(List<SysDepartExportVo> listSysDeparts, List<String> errorMessageList) {
|
||||
int num = 0;
|
||||
int tenantId = 0;
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
|
||||
}
|
||||
//部门路径排序
|
||||
Collections.sort(listSysDeparts, new Comparator<SysDepartExportVo>() {
|
||||
@Override
|
||||
public int compare(SysDepartExportVo o1, SysDepartExportVo o2) {
|
||||
if(oConvertUtils.isNotEmpty(o1.getDepartNameUrl()) && oConvertUtils.isNotEmpty(o2.getDepartNameUrl())){
|
||||
int oldLength = o1.getDepartNameUrl().split(SymbolConstant.SINGLE_SLASH).length;
|
||||
int newLength = o2.getDepartNameUrl().split(SymbolConstant.SINGLE_SLASH).length;
|
||||
return oldLength - newLength;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
//存放部门数据的map
|
||||
Map<String,SysDepart> departMap = new HashMap<>();
|
||||
// orgCode编码长度
|
||||
int codeLength = YouBianCodeUtil.ZHANWEI_LENGTH;
|
||||
//循环第二遍导入数据
|
||||
for (SysDepartExportVo departExportVo : listSysDeparts) {
|
||||
SysDepart sysDepart = new SysDepart();
|
||||
boolean izExport = false;
|
||||
try {
|
||||
izExport = this.addDepartByName(departExportVo.getDepartNameUrl(),departExportVo.getDepartName(),sysDepart,errorMessageList,tenantId,departMap,num);
|
||||
} catch (Exception e) {
|
||||
//没有查找到parentDept
|
||||
}
|
||||
//没有错误的时候才会导入数据
|
||||
if(izExport){
|
||||
if(oConvertUtils.isNotEmpty(departExportVo.getOrgCode())){
|
||||
SysDepart depart = this.baseMapper.queryCompByOrgCode(departExportVo.getOrgCode());
|
||||
if(null != depart){
|
||||
if(oConvertUtils.isNotEmpty(sysDepart.getParentId())){
|
||||
//更新上级部门为叶子节点
|
||||
this.updateIzLeaf(sysDepart.getParentId(),CommonConstant.IS_LEAF);
|
||||
}
|
||||
//部门名称已存在
|
||||
errorMessageList.add("第 " + num + " 行:记录部门名称“"+departExportVo.getDepartName()+"”部门编码重复,请检查!");
|
||||
continue;
|
||||
}
|
||||
String departNameUrl = departExportVo.getDepartNameUrl();
|
||||
//包含/说明是多级
|
||||
if(departNameUrl.contains(SymbolConstant.SINGLE_SLASH)){
|
||||
//判断添加部门的规则是否和生成的一致
|
||||
if(!sysDepart.getOrgCode().equals(departExportVo.getOrgCode())){
|
||||
if(oConvertUtils.isNotEmpty(sysDepart.getParentId())){
|
||||
//更新上级部门为叶子节点
|
||||
this.updateIzLeaf(sysDepart.getParentId(),CommonConstant.IS_LEAF);
|
||||
}
|
||||
//部门名称已存在
|
||||
errorMessageList.add("第 " + num + " 行:记录部门名称“"+departExportVo.getDepartName()+"”部门编码规则不匹配,请检查!");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
sysDepart.setOrgCode(departExportVo.getOrgCode());
|
||||
if(oConvertUtils.isNotEmpty(sysDepart.getParentId())){
|
||||
//上级
|
||||
sysDepart.setOrgType("2");
|
||||
}else{
|
||||
//下级
|
||||
sysDepart.setOrgType("1");
|
||||
}
|
||||
}else{
|
||||
sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
|
||||
}
|
||||
sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
sysDepart.setDepartNameEn(departExportVo.getDepartNameEn());
|
||||
sysDepart.setDepartOrder(departExportVo.getDepartOrder());
|
||||
sysDepart.setOrgCategory(oConvertUtils.getString(departExportVo.getOrgCategory(),"1"));
|
||||
sysDepart.setMobile(departExportVo.getMobile());
|
||||
sysDepart.setFax(departExportVo.getFax());
|
||||
sysDepart.setAddress(departExportVo.getAddress());
|
||||
sysDepart.setMemo(departExportVo.getMemo());
|
||||
ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
|
||||
departMap.put(departExportVo.getDepartNameUrl(),sysDepart);
|
||||
}
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 寻找部门路径
|
||||
*
|
||||
* @param departVo 部门vo
|
||||
* @param path 部门路径
|
||||
* @param tenantId 租户id
|
||||
* @param childrenDepart 子部门
|
||||
* @param departIdList 部门id集合
|
||||
*/
|
||||
private void findSysDepartPath(SysDepartExportVo departVo, List<String> path, Integer tenantId, List<SysDepartExportVo> childrenDepart, List<String> departIdList) {
|
||||
//step 1.查询子部门的数据
|
||||
//获取租户id和部门父id获取的部门数据
|
||||
List<SysDepartExportVo> departList = departMapper.getSysDepartList(departVo.getId(), tenantId);
|
||||
//部门为空判断
|
||||
if (departList == null || departList.size() <= 0) {
|
||||
//判断最后一个子部门是否已拼接
|
||||
if (!departIdList.contains(departVo.getId())) {
|
||||
departVo.setDepartNameUrl(String.join(SymbolConstant.SINGLE_SLASH, path));
|
||||
childrenDepart.add(departVo);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (SysDepartExportVo exportDepartVo : departList) {
|
||||
//存放子级路径
|
||||
List<String> cPath = new ArrayList<>(path);
|
||||
cPath.add(exportDepartVo.getDepartName());
|
||||
//step 2.拼接子部门路径
|
||||
if (!departIdList.contains(departVo.getId())) {
|
||||
departIdList.add(departVo.getId());
|
||||
departVo.setDepartNameUrl(String.join(SymbolConstant.SINGLE_SLASH, path));
|
||||
childrenDepart.add(departVo);
|
||||
}
|
||||
//step 3.递归查询子路径,直到找不到为止
|
||||
findSysDepartPath(exportDepartVo, cPath, tenantId, childrenDepart, departIdList);
|
||||
}
|
||||
}
|
||||
//========================end 系统下部门与人员导入 ==================================================================
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@ -326,15 +327,22 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> codeValues) {
|
||||
public List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> codeValues, String dataSource) {
|
||||
String str = table+","+text+","+code;
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
// 是否自定义数据源
|
||||
boolean isCustomDataSource = oConvertUtils.isNotEmpty(dataSource);
|
||||
// 如果是自定义数据源就不检查表字典白名单
|
||||
if (!isCustomDataSource) {
|
||||
// 【QQYUN-6533】表字典白名单check
|
||||
sysBaseAPI.dictTableWhiteListCheckByDict(table, text, code);
|
||||
// 1.表字典黑名单check
|
||||
if(!dictQueryBlackListHandler.isPass(str)){
|
||||
if (!dictQueryBlackListHandler.isPass(str)) {
|
||||
log.error(dictQueryBlackListHandler.getError());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
// 2.分割SQL获取表名和条件
|
||||
String filterSql = null;
|
||||
@ -353,7 +361,18 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
text = SqlInjectionUtil.getSqlInjectField(text);
|
||||
code = SqlInjectionUtil.getSqlInjectField(code);
|
||||
|
||||
return sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, codeValues);
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
// 切换为字典表的数据源
|
||||
if (isCustomDataSource) {
|
||||
DynamicDataSourceContextHolder.push(dataSource);
|
||||
}
|
||||
List<DictModel> restData = sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, codeValues);
|
||||
// 清理自定义的数据源
|
||||
if (isCustomDataSource) {
|
||||
DynamicDataSourceContextHolder.clear();
|
||||
}
|
||||
return restData;
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
//update-end-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件
|
||||
}
|
||||
|
||||
|
||||
@ -128,11 +128,19 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
||||
|
||||
@Override
|
||||
public void addDefaultTenantPack(Integer tenantId) {
|
||||
LambdaQueryWrapper<SysTenantPack> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysTenantPack::getTenantId,tenantId);
|
||||
// 创建超级管理员
|
||||
SysTenantPack superAdminPack = new SysTenantPack(tenantId, "超级管理员", TenantConstant.SUPER_ADMIN);
|
||||
ISysTenantPackService currentService = SpringContextUtils.getApplicationContext().getBean(ISysTenantPackService.class);
|
||||
String packId = currentService.saveOne(superAdminPack);
|
||||
|
||||
query.eq(SysTenantPack::getPackCode, TenantConstant.SUPER_ADMIN);
|
||||
SysTenantPack sysTenantPackSuperAdmin = currentService.getOne(query);
|
||||
String packId = "";
|
||||
if(null == sysTenantPackSuperAdmin){
|
||||
packId = currentService.saveOne(superAdminPack);
|
||||
}else{
|
||||
packId = sysTenantPackSuperAdmin.getId();
|
||||
}
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
SysTenantPackUser packUser = new SysTenantPackUser(tenantId, packId, sysUser.getId());
|
||||
packUser.setRealname(sysUser.getRealname());
|
||||
@ -140,13 +148,22 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
||||
//添加人员和管理员的关系数据
|
||||
currentService.savePackUser(packUser);
|
||||
|
||||
query.eq(SysTenantPack::getPackCode, TenantConstant.ACCOUNT_ADMIN);
|
||||
SysTenantPack sysTenantPackAccountAdmin = currentService.getOne(query);
|
||||
if(null == sysTenantPackAccountAdmin){
|
||||
// 创建超级管理员
|
||||
SysTenantPack accountAdminPack = new SysTenantPack(tenantId, "组织账户管理员", TenantConstant.ACCOUNT_ADMIN);
|
||||
currentService.saveOne(accountAdminPack);
|
||||
}
|
||||
|
||||
query.eq(SysTenantPack::getPackCode, TenantConstant.APP_ADMIN);
|
||||
SysTenantPack sysTenantPackAppAdmin = currentService.getOne(query);
|
||||
|
||||
if(null == sysTenantPackAppAdmin){
|
||||
// 创建超级管理员
|
||||
SysTenantPack appAdminPack = new SysTenantPack(tenantId, "组织应用管理员", TenantConstant.APP_ADMIN);
|
||||
currentService.saveOne(appAdminPack);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -156,7 +156,7 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
sysTenantPackService.addDefaultTenantPack(tenantId);
|
||||
|
||||
//添加租户到关系表
|
||||
return this.saveTenantRelation(sysTenant.getId(), userId);
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -164,6 +164,7 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
//获取租户id
|
||||
sysTenant.setId(this.tenantIdGenerate());
|
||||
sysTenant.setHouseNumber(RandomUtil.randomStringUpper(6));
|
||||
sysTenant.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
this.save(sysTenant);
|
||||
//update-begin---author:wangshuai ---date:20230710 for:【QQYUN-5723】1、把当前创建人加入到租户关系里面------------
|
||||
//当前登录人的id
|
||||
@ -680,6 +681,9 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
messageDTO.setData(data);
|
||||
messageDTO.setContent(title);
|
||||
messageDTO.setType("system");
|
||||
//update-begin---author:wangshuai---date:2023-11-24---for:【QQYUN-7168】邀请成员时,会报错,但实际已经邀请成功了---
|
||||
messageDTO.setCategory(CommonConstant.MSG_CATEGORY_1);
|
||||
//update-end---author:wangshuai---date:2023-11-24---for:【QQYUN-7168】邀请成员时,会报错,但实际已经邀请成功了---
|
||||
//update-begin---author:wangshuai ---date:20230721 for:【QQYUN-5726】邀请加入租户加个按钮直接跳转过去------------
|
||||
messageDTO.setBusType(SysAnnmentTypeEnum.TENANT_INVITE.getType());
|
||||
sysBaseApi.sendBusAnnouncement(messageDTO);
|
||||
|
||||
@ -62,6 +62,8 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
//修改第三方登录账户表使其进行添加用户id
|
||||
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysThirdAccount::getThirdUserUuid,thirdUserUuid);
|
||||
//扫码登录更新用户创建的时候存的是默认租户,更新的时候也需要根据默认租户来查询,同一个公司下UUID是一样的,不同应用需要区分租户。
|
||||
query.eq(SysThirdAccount::getTenantId,CommonConstant.TENANT_ID_DEFAULT_VALUE);
|
||||
SysThirdAccount account = sysThirdAccountMapper.selectOne(query);
|
||||
SysThirdAccount sysThirdAccount = new SysThirdAccount();
|
||||
sysThirdAccount.setSysUserId(sysUser.getId());
|
||||
@ -189,7 +191,7 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
//获取当前登录用户
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
//当前第三方用户已被其他用户所绑定
|
||||
SysThirdAccount oneByThirdUserId = this.getOneByUuidAndThirdType(thirdUserUuid, thirdType,CommonConstant.TENANT_ID_DEFAULT_VALUE);
|
||||
SysThirdAccount oneByThirdUserId = this.getOneByUuidAndThirdType(thirdUserUuid, thirdType,CommonConstant.TENANT_ID_DEFAULT_VALUE, null);
|
||||
if(null != oneByThirdUserId){
|
||||
//如果不为空,并且第三方表和当前登录的用户一致,直接返回
|
||||
if(oConvertUtils.isNotEmpty(oneByThirdUserId.getSysUserId()) && oneByThirdUserId.getSysUserId().equals(sysUser.getId())){
|
||||
@ -210,10 +212,16 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysThirdAccount getOneByUuidAndThirdType(String unionid, String thirdType,Integer tenantId) {
|
||||
public SysThirdAccount getOneByUuidAndThirdType(String unionid, String thirdType,Integer tenantId,String thirdUserId) {
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getThirdUserUuid, unionid);
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, thirdType);
|
||||
//update-begin---author:wangshuai---date:2023-12-04---for: 如果第三方用户id为空那么就不走第三方用户查询逻辑,因为扫码登录third_user_id是唯一的,没有重复的情况---
|
||||
if(oConvertUtils.isNotEmpty(thirdUserId)){
|
||||
queryWrapper.and((wrapper) ->wrapper.eq(SysThirdAccount::getThirdUserUuid,unionid).or().eq(SysThirdAccount::getThirdUserId,thirdUserId));
|
||||
}else{
|
||||
queryWrapper.eq(SysThirdAccount::getThirdUserUuid, unionid);
|
||||
}
|
||||
//update-end---author:wangshuai---date:2023-12-04---for:如果第三方用户id为空那么就不走第三方用户查询逻辑,因为扫码登录third_user_id是唯一的,没有重复的情况---
|
||||
queryWrapper.eq(SysThirdAccount::getTenantId, tenantId);
|
||||
return super.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
@ -143,8 +143,19 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param departId
|
||||
* @param username
|
||||
* @param realname
|
||||
* @param pageSize
|
||||
* @param pageNo
|
||||
* @param id
|
||||
* @param isMultiTranslate 是否多字段翻译
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id) {
|
||||
public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id,String isMultiTranslate) {
|
||||
IPage<SysUser> pageList = null;
|
||||
// 部门ID不存在 直接查询用户表即可
|
||||
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
|
||||
@ -153,9 +164,17 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
//update-begin---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
|
||||
//update-end---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
//update-begin---author:liusq ---date:20231215 for:逗号分割多个用户翻译问题------------
|
||||
if(oConvertUtils.isNotEmpty(username)){
|
||||
String COMMA = ",";
|
||||
if(oConvertUtils.isNotEmpty(isMultiTranslate) && username.contains(COMMA)){
|
||||
String[] usernameArr = username.split(COMMA);
|
||||
query.in(SysUser::getUsername,usernameArr);
|
||||
}else {
|
||||
query.like(SysUser::getUsername, username);
|
||||
}
|
||||
}
|
||||
//update-end---author:liusq ---date:20231215 for:逗号分割多个用户翻译问题------------
|
||||
//update-begin---author:wangshuai ---date:20220608 for:[VUEN-1238]邮箱回复时,发送到显示的为用户id------------
|
||||
if(oConvertUtils.isNotEmpty(id)){
|
||||
query.eq(SysUser::getId, id);
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
@ -120,6 +118,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
private SysPositionMapper sysPositionMapper;
|
||||
@Autowired
|
||||
private SystemSendMsgHandle systemSendMsgHandle;
|
||||
|
||||
@Autowired
|
||||
private ISysThirdAccountService sysThirdAccountService;
|
||||
|
||||
@ -178,8 +177,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
} else {
|
||||
item.setRelTenantIds("");
|
||||
}
|
||||
Integer posTenantId = null;
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
posTenantId = tenantId;
|
||||
}
|
||||
//查询用户职位关系表(获取租户下面的)
|
||||
List<String> positionList = sysUserPositionMapper.getPositionIdByUserTenantId(item.getId(),tenantId);
|
||||
//update-begin---author:wangshuai---date:2023-11-15---for:【QQYUN-7028】用户职务保存后未回显---
|
||||
List<String> positionList = sysUserPositionMapper.getPositionIdByUserTenantId(item.getId(),posTenantId);
|
||||
//update-end---author:wangshuai---date:2023-11-15---for:【QQYUN-7028】用户职务保存后未回显---
|
||||
//update-end---author:wangshuai ---date:20230228 for:[QQYUN-4354]加入更多字段:当前加入时间应该取当前租户的/职位也是当前租户下的------------
|
||||
item.setPost(CommonUtils.getSplitText(positionList,SymbolConstant.COMMA));
|
||||
|
||||
@ -828,6 +833,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
SysUserTenant userTenant = new SysUserTenant();
|
||||
userTenant.setStatus(CommonConstant.USER_TENANT_QUIT);
|
||||
userTenantMapper.update(userTenant,query);
|
||||
//update-end---author:wangshuai ---date:20230111 for:[QQYUN-3951]租户用户离职重构------------
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -929,8 +935,18 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
relation.setUserId(userId);
|
||||
relation.setTenantId(Integer.valueOf(tenantId));
|
||||
relation.setStatus(CommonConstant.STATUS_1);
|
||||
|
||||
LambdaQueryWrapper sysUserTenantQueryWrapper = new LambdaQueryWrapper<SysUserTenant>()
|
||||
.eq(SysUserTenant::getUserId, userId)
|
||||
.eq(SysUserTenant::getTenantId,Integer.valueOf(tenantId));
|
||||
SysUserTenant tenantPresent = relationMapper.selectOne(sysUserTenantQueryWrapper);
|
||||
if (tenantPresent != null) {
|
||||
tenantPresent.setStatus(CommonConstant.STATUS_1);
|
||||
relationMapper.updateById(tenantPresent);
|
||||
}else{
|
||||
relationMapper.insert(relation);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
@ -960,7 +976,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
LambdaQueryWrapper<SysUserTenant> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysUserTenant::getUserId, userId);
|
||||
//数据库的租户id
|
||||
List<Integer> oldTenantIds = relationMapper.getTenantIdsNoStatus(userId);
|
||||
List<Integer> oldTenantIds = relationMapper.getTenantIdsByUserId(userId);
|
||||
//如果传过来的租户id为空,那么就删除租户
|
||||
if (oConvertUtils.isEmpty(relTenantIds) && CollectionUtils.isNotEmpty(oldTenantIds)) {
|
||||
this.deleteTenantByUserId(userId, null);
|
||||
|
||||
@ -15,6 +15,7 @@ import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysTenant;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.entity.SysUserTenant;
|
||||
import org.jeecg.modules.system.mapper.SysTenantPackUserMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserPositionMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserTenantMapper;
|
||||
@ -53,6 +54,9 @@ public class SysUserTenantServiceImpl extends ServiceImpl<SysUserTenantMapper, S
|
||||
@Autowired
|
||||
private SysUserPositionMapper userPositionMapper;
|
||||
|
||||
@Autowired
|
||||
private SysTenantPackUserMapper packUserMapper;
|
||||
|
||||
@Override
|
||||
public Page<SysUser> getPageUserList(Page<SysUser> page, Integer userTenantId, SysUser user) {
|
||||
return page.setRecords(userTenantMapper.getPageUserList(page,userTenantId,user));
|
||||
@ -162,7 +166,6 @@ public class SysUserTenantServiceImpl extends ServiceImpl<SysUserTenantMapper, S
|
||||
return userTenantMapper.userTenantIzExist(userId,tenantId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IPage<SysTenant> getTenantPageListByUserId(Page<SysTenant> page, String userId, List<String> userTenantStatus,SysUserTenantVo sysUserTenantVo) {
|
||||
return page.setRecords(userTenantMapper.getTenantPageListByUserId(page,userId,userTenantStatus,sysUserTenantVo));
|
||||
@ -183,4 +186,9 @@ public class SysUserTenantServiceImpl extends ServiceImpl<SysUserTenantMapper, S
|
||||
public SysUserTenant getUserTenantByTenantId(String userId, Integer tenantId) {
|
||||
return userTenantMapper.getUserTenantByTenantId(userId,tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getUserCount(Integer tenantId, String tenantStatus) {
|
||||
return userTenantMapper.getUserCount(tenantId,tenantStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
@ -983,6 +984,7 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
* OAuth2登录,成功返回登录的SysUser,失败返回null
|
||||
*/
|
||||
public SysUser oauth2Login(String authCode,Integer tenantId) {
|
||||
this.tenantIzExist(tenantId);
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
SysThirdAppConfig dtConfig = configMapper.getThirdConfigByThirdType(tenantId, MessageTypeEnum.DD.getType());
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
@ -1017,7 +1019,9 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, THIRD_TYPE);
|
||||
queryWrapper.eq(SysThirdAccount::getTenantId, tenantId);
|
||||
queryWrapper.eq(SysThirdAccount::getThirdUserUuid, unionId);
|
||||
//update-begin---author:wangshuai---date:2023-12-04---for: auth登录需要联查一下---
|
||||
queryWrapper.and((wrapper)->wrapper.eq(SysThirdAccount::getThirdUserUuid,appUserId).or().eq(SysThirdAccount::getThirdUserId,appUserId));
|
||||
//update-end---author:wangshuai---date:2023-12-04---for: auth登录需要联查一下---
|
||||
SysThirdAccount thirdAccount = sysThirdAccountService.getOne(queryWrapper);
|
||||
if (thirdAccount != null) {
|
||||
return this.getSysUserByThird(thirdAccount, null, appUserId, accessToken,tenantId);
|
||||
@ -1082,6 +1086,7 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
*/
|
||||
private SysThirdAppConfig getDingThirdAppConfig(){
|
||||
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
|
||||
this.tenantIzExist(tenantId);
|
||||
return configMapper.getThirdConfigByThirdType(tenantId,MessageTypeEnum.DD.getType());
|
||||
}
|
||||
|
||||
@ -1164,7 +1169,7 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
}
|
||||
syncedUserIdSet.add(user.getUserid());
|
||||
SysUser userByPhone = userMapper.getUserByPhone(user.getMobile());
|
||||
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneByUuidAndThirdType(user.getUnionid(), THIRD_TYPE,tenantId);
|
||||
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneByUuidAndThirdType(user.getUnionid(), THIRD_TYPE,tenantId,user.getUserid());
|
||||
if (null != userByPhone) {
|
||||
// 循环到此说明用户匹配成功,进行更新操作
|
||||
SysUser updateSysUser = this.dtUserToSysUser(user, userByPhone);
|
||||
@ -1220,4 +1225,17 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
}
|
||||
|
||||
//========================end 应用低代码钉钉同步用户部门专用 ====================
|
||||
|
||||
/**
|
||||
* 验证租户是否存在
|
||||
* @param tenantId
|
||||
*/
|
||||
public void tenantIzExist(Integer tenantId){
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
Long count = tenantMapper.tenantIzExist(tenantId);
|
||||
if(ObjectUtil.isEmpty(count) || 0 == count){
|
||||
throw new JeecgBootException("租户不存在!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
@ -28,20 +30,21 @@ import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.PasswordUtil;
|
||||
import org.jeecg.common.util.RestUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
|
||||
import org.jeecg.modules.system.mapper.SysThirdAppConfigMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.jeecg.modules.system.mapper.*;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.model.ThirdLoginModel;
|
||||
import org.jeecg.modules.system.service.*;
|
||||
import org.jeecg.modules.system.vo.thirdapp.JwDepartmentTreeVo;
|
||||
import org.jeecg.modules.system.vo.thirdapp.JwSysUserDepartVo;
|
||||
import org.jeecg.modules.system.vo.thirdapp.JwUserDepartVo;
|
||||
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -50,6 +53,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -76,6 +80,15 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
private SysAnnouncementSendMapper sysAnnouncementSendMapper;
|
||||
@Autowired
|
||||
private SysThirdAppConfigMapper configMapper;
|
||||
@Autowired
|
||||
private SysTenantMapper sysTenantMapper;
|
||||
@Autowired
|
||||
private SysUserTenantMapper sysUserTenantMapper;
|
||||
@Autowired
|
||||
private SysThirdAccountMapper sysThirdAccountMapper;
|
||||
@Autowired
|
||||
private SysTenantMapper tenantMapper;
|
||||
|
||||
|
||||
/**
|
||||
* errcode
|
||||
@ -235,82 +248,85 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public SyncInfoVo syncThirdAppDepartmentToLocal(String ids) {
|
||||
// SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
// String accessToken = this.getAccessToken();
|
||||
// if (accessToken == null) {
|
||||
// syncInfo.addFailInfo("accessToken获取失败!");
|
||||
// return syncInfo;
|
||||
// }
|
||||
// // 获取企业微信所有的部门
|
||||
// List<Department> departments = JwDepartmentAPI.getAllDepartment(accessToken);
|
||||
// if (departments == null) {
|
||||
// syncInfo.addFailInfo("企业微信部门信息获取失败!");
|
||||
// return syncInfo;
|
||||
// }
|
||||
// String username = JwtUtil.getUserNameByToken(SpringContextUtils.getHttpServletRequest());
|
||||
// // 将list转为tree
|
||||
// List<JwDepartmentTreeVo> departmentTreeList = JwDepartmentTreeVo.listToTree(departments);
|
||||
// // 递归同步部门
|
||||
// this.syncDepartmentToLocalRecursion(departmentTreeList, null, username, syncInfo);
|
||||
// return syncInfo;
|
||||
// }
|
||||
public SyncInfoVo syncThirdAppDepartmentToLocal(Integer tenantId, Map<String,String> map) {
|
||||
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
syncInfo.addFailInfo("accessToken获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
// 获取企业微信所有的部门
|
||||
List<Department> departments = JwDepartmentAPI.getAllDepartment(accessToken);
|
||||
if (departments == null) {
|
||||
syncInfo.addFailInfo("企业微信部门信息获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
String username = JwtUtil.getUserNameByToken(SpringContextUtils.getHttpServletRequest());
|
||||
// 将list转为tree
|
||||
List<JwDepartmentTreeVo> departmentTreeList = JwDepartmentTreeVo.listToTree(departments);
|
||||
// 递归同步部门
|
||||
this.syncDepartmentToLocalRecursion(departmentTreeList, null, username, syncInfo, tenantId, map);
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 递归同步部门到本地
|
||||
// */
|
||||
// private void syncDepartmentToLocalRecursion(List<JwDepartmentTreeVo> departmentTreeList, String sysParentId, String username, SyncInfoVo syncInfo) {
|
||||
// if (departmentTreeList != null && departmentTreeList.size() != 0) {
|
||||
// for (JwDepartmentTreeVo departmentTree : departmentTreeList) {
|
||||
// String depId = departmentTree.getId();
|
||||
// LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// // 根据 qywxIdentifier 字段查询
|
||||
// queryWrapper.eq(SysDepart::getQywxIdentifier, depId);
|
||||
// SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
|
||||
// if (sysDepart != null) {
|
||||
// // 执行更新操作
|
||||
// SysDepart updateSysDepart = this.qwDepartmentToSysDepart(departmentTree, sysDepart);
|
||||
// if (sysParentId != null) {
|
||||
// updateSysDepart.setParentId(sysParentId);
|
||||
// }
|
||||
// try {
|
||||
// sysDepartService.updateDepartDataById(updateSysDepart, username);
|
||||
// String str = String.format("部门 %s 更新成功!", updateSysDepart.getDepartName());
|
||||
// syncInfo.addSuccessInfo(str);
|
||||
// } catch (Exception e) {
|
||||
// this.syncDepartCollectErrInfo(e, departmentTree, syncInfo);
|
||||
// }
|
||||
// if (departmentTree.hasChildren()) {
|
||||
// // 紧接着同步子级
|
||||
// this.syncDepartmentToLocalRecursion(departmentTree.getChildren(), updateSysDepart.getId(), username, syncInfo);
|
||||
// }
|
||||
// } else {
|
||||
// // 执行新增操作
|
||||
// SysDepart newSysDepart = this.qwDepartmentToSysDepart(departmentTree, null);
|
||||
// if (sysParentId != null) {
|
||||
// newSysDepart.setParentId(sysParentId);
|
||||
// // 2 = 组织机构
|
||||
// newSysDepart.setOrgCategory("2");
|
||||
// } else {
|
||||
// // 1 = 公司
|
||||
// newSysDepart.setOrgCategory("1");
|
||||
// }
|
||||
// try {
|
||||
// sysDepartService.saveDepartData(newSysDepart, username);
|
||||
// String str = String.format("部门 %s 创建成功!", newSysDepart.getDepartName());
|
||||
// syncInfo.addSuccessInfo(str);
|
||||
// } catch (Exception e) {
|
||||
// this.syncDepartCollectErrInfo(e, departmentTree, syncInfo);
|
||||
// }
|
||||
// // 紧接着同步子级
|
||||
// if (departmentTree.hasChildren()) {
|
||||
// this.syncDepartmentToLocalRecursion(departmentTree.getChildren(), newSysDepart.getId(), username, syncInfo);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
/**
|
||||
* 递归同步部门到本地
|
||||
*/
|
||||
private void syncDepartmentToLocalRecursion(List<JwDepartmentTreeVo> departmentTreeList, String sysParentId, String username, SyncInfoVo syncInfo,Integer tenantId, Map<String,String> map) {
|
||||
if (departmentTreeList != null && departmentTreeList.size() != 0) {
|
||||
for (JwDepartmentTreeVo departmentTree : departmentTreeList) {
|
||||
String depId = departmentTree.getId();
|
||||
LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// 根据 qywxIdentifier 字段和租户id查询,租户id默认为0
|
||||
queryWrapper.eq(SysDepart::getQywxIdentifier, depId);
|
||||
queryWrapper.eq(SysDepart::getTenantId, tenantId);
|
||||
SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
|
||||
if (sysDepart != null) {
|
||||
// 执行更新操作
|
||||
SysDepart updateSysDepart = this.qwDepartmentToSysDepart(departmentTree, sysDepart);
|
||||
if (sysParentId != null) {
|
||||
updateSysDepart.setParentId(sysParentId);
|
||||
}
|
||||
try {
|
||||
sysDepartService.updateDepartDataById(updateSysDepart, username);
|
||||
String str = String.format("部门 %s 更新成功!", updateSysDepart.getDepartName());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
map.put(depId,updateSysDepart.getId());
|
||||
} catch (Exception e) {
|
||||
this.syncDepartCollectErrInfo(e, departmentTree, syncInfo);
|
||||
}
|
||||
if (departmentTree.hasChildren()) {
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentToLocalRecursion(departmentTree.getChildren(), updateSysDepart.getId(), username, syncInfo, tenantId, map);
|
||||
}
|
||||
} else {
|
||||
// 执行新增操作
|
||||
SysDepart newSysDepart = this.qwDepartmentToSysDepart(departmentTree, null);
|
||||
if (sysParentId != null) {
|
||||
newSysDepart.setParentId(sysParentId);
|
||||
// 2 = 组织机构
|
||||
newSysDepart.setOrgCategory("2");
|
||||
} else {
|
||||
// 1 = 公司
|
||||
newSysDepart.setOrgCategory("1");
|
||||
}
|
||||
newSysDepart.setTenantId(tenantId);
|
||||
try {
|
||||
sysDepartService.saveDepartData(newSysDepart, username);
|
||||
String str = String.format("部门 %s 创建成功!", newSysDepart.getDepartName());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
map.put(depId,newSysDepart.getId());
|
||||
} catch (Exception e) {
|
||||
this.syncDepartCollectErrInfo(e, departmentTree, syncInfo);
|
||||
}
|
||||
// 紧接着同步子级
|
||||
if (departmentTree.hasChildren()) {
|
||||
this.syncDepartmentToLocalRecursion(departmentTree.getChildren(), newSysDepart.getId(), username, syncInfo, tenantId, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncInfoVo syncLocalUserToThirdApp(String ids) {
|
||||
@ -374,7 +390,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
int errCode = JwUserAPI.updateUser(qwUser, accessToken);
|
||||
// 收集错误信息
|
||||
this.syncUserCollectErrInfo(errCode, sysUser, syncInfo);
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount, sysUser.getId(), qwUser.getUserid());
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount, sysUser.getId(), qwUser.getUserid(),qwUser.getName());
|
||||
// 更新完成,直接跳到下一次外部循环继续
|
||||
continue for1;
|
||||
}
|
||||
@ -384,7 +400,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
// 收集错误信息
|
||||
boolean apiSuccess = this.syncUserCollectErrInfo(errCode, sysUser, syncInfo);
|
||||
if (apiSuccess) {
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount, sysUser.getId(), qwUser.getUserid());
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount, sysUser.getId(), qwUser.getUserid(),qwUser.getName());
|
||||
}
|
||||
}
|
||||
return syncInfo;
|
||||
@ -453,8 +469,9 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
* @param sysThirdAccount 第三方账户表对象,为null就新增数据,否则就修改
|
||||
* @param sysUserId 本地系统用户ID
|
||||
* @param qwUserId 企业微信用户ID
|
||||
* @param wechatRealName 企业微信用户真实姓名
|
||||
*/
|
||||
private void thirdAccountSaveOrUpdate(SysThirdAccount sysThirdAccount, String sysUserId, String qwUserId) {
|
||||
private void thirdAccountSaveOrUpdate(SysThirdAccount sysThirdAccount, String sysUserId, String qwUserId, String wechatRealName) {
|
||||
if (sysThirdAccount == null) {
|
||||
sysThirdAccount = new SysThirdAccount();
|
||||
sysThirdAccount.setSysUserId(sysUserId);
|
||||
@ -463,6 +480,8 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
sysThirdAccount.setThirdType(THIRD_TYPE);
|
||||
}
|
||||
sysThirdAccount.setThirdUserId(qwUserId);
|
||||
sysThirdAccount.setThirdUserUuid(qwUserId);
|
||||
sysThirdAccount.setRealname(wechatRealName);
|
||||
sysThirdAccountService.saveOrUpdate(sysThirdAccount);
|
||||
}
|
||||
|
||||
@ -919,6 +938,10 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
* OAuth2登录,成功返回登录的SysUser,失败返回null
|
||||
*/
|
||||
public SysUser oauth2Login(String code,Integer tenantId) {
|
||||
Long count = tenantMapper.tenantIzExist(tenantId);
|
||||
if(ObjectUtil.isEmpty(count) || 0 == count){
|
||||
throw new JeecgBootException("租户不存在!");
|
||||
}
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
SysThirdAppConfig config = configMapper.getThirdConfigByThirdType(tenantId, MessageTypeEnum.QYWX.getType());
|
||||
String accessToken = this.getAppAccessToken(config);
|
||||
@ -933,19 +956,14 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
String userTicket = map.get("userTicket");
|
||||
// 判断第三方用户表有没有这个人
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getThirdUserUuid, appUserId);
|
||||
queryWrapper.or().eq(SysThirdAccount::getThirdUserId, appUserId);
|
||||
queryWrapper.eq(SysThirdAccount::getThirdUserId, appUserId);
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, THIRD_TYPE);
|
||||
queryWrapper.eq(SysThirdAccount::getTenantId, tenantId);
|
||||
SysThirdAccount thirdAccount = sysThirdAccountService.getOne(queryWrapper);
|
||||
if (thirdAccount != null) {
|
||||
return this.getSysUserByThird(thirdAccount, null, appUserId, accessToken, userTicket,tenantId);
|
||||
} else {
|
||||
// 直接创建新账号
|
||||
User appUser = this.getUserByUserTicket(userTicket, accessToken);
|
||||
ThirdLoginModel tlm = new ThirdLoginModel(THIRD_TYPE, appUser.getUserid(), appUser.getName(), appUser.getAvatar());
|
||||
thirdAccount = sysThirdAccountService.saveThirdUser(tlm,tenantId);
|
||||
return this.getSysUserByThird(thirdAccount, appUser, null, null, userTicket,tenantId);
|
||||
throw new JeecgBootException("该用户尚未同步,请同步后再次登录!");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -1032,4 +1050,242 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业微信绑定的用户信息
|
||||
* @return
|
||||
*/
|
||||
public JwSysUserDepartVo getThirdUserByWechat(Integer tenantId) {
|
||||
JwSysUserDepartVo sysUserDepartVo = new JwSysUserDepartVo();
|
||||
//step1 获取用户id和部门id
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
throw new JeecgBootException("accessToken获取失败!");
|
||||
}
|
||||
//获取当前租户下的用户
|
||||
List<JwUserDepartVo> userList = sysUserTenantMapper.getUsersByTenantIdAndName(tenantId);
|
||||
// 获取企业微信所有的用户(只能获取userid)
|
||||
List<User> qwUsers = JwUserAPI.getUsersByDepartid("1","1",null,accessToken);
|
||||
if(oConvertUtils.isEmpty(qwUsers)){
|
||||
throw new JeecgBootException("企业微信下没查询到用户!");
|
||||
}
|
||||
List<String> userIds = new ArrayList<>();
|
||||
List<JwUserDepartVo> userWechatList = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < qwUsers.size(); i++) {
|
||||
User user = qwUsers.get(i);
|
||||
String userId = qwUsers.get(i).getUserid();
|
||||
//保证用户唯一
|
||||
if(!userIds.contains(userId)){
|
||||
//step2 查看是否已经同步过了,同步过的不做处理
|
||||
SysThirdAccount oneBySysUserId = sysThirdAccountService.getOneByUuidAndThirdType(userId, THIRD_TYPE,tenantId, userId);
|
||||
if(null != oneBySysUserId){
|
||||
userIds.add(qwUsers.get(i).getUserid());
|
||||
userList = userList.stream().filter(item -> !item.getUserId().equals(oneBySysUserId.getSysUserId())).collect(Collectors.toList());;
|
||||
continue;
|
||||
}
|
||||
AtomicBoolean excludeUser = new AtomicBoolean(false);
|
||||
if(ObjectUtil.isNotEmpty(qwUsers)){
|
||||
//step3 通过名称匹配敲敲云
|
||||
userList.forEach(item ->{
|
||||
if(item.getRealName().equals(user.getName())){
|
||||
item.setWechatUserId(user.getUserid());
|
||||
item.setWechatRealName(user.getName());
|
||||
if(ObjectUtil.isNotEmpty(user.getDepartment())){
|
||||
item.setWechatDepartId(Arrays.toString(user.getDepartment()));
|
||||
}
|
||||
excludeUser.set(true);
|
||||
}
|
||||
});
|
||||
userIds.add(user.getUserid());
|
||||
}
|
||||
if(!excludeUser.get()){
|
||||
JwUserDepartVo userDepartVo = new JwUserDepartVo();
|
||||
userDepartVo.setWechatRealName(user.getName());
|
||||
userDepartVo.setWechatUserId(user.getUserid());
|
||||
if(ObjectUtil.isNotEmpty(user.getDepartment())){
|
||||
userDepartVo.setWechatDepartId(Arrays.toString(user.getDepartment()));
|
||||
}
|
||||
userWechatList.add(userDepartVo);
|
||||
}
|
||||
}
|
||||
}
|
||||
//step4 返回用户信息
|
||||
sysUserDepartVo.setUserList(userWechatList);
|
||||
sysUserDepartVo.setJwUserDepartVos(userList);
|
||||
return sysUserDepartVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步企业微信和部门
|
||||
* @param jwUserDepartJson
|
||||
* @return
|
||||
*/
|
||||
public SyncInfoVo syncWechatEnterpriseDepartAndUserToLocal(String jwUserDepartJson, Integer tenantId) {
|
||||
//step 1 同步部门
|
||||
//存放部门id的map
|
||||
Map<String,String> idsMap = new HashMap<>();
|
||||
SyncInfoVo syncInfoVo = this.syncThirdAppDepartmentToLocal(tenantId, idsMap);
|
||||
//step 2 同步用户及用户部门
|
||||
this.syncDepartAndUser(syncInfoVo, tenantId, idsMap, jwUserDepartJson);
|
||||
//step 3 返回同步成功或者同步失败的消息
|
||||
return syncInfoVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步用户和部门
|
||||
* @param syncInfoVo 存放错误信息的日志
|
||||
* @param tenantId 租户id
|
||||
* @param idsMap 部门id集合 key为企业微信的id value 为系统部门的id
|
||||
* @param jwUserDepartJson
|
||||
*/
|
||||
private void syncDepartAndUser(SyncInfoVo syncInfoVo, Integer tenantId, Map<String, String> idsMap, String jwUserDepartJson) {
|
||||
if (oConvertUtils.isNotEmpty(jwUserDepartJson)) {
|
||||
JSONArray jsonArray = JSONObject.parseArray(jwUserDepartJson);
|
||||
for (Object object : jsonArray) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(object.toString());
|
||||
Object userId = jsonObject.get("userId");
|
||||
String wechatUserId = jsonObject.getString("wechatUserId");
|
||||
String wechatRealName = jsonObject.getString("wechatRealName");
|
||||
Object wechatDepartId = jsonObject.get("wechatDepartId");
|
||||
String sysUserId = "";
|
||||
//step 1 新建或更新用户
|
||||
//用户id为空说明需要创建用户
|
||||
if (null == userId) {
|
||||
SysTenant sysTenant = sysTenantMapper.selectById(tenantId);
|
||||
String houseNumber = "";
|
||||
//空说明没有租户直接用用户名
|
||||
if (null != sysTenant) {
|
||||
houseNumber = sysTenant.getHouseNumber();
|
||||
}
|
||||
//用户名和密码用门牌号+用户id的格式,避免用户名重复
|
||||
String username = houseNumber + wechatUserId;
|
||||
//新建用户
|
||||
sysUserId = this.saveUser(username, wechatRealName, syncInfoVo, wechatUserId);
|
||||
} else {
|
||||
//根据id查询用户
|
||||
SysUser sysUser = userMapper.selectById(userId.toString());
|
||||
if (null != sysUser) {
|
||||
sysUserId = sysUser.getId();
|
||||
//如果真实姓名为空的情况下,才会改真实姓名
|
||||
if(oConvertUtils.isEmpty(sysUser.getRealname())){
|
||||
sysUser.setRealname(wechatRealName);
|
||||
//更新用户
|
||||
userMapper.updateById(sysUser);
|
||||
}
|
||||
String str = String.format("用户 %s(%s) 更新成功!", sysUser.getRealname(), sysUser.getUsername());
|
||||
syncInfoVo.addSuccessInfo(str);
|
||||
}else{
|
||||
syncInfoVo.addFailInfo("企业微信用户 "+wechatRealName+" 对应的组织用户没有匹配到!");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(sysUserId)) {
|
||||
//step 2 新增租户用户表
|
||||
this.createUserTenant(sysUserId,false,tenantId);
|
||||
//step 3 新建或更新第三方账号表
|
||||
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneByUuidAndThirdType(wechatUserId, THIRD_TYPE, tenantId, wechatUserId);
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount,sysUserId,wechatUserId,wechatRealName);
|
||||
//step 4 新建或更新用户部门关系表
|
||||
if(oConvertUtils.isNotEmpty(wechatDepartId)){
|
||||
String wechatDepartIds = wechatDepartId.toString();
|
||||
String[] departIds = wechatDepartIds.substring(1, wechatDepartIds.length() - 1).split(",");
|
||||
this.userDepartSaveOrUpdate(idsMap,sysUserId,departIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
syncInfoVo.addFailInfo("用户同同步失败,请查看企业微信是否存在用户!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param wechatRealName 企业微信用户真实姓名
|
||||
* @param syncInfo 存放成功或失败的信息
|
||||
* @param wechatUserId wechatUserId 企业微信对应的id
|
||||
* @return
|
||||
*/
|
||||
private String saveUser(String username, String wechatRealName, SyncInfoVo syncInfo, String wechatUserId) {
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setRealname(wechatRealName);
|
||||
sysUser.setPassword(username);
|
||||
sysUser.setUsername(username);
|
||||
sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
//设置创建时间
|
||||
sysUser.setCreateTime(new Date());
|
||||
String salt = oConvertUtils.randomGen(8);
|
||||
sysUser.setSalt(salt);
|
||||
String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), sysUser.getPassword(), salt);
|
||||
sysUser.setPassword(passwordEncode);
|
||||
sysUser.setStatus(1);
|
||||
sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
//用户表字段org_code不能在这里设置他的值
|
||||
sysUser.setOrgCode(null);
|
||||
try {
|
||||
userMapper.insert(sysUser);
|
||||
String str = String.format("用户 %s(%s) 创建成功!", sysUser.getRealname(), sysUser.getUsername());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
return sysUser.getId();
|
||||
} catch (Exception e) {
|
||||
User user = new User();
|
||||
user.setUserid(wechatUserId);
|
||||
user.setName(wechatRealName);
|
||||
this.syncUserCollectErrInfo(e, user, syncInfo);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户租户
|
||||
*
|
||||
* @param userId
|
||||
* @param isUpdate 是否是新增
|
||||
* @param tenantId
|
||||
*/
|
||||
private void createUserTenant(String userId, Boolean isUpdate, Integer tenantId) {
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
//判断当前用户是否已在该租户下面
|
||||
Integer count = sysUserTenantMapper.userTenantIzExist(userId, tenantId);
|
||||
//count 为0 新增租户用户,否则不用新增
|
||||
if (count == 0) {
|
||||
SysUserTenant userTenant = new SysUserTenant();
|
||||
userTenant.setTenantId(tenantId);
|
||||
userTenant.setUserId(userId);
|
||||
userTenant.setStatus(isUpdate ? CommonConstant.USER_TENANT_UNDER_REVIEW : CommonConstant.USER_TENANT_NORMAL);
|
||||
sysUserTenantMapper.insert(userTenant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建或更新用户部门关系表
|
||||
* @param idsMap 部门id集合 key为企业微信的id value 为系统部门的id
|
||||
* @param sysUserId 系统对应的用户id
|
||||
*/
|
||||
private void userDepartSaveOrUpdate(Map<String, String> idsMap, String sysUserId, String[] departIds) {
|
||||
LambdaQueryWrapper<SysUserDepart> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysUserDepart::getUserId,sysUserId);
|
||||
for (String departId:departIds) {
|
||||
departId = departId.trim();
|
||||
if(idsMap.containsKey(departId)){
|
||||
String value = idsMap.get(departId);
|
||||
//查询用户是否在部门里面
|
||||
query.eq(SysUserDepart::getDepId,value);
|
||||
long count = sysUserDepartService.count(query);
|
||||
if(count == 0){
|
||||
//不存在,则新增部门用户关系
|
||||
SysUserDepart sysUserDepart = new SysUserDepart(null,sysUserId,value);
|
||||
sysUserDepartService.save(sysUserDepart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<JwUserDepartVo> getThirdUserBindByWechat(int tenantId) {
|
||||
return sysThirdAccountMapper.getThirdUserBindByWechat(tenantId,THIRD_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
package org.jeecg.modules.system.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
|
||||
@Data
|
||||
public class SysDepartExportVo {
|
||||
/**部门路径*/
|
||||
@Excel(name="部门路径",width=50)
|
||||
private String departNameUrl;
|
||||
/**机构/部门名称*/
|
||||
@Excel(name="部门名称",width=50)
|
||||
private String departName;
|
||||
/**id*/
|
||||
private String id;
|
||||
/**父级id*/
|
||||
private String parentId;
|
||||
/**英文名*/
|
||||
@Excel(name="英文名",width=15)
|
||||
private String departNameEn;
|
||||
/**排序*/
|
||||
@Excel(name="排序",width=15)
|
||||
private Integer departOrder;
|
||||
/**描述*/
|
||||
@Excel(name="描述",width=15)
|
||||
private String description;
|
||||
/**机构类别 1=公司,2=组织机构,3=岗位*/
|
||||
@Excel(name="机构类别",width=15,dicCode="org_category")
|
||||
private String orgCategory;
|
||||
/**机构编码*/
|
||||
@Excel(name="机构编码",width=15)
|
||||
private String orgCode;
|
||||
/**手机号*/
|
||||
@Excel(name="手机号",width=15)
|
||||
private String mobile;
|
||||
/**传真*/
|
||||
@Excel(name="传真",width=15)
|
||||
private String fax;
|
||||
/**地址*/
|
||||
@Excel(name="地址",width=15)
|
||||
private String address;
|
||||
/**备注*/
|
||||
@Excel(name="备注",width=15)
|
||||
private String memo;
|
||||
}
|
||||
@ -102,4 +102,14 @@ public class SysUserTenantVo {
|
||||
* 门牌号
|
||||
*/
|
||||
private String houseNumber;
|
||||
|
||||
/**
|
||||
* 是否为会员
|
||||
*/
|
||||
private String memberType;
|
||||
|
||||
/**
|
||||
* 是否为租户管理员
|
||||
*/
|
||||
private Boolean tenantAdmin = false;
|
||||
}
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
package org.jeecg.modules.system.vo.thirdapp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 企业微信的实现类
|
||||
*/
|
||||
@Data
|
||||
public class JwSysUserDepartVo {
|
||||
|
||||
/**
|
||||
* 企业微信和用户的映射类
|
||||
*/
|
||||
private List<JwUserDepartVo> jwUserDepartVos;
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
*/
|
||||
private List<JwUserDepartVo> userList;
|
||||
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package org.jeecg.modules.system.vo.thirdapp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: 企业微信用户同步工具类
|
||||
*
|
||||
* @author: wangshuai
|
||||
* @date: 2023/11/28 18:17
|
||||
*/
|
||||
@Data
|
||||
public class JwUserDepartVo {
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 真实姓名
|
||||
*/
|
||||
private String realName;
|
||||
|
||||
/**
|
||||
* 企业微信的名字
|
||||
*/
|
||||
private String wechatRealName;
|
||||
|
||||
/**
|
||||
* 企业微信对应的部门
|
||||
*/
|
||||
private String wechatDepartId;
|
||||
|
||||
/**
|
||||
* 企业微信对应的用户id
|
||||
*/
|
||||
private String wechatUserId;
|
||||
|
||||
/**
|
||||
* 第三方id
|
||||
*/
|
||||
private String thirdId;
|
||||
}
|
||||
@ -20,7 +20,9 @@
|
||||
JSelectDept,
|
||||
</#if>
|
||||
<#if need_dept_user>
|
||||
JSelectUserByDept,
|
||||
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
JSelectUser,
|
||||
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
</#if>
|
||||
<#if need_select_tree>
|
||||
JTreeSelect,
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow =='Y' && po.fieldName != 'id' && isNotPidField(tableVo, po.fieldDbName)>
|
||||
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#if po.isShow =='Y' && po.fieldName != 'id' && po.fieldName !='delFlag' && isNotPidField(tableVo, po.fieldDbName)>
|
||||
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#assign form_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
@ -40,7 +42,7 @@
|
||||
<j-switch v-model:value="formData.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>></j-switch>
|
||||
<#elseif po.classType =='pca'>
|
||||
<#assign need_pca = true>
|
||||
<j-area-linkage v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> />
|
||||
<j-area-select v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> />
|
||||
<#elseif po.classType =='markdown'>
|
||||
<#assign need_markdown = true>
|
||||
<j-markdown-editor v-model:value="formData.${autoStringSuffixForModel(po)}" id="${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>></j-markdown-editor>
|
||||
@ -48,7 +50,9 @@
|
||||
<a-input-password v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
|
||||
<#elseif po.classType =='sel_user'>
|
||||
<#assign need_dept_user = true>
|
||||
<j-select-user-by-dept v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
|
||||
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
<j-select-user v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
|
||||
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
<#elseif po.classType =='textarea'>
|
||||
<a-textarea v-model:value="formData.${autoStringSuffixForModel(po)}" :rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
|
||||
<#elseif po.classType=='radio'>
|
||||
|
||||
@ -20,7 +20,9 @@
|
||||
import JSelectDept from '/@/components/Form/src/jeecg/components/JSelectDept.vue';
|
||||
</#if>
|
||||
<#if need_dept_user>
|
||||
import JSelectUserByDept from '/@/components/Form/src/jeecg/components/JSelectUserByDept.vue';
|
||||
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
import JSelectUser from '/@/components/Form/src/jeecg/components/JSelectUser.vue';
|
||||
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
</#if>
|
||||
<#if need_select_tree>
|
||||
import JTreeSelect from '/@/components/Form/src/jeecg/components/JTreeSelect.vue';
|
||||
@ -29,7 +31,7 @@
|
||||
import { TimePicker } from 'ant-design-vue';
|
||||
</#if>
|
||||
<#if need_pca>
|
||||
import JAreaLinkage from '/@/components/Form/src/jeecg/components/JAreaLinkage.vue';
|
||||
import JAreaSelect from '/@/components/Form/src/jeecg/components/JAreaSelect.vue';
|
||||
</#if>
|
||||
<#if need_upload>
|
||||
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isQuery=='Y'>
|
||||
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#if po.isQuery=='Y' && po.fieldName !='delFlag'>
|
||||
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#assign query_flag=true>
|
||||
<#if query_field_no==2>
|
||||
<template v-if="toggleSearchStatus">
|
||||
@ -14,12 +16,14 @@
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
<#if query_field_no gt 1> </#if><a-col :lg="6">
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}">
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${autoStringSuffixForModel(po)}">
|
||||
<#if query_field_no gt 1> </#if><template #label><span title="${po.filedComment}"><#if po.filedComment?default("")?trim?length gt 4>${po.filedComment?substring(0,4)}<#else>${po.filedComment}</#if></span></template>
|
||||
<#if po.classType=='sel_search'>
|
||||
<#if query_field_no gt 1> </#if><j-search-select placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dict="${po.dictTable},${po.dictText},${po.dictField}" />
|
||||
<#elseif po.classType=='sel_user'>
|
||||
<#if query_field_no gt 1> </#if><j-select-user-by-dept placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" />
|
||||
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
<#if query_field_no gt 1> </#if><j-select-user placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" @change="(value)=>handleFormJoinChange('${po.fieldName}',value)"/>
|
||||
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
<#elseif po.classType=='switch'>
|
||||
<#if query_field_no gt 1> </#if><j-switch placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> query />
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
@ -32,8 +36,10 @@
|
||||
<#if query_field_no gt 1> </#if><a-date-picker valueFormat="YYYY-MM-DD" placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" />
|
||||
<#elseif po.classType=='datetime'>
|
||||
<#if query_field_no gt 1> </#if><a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" />
|
||||
<#elseif po.classType=='time'>
|
||||
<#if query_field_no gt 1> </#if><time-picker valueFormat="HH:mm:ss" placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" />
|
||||
<#elseif po.classType=='pca'>
|
||||
<#if query_field_no gt 1> </#if><j-area-linkage v-model:value="queryParam.${po.fieldName}" placeholder="请选择${po.filedComment}" @change="(value) => handleAreaChange('${po.fieldName}', value)" />
|
||||
<#if query_field_no gt 1> </#if><j-area-select v-model:value="queryParam.${po.fieldName}" placeholder="请选择${po.filedComment}" />
|
||||
<#elseif po.classType=='sel_tree'>
|
||||
<#if query_field_no gt 1> </#if><j-tree-select v-model:value="queryParam.${po.fieldName}" placeholder="请选择${po.filedComment}" <#if po.dictText??><#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}" <#elseif po.dictText?split(',')[1]??>pidField:"${po.dictText?split(',')[1]}", <#elseif po.dictText?split(',')[3]??>hasChildField:"${po.dictText?split(',')[3]}"</#if> </#if>pidValue="${po.dictField}" />
|
||||
<#elseif po.classType=='popup'>
|
||||
@ -60,7 +66,7 @@
|
||||
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}"></a-input>
|
||||
</#if>
|
||||
<#else>
|
||||
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}"></a-input>
|
||||
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${autoStringSuffixForModel(po)}"></a-input>
|
||||
</#if>
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if></a-col>
|
||||
@ -69,17 +75,45 @@
|
||||
<#if query_field_no gt 1> </#if><a-form-item>
|
||||
<#if query_field_no gt 1> </#if><template #label><span title="${po.filedComment}"><#if po.filedComment?default("")?trim?length gt 4>${po.filedComment?substring(0,4)}<#else>${po.filedComment}</#if></span></template>
|
||||
<#if po.classType=='date'>
|
||||
<#if query_field_no gt 1> </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust"/>
|
||||
<#if query_field_no gt 1> </#if><div style="display: flex">
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
|
||||
<#if query_field_no gt 1> </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择开始日期" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust"/>
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
|
||||
<#if query_field_no gt 1> </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择结束日期" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust"/>
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if></div>
|
||||
<#elseif po.classType=='time'>
|
||||
<#if query_field_no gt 1> </#if><div style="display: flex">
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
|
||||
<#if query_field_no gt 1> </#if><time-picker value-format="HH:mm:ss" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust"/>
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
|
||||
<#if query_field_no gt 1> </#if><time-picker value-format="HH:mm:ss" placeholder="请选择结束日期" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust"/>
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if></div>
|
||||
<#elseif po.classType=='datetime'>
|
||||
<#if query_field_no gt 1> </#if><div style="display: flex">
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
|
||||
<#if query_field_no gt 1> </#if><a-date-picker showTime value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" />
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
|
||||
<#if query_field_no gt 1> </#if><a-date-picker showTime value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" />
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if></div>
|
||||
<#else>
|
||||
<#if query_field_no gt 1> </#if><div style="display: flex">
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
|
||||
<#if query_field_no gt 1> </#if><a-input placeholder="请输入最小值" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust"></a-input>
|
||||
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if><span class="query-group-left query-group-split-cust">~</span>
|
||||
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
|
||||
<#if query_field_no gt 1> </#if><a-input placeholder="请输入最大值" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust"></a-input>
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if></div>
|
||||
</#if>
|
||||
<#if query_field_no gt 1> </#if></a-form-item>
|
||||
<#if query_field_no gt 1> </#if></a-col>
|
||||
|
||||
@ -131,6 +131,65 @@
|
||||
</#if>
|
||||
</#if>
|
||||
</#function>
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
<#-- ** 高级查询生成(Vue3 * -->
|
||||
<#function superQueryFieldListForVue3(po,order)>
|
||||
<#-- 字段展示/DB类型 -->
|
||||
<#assign baseAttrs="view: '${po.classType}', type: 'string',">
|
||||
<#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
<#assign baseAttrs="view: 'number', type: 'number',">
|
||||
</#if>
|
||||
|
||||
<#-- 特殊类型控件扩展字段 -->
|
||||
<#assign extAttrs="">
|
||||
<#assign dictCode="">
|
||||
<#if po.dictTable?default('')?trim?length gt 1 && po.dictText?default('')?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:fix 带条件字典存在单引号导致js编译错误---------- -->
|
||||
<#assign dictCode="dictTable: \"${po.dictTable}\", dictCode: '${po.dictField}', dictText: '${po.dictText}'">
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:fix 带条件字典存在单引号导致js编译错误---------- -->
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign dictCode="dictCode: '${po.dictField}'">
|
||||
</#if>
|
||||
|
||||
<#if po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='checkbox'>
|
||||
<#assign extAttrs="${dictCode},">
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#-- 分类字典树 -->
|
||||
<#-- update-begin---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||
<#assign extAttrs="pcode: '${po.dictField?default('')}',">
|
||||
<#-- update-end---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||
<#elseif po.classType=='sel_tree'>
|
||||
<#-- 自定义树 -->
|
||||
<#if po.dictText??>
|
||||
<#-- dictText示例:id,pid,name,has_child -->
|
||||
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||
<#assign extAttrs="dict: '${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}'">
|
||||
<#elseif po.dictText?split(',')[1]??>
|
||||
<#assign extAttrs="pidField: '${po.dictText?split(',')[1]}'">
|
||||
<#elseif po.dictText?split(',')[3]??>
|
||||
<#assign extAttrs="hasChildField: '${po.dictText?split(',')[3]}'">
|
||||
</#if>
|
||||
</#if>
|
||||
<#-- update-begin---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||
<#assign extAttrs="${extAttrs}, pidValue: '${po.dictField?default('')}',">
|
||||
<#-- update-end---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||
<#elseif po.classType=='popup'>
|
||||
<#-- popup -->
|
||||
<#-- update-begin---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||
<#if po.dictText?default("")?trim?length gt 1 && po.dictText?index_of(',') gt 0 && po.dictField?default("")?trim?length gt 1>
|
||||
<#-- update-begin---author:chenrui ---date:20240109 for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
|
||||
<#-- 如果有多个回填字段,找到popup字段对应的来源字段 -->
|
||||
<#assign orgFieldIx=po.dictText?split(',')?seq_index_of(po.fieldDbName)>
|
||||
<#assign orgField=po.dictField?split(',')[orgFieldIx]>
|
||||
<#else>
|
||||
<#assign orgField=po.dictField?default("")>
|
||||
</#if>
|
||||
<#assign extAttrs="code: '${po.dictTable?default('')}', orgFields: '${orgField}', destFields: '${po.fieldName}', popupMulti: false,">
|
||||
</#if>
|
||||
|
||||
<#return "${po.fieldName}: {title: '${po.filedComment}',order: ${order},${baseAttrs}${extAttrs}}" >
|
||||
</#function>
|
||||
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
|
||||
|
||||
<#-- vue3 获取表单modal的宽度-->
|
||||
|
||||
@ -37,6 +37,10 @@
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
<!-- 高级查询 -->
|
||||
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
|
||||
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
@ -71,12 +75,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {ref, reactive, computed, unref} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||
import {useModal} from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage'
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||
import {columns, searchFormSchema} from './${entityName}.data';
|
||||
import {columns, searchFormSchema, superQuerySchema} from './${entityName}.data';
|
||||
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
@ -91,6 +95,7 @@
|
||||
<#if bpm_flag==true>
|
||||
import { startProcess } from '/@/api/common/api';
|
||||
</#if>
|
||||
const queryParam = reactive<any>({});
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
const userStore = useUserStore();
|
||||
//注册model
|
||||
@ -133,13 +138,17 @@
|
||||
],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 150,
|
||||
width: 120,
|
||||
fixed:'right'
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
return Object.assign(params, queryParam);
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name:"${tableVo.ftlDescription}",
|
||||
url: getExportUrl,
|
||||
params: queryParam,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
@ -149,6 +158,20 @@
|
||||
|
||||
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
|
||||
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
// 高级查询配置
|
||||
const superQueryConfig = reactive(superQuerySchema);
|
||||
|
||||
/**
|
||||
* 高级查询事件
|
||||
*/
|
||||
function handleSuperQuery(params) {
|
||||
Object.keys(params).map((k) => {
|
||||
queryParam[k] = params[k];
|
||||
});
|
||||
reload();
|
||||
}
|
||||
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
@ -221,6 +244,7 @@
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
placement: 'topLeft',
|
||||
}
|
||||
}
|
||||
];
|
||||
@ -230,6 +254,7 @@
|
||||
popConfirm: {
|
||||
title: '确认提交流程吗?',
|
||||
confirm: handleProcess.bind(null, record),
|
||||
placement: 'topLeft',
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -244,6 +269,7 @@
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
placement: 'topLeft',
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -6,7 +6,9 @@ import { render } from '/@/utils/common/renderUtils';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
|
||||
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
@ -70,7 +72,9 @@ export const searchFormSchema: FormSchema[] = [
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#if po.isQuery=='Y' && po.fieldName !='delFlag'>
|
||||
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
@ -88,7 +92,9 @@ export const searchFormSchema: FormSchema[] = [
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
component: 'JSelectUser',
|
||||
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
@ -186,7 +192,9 @@ export const formSchema: FormSchema[] = [
|
||||
<#if po.fieldDbName == 'id'>
|
||||
<#assign id_exists = true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#if po.isShow =='Y' && po.fieldName !='delFlag'>
|
||||
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#assign form_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
@ -236,7 +244,9 @@ export const formSchema: FormSchema[] = [
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
component: 'JSelectUser',
|
||||
<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
},
|
||||
@ -247,11 +257,18 @@ export const formSchema: FormSchema[] = [
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
},
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JSelectMultiple',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
},
|
||||
<#elseif po.classType=='checkbox'>
|
||||
component: 'JCheckbox',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
},
|
||||
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
@ -376,7 +393,18 @@ export const formSchema: FormSchema[] = [
|
||||
</#if>
|
||||
];
|
||||
|
||||
|
||||
<#-- update-begin-author:chenrui date:2023-12-28 for:[QQYUN-7527]vue3代码生成默认带上高级查询 -->
|
||||
// 高级查询数据
|
||||
export const superQuerySchema = {
|
||||
<#list columns as po>
|
||||
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
|
||||
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
${superQueryFieldListForVue3(po,po_index)},
|
||||
</#if>
|
||||
</#list>
|
||||
};
|
||||
<#-- update-end-author:chenrui date:2023-12-28 for:[QQYUN-7527]vue3代码生成默认带上高级查询 -->
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<view>
|
||||
<!--标题和返回-->
|
||||
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
|
||||
<block slot="backText">返回</block>
|
||||
<block slot="content">${tableVo.ftlDescription}</block>
|
||||
</cu-custom>
|
||||
<!--表单区域-->
|
||||
<view>
|
||||
<form>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldName !='id'><#rt/>
|
||||
<#if po.classType =='date'>
|
||||
<my-date label="${po.filedComment}:" fields="day" v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"></my-date>
|
||||
<#elseif po.classType =='datetime'>
|
||||
<my-date label="${po.filedComment}:" v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"></my-date>
|
||||
<#else>
|
||||
<view class="cu-form-group">
|
||||
<view class="flex align-center">
|
||||
<view class="title"><text space="ensp">${po.filedComment}:</text></view>
|
||||
<input <#if "int,BigDecimal,double,"?contains(po.fieldDbType)>type="number"</#if> placeholder="请输入${po.filedComment}" v-model="model.${po.fieldName}"/>
|
||||
</view>
|
||||
</view>
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<view class="padding">
|
||||
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
|
||||
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
|
||||
</button>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import myDate from '@/components/my-componets/my-date.vue'
|
||||
|
||||
export default {
|
||||
name: "${entityName}Form",
|
||||
components:{ myDate },
|
||||
props:{
|
||||
formData:{
|
||||
type:Object,
|
||||
default:()=>{},
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
CustomBar: this.CustomBar,
|
||||
NavBarColor: this.NavBarColor,
|
||||
loading:false,
|
||||
model: {},
|
||||
backRouteName:'index',
|
||||
url: {
|
||||
queryById: "/${entityPackage}/${entityName?uncap_first}/queryById",
|
||||
add: "/${entityPackage}/${entityName?uncap_first}/add",
|
||||
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
|
||||
},
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.initFormData();
|
||||
},
|
||||
methods:{
|
||||
initFormData(){
|
||||
if(this.formData){
|
||||
let dataId = this.formData.dataId;
|
||||
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
|
||||
if(res.data.success){
|
||||
console.log("表单数据",res);
|
||||
this.model = res.data.result;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onSubmit() {
|
||||
let myForm = {...this.model};
|
||||
this.loading = true;
|
||||
let url = myForm.id?this.url.edit:this.url.add;
|
||||
this.$http.post(url,myForm).then(res=>{
|
||||
console.log("res",res)
|
||||
this.loading = false
|
||||
this.$Router.push({name:this.backRouteName})
|
||||
}).catch(()=>{
|
||||
this.loading = false
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<view>
|
||||
<!--标题和返回-->
|
||||
<cu-custom :bgColor="NavBarColor" isBack>
|
||||
<block slot="backText">返回</block>
|
||||
<block slot="content">${tableVo.ftlDescription}</block>
|
||||
</cu-custom>
|
||||
<!--滚动加载列表-->
|
||||
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
|
||||
<view class="cu-list menu">
|
||||
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
|
||||
<view class="flex" style="width:100%">
|
||||
<text class="text-lg" style="color: #000;">
|
||||
{{ item.createBy}}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
|
||||
import Mixin from "@/common/mixin/Mixin.js";
|
||||
|
||||
export default {
|
||||
name: '${tableVo.ftlDescription}',
|
||||
mixins: [MescrollMixin,Mixin],
|
||||
data() {
|
||||
return {
|
||||
CustomBar:this.CustomBar,
|
||||
NavBarColor:this.NavBarColor,
|
||||
url: "/${entityPackage}/${entityName?uncap_first}/list",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
goHome(){
|
||||
this.$Router.push({name: "index"})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -101,6 +101,10 @@
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
<!-- 高级查询 -->
|
||||
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
|
||||
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
@ -137,7 +141,7 @@
|
||||
import { ref, reactive } from 'vue';
|
||||
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { columns } from './${entityName}.data';
|
||||
import { columns, superQuerySchema } from './${entityName}.data';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './${entityName}.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||
@ -169,7 +173,7 @@
|
||||
canResize:false,
|
||||
useSearchForm: false,
|
||||
actionColumn: {
|
||||
width: 150,
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
@ -198,6 +202,21 @@
|
||||
sm: 20,
|
||||
});
|
||||
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
// 高级查询配置
|
||||
const superQueryConfig = reactive(superQuerySchema);
|
||||
|
||||
/**
|
||||
* 高级查询事件
|
||||
*/
|
||||
function handleSuperQuery(params) {
|
||||
Object.keys(params).map((k) => {
|
||||
queryParam[k] = params[k];
|
||||
});
|
||||
searchQuery();
|
||||
}
|
||||
<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- -->
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
@ -269,6 +288,7 @@
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
placement: 'topLeft',
|
||||
}
|
||||
}
|
||||
];
|
||||
@ -278,6 +298,7 @@
|
||||
popConfirm: {
|
||||
title: '确认提交流程吗?',
|
||||
confirm: handleProcess.bind(null, record),
|
||||
placement: 'topLeft',
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -292,6 +313,7 @@
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
placement: 'topLeft',
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -326,13 +348,13 @@
|
||||
}
|
||||
</#if>
|
||||
|
||||
<#if need_pca>
|
||||
<#if need_pca || need_dept_user>
|
||||
/**
|
||||
* 省市区点击事件
|
||||
* form点击事件(以逗号分割)
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
function handleAreaChange(key, value) {
|
||||
function handleFormJoinChange(key, value) {
|
||||
queryParam[key] = value.join(',');
|
||||
}
|
||||
</#if>
|
||||
@ -394,7 +416,6 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
.query-group-cust{
|
||||
width: calc(50% - 15px);
|
||||
min-width: 100px !important;
|
||||
}
|
||||
.query-group-split-cust{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user