mirror of https://github.com/jeecgboot/jeecg-boot
JeecgBoot低代码平台 2.4.5 版本发布,钉钉与企业微信集成版本
parent
1bc7ee3345
commit
6840772959
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,81 +0,0 @@
|
||||||
|
|
||||||
-- redis监控菜单sql
|
|
||||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_route`, `is_leaf`, `keep_alive`, `hidden`, `description`, `status`, `del_flag`, `rule_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `internal_or_external`) VALUES ('1352200630711652354', 'f0675b52d89100ee88472b6800754a08', 'redis监控', '{{ window._CONFIG[\'domianURL\'] }}/jmreport/view/1352160857479581696', 'layouts/IframePageView', NULL, NULL, '1', NULL, '1', '1.00', '0', '', '1', '1', '0', '0', NULL, '1', '0', '0', 'admin', '2021-01-21 18:25:28', 'admin', '2021-01-22 16:49:43', '0');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- 新增开关字典
|
|
||||||
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `type`) VALUES ('1356445645198135298', '开关', 'is_open', '', '0', 'admin', '2021-02-02 11:33:38', 'admin', '2021-02-02 15:28:12', '0');
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1356445705549975553', '1356445645198135298', '是', 'Y', '', '1', '1', 'admin', '2021-02-02 11:33:52', NULL, NULL);
|
|
||||||
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1356445754212290561', '1356445645198135298', '否', 'N', '', '1', '1', 'admin', '2021-02-02 11:34:04', NULL, NULL);
|
|
||||||
-- author:liusq----date:20210202----for: 新增开关字典
|
|
||||||
|
|
||||||
|
|
||||||
-- 是否字典
|
|
||||||
INSERT INTO `sys_dict`(`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `type`) VALUES ('a7adbcd86c37f7dbc9b66945c82ef9e6', '1是0否', 'yn', '', 0, 'admin', '2019-05-22 19:29:29', NULL, NULL, 0);
|
|
||||||
INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('51222413e5906cdaf160bb5c86fb827c', 'a7adbcd86c37f7dbc9b66945c82ef9e6', '是', '1', '', 1, 1, 'admin', '2019-05-22 19:29:45', NULL, NULL);
|
|
||||||
INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('c5700a71ad08994d18ad1dacc37a71a9', 'a7adbcd86c37f7dbc9b66945c82ef9e6', '否', '0', '', 1, 1, 'admin', '2019-05-22 19:29:55', NULL, NULL);
|
|
||||||
-- author:scott----date:20210202----for: 是否字典
|
|
||||||
|
|
||||||
|
|
||||||
-- 精简积木报表的示例表,由22个减至4个----
|
|
||||||
drop table rep_demo_dadong;
|
|
||||||
drop table rep_demo_daibu;
|
|
||||||
drop table rep_demo_deliveryorder;
|
|
||||||
drop table rep_demo_huizong;
|
|
||||||
drop table rep_demo_income;
|
|
||||||
drop table rep_demo_jiehsao;
|
|
||||||
drop table rep_demo_kaoqin;
|
|
||||||
drop table rep_demo_salesrate;
|
|
||||||
drop table rep_demo_xiaoshou;
|
|
||||||
drop table xianlu1_wxtl;
|
|
||||||
drop table xianlu_wxtl;
|
|
||||||
drop table yanshi_duozu;
|
|
||||||
drop table yanshi_jdcx;
|
|
||||||
drop table yanshi_qipaosandian;
|
|
||||||
drop table yanshi_sandian;
|
|
||||||
drop table yanshi_tima;
|
|
||||||
drop table yanshi_wxtl;
|
|
||||||
drop table yanshi_yipan;
|
|
||||||
alter table yanshi_dxtj rename to rep_demo_dxtj;
|
|
||||||
delete from jimu_report_data_source where report_id in ('1331429368098066432','1333962561053396992','1334028738995818496','1334074491629867008','1337271712059887616','1339478701846433792','1339859143477039104','8e69f5396643b199c92d6f401be4d833');
|
|
||||||
delete from jimu_report_db where jimu_report_id in('1331429368098066432','1333962561053396992','1334028738995818496','1334074491629867008','1337271712059887616','1339478701846433792','1339859143477039104','8e69f5396643b199c92d6f401be4d833');
|
|
||||||
delete from jimu_report_db_param where jimu_report_head_id in ('1331429368098066432','1333962561053396992','1334028738995818496','1334074491629867008','1337271712059887616','1339478701846433792','1339859143477039104','8e69f5396643b199c92d6f401be4d833');
|
|
||||||
delete from jimu_report_db_field where jimu_report_db_id not in (select id from jimu_report_db);
|
|
||||||
delete from jimu_report where id in ('1331429368098066432','1333962561053396992','1334028738995818496','1334074491629867008','1337271712059887616','1339478701846433792','1339859143477039104','8e69f5396643b199c92d6f401be4d833');
|
|
||||||
|
|
||||||
|
|
||||||
-- 添加一对多JVxeTable案例
|
|
||||||
INSERT INTO sys_permission (`id`, `parent_id`, `name`, `url`, `component`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_route`, `is_leaf`, `keep_alive`, `hidden`, `description`, `status`, `del_flag`, `rule_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `internal_or_external`) VALUES ('1365187528377102337', '2a470fc0c3954d9dbb61de6d80846549', '一对多JVxeTable', '/jeecg/JeecgOrderMainListForJVxeTable', 'jeecg/JeecgOrderMainListForJVxeTable', NULL, NULL, 1, NULL, '1', 2.00, 0, NULL, 1, 1, 0, 0, NULL, '1', 0, 0, 'admin', '2021-02-26 14:30:45', 'admin', '2021-02-26 14:32:05', 0);
|
|
||||||
|
|
||||||
-- 积木权限表
|
|
||||||
CREATE TABLE `jimu_report_share` (
|
|
||||||
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键',
|
|
||||||
`report_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '在线excel设计器id',
|
|
||||||
`preview_url` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '预览地址',
|
|
||||||
`preview_lock` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '密码锁',
|
|
||||||
`last_update_time` datetime(0) NULL DEFAULT NULL COMMENT '最后更新时间',
|
|
||||||
`term_of_validity` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '有效期(0:永久有效,1:1天,2:7天)',
|
|
||||||
`status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否过期(0未过期,1已过期)',
|
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
|
||||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '积木报表预览权限表';
|
|
||||||
|
|
||||||
|
|
||||||
-- 积木报表链接表
|
|
||||||
CREATE TABLE `jimu_report_link` (
|
|
||||||
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键id',
|
|
||||||
`report_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '积木设计器id',
|
|
||||||
`parameter` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '参数',
|
|
||||||
`eject_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '弹出方式(0 当前页面 1 新窗口)',
|
|
||||||
`link_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '链接名称',
|
|
||||||
`api_method` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求方法0-get,1-post',
|
|
||||||
`link_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '链接方式(0 网络报表 1 网络连接 2 图表联动)',
|
|
||||||
`api_url` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '外网api',
|
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
|
||||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '超链接配置表';
|
|
||||||
|
|
||||||
|
|
||||||
update jimu_report_link set link_type = '0';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
-- online 新增部门授权 扩展字段
|
||||||
|
ALTER TABLE `onl_auth_relation`
|
||||||
|
ADD COLUMN `auth_mode` varchar(50) NULL COMMENT '授权方式role角色,depart部门,user人' AFTER `cgform_id`;
|
||||||
|
update onl_auth_relation set auth_mode = 'role';
|
||||||
|
|
||||||
|
-- 部门表新增 qywx_identifier 字段
|
||||||
|
ALTER TABLE `sys_depart`
|
||||||
|
ADD COLUMN `qywx_identifier` varchar(100) NULL COMMENT '对接企业微信的ID' AFTER `del_flag`;
|
||||||
|
|
||||||
|
-- sys_third_account 表新增 third_user_id 字段
|
||||||
|
ALTER TABLE `sys_third_account`
|
||||||
|
ADD COLUMN `third_user_id` varchar(100) NULL COMMENT '第三方app用户账号' AFTER `third_user_uuid`;
|
||||||
|
|
||||||
|
-- 新增第三方APP消息测试菜单
|
||||||
|
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`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1387612436586065922', '2a470fc0c3954d9dbb61de6d80846549', '第三方APP消息测试', '/jeecg/ThirdAppMessageTest', 'jeecg/ThirdAppMessageTest', '1', NULL, NULL, '1', NULL, '1', '3', '0', NULL, '1', '0', '0', NULL, 'admin', '2021-04-29 11:39:20', 'admin', '2021-04-29 11:39:27', '0', '0', '1', '0');
|
||||||
|
|
||||||
|
-- 定时任务:一个类允许配置多个调度
|
||||||
|
-- 删除定时任务表唯一索引
|
||||||
|
ALTER TABLE `sys_quartz_job`
|
||||||
|
DROP INDEX `uniq_job_class_name`;
|
||||||
|
|
||||||
|
-- 停止所有的定时任务,用于旧数据,只执行一次即可,【执行完毕后需要重启后台项目,并[手动]再次打开定时任务】!
|
||||||
|
DELETE FROM `qrtz_cron_triggers`;
|
||||||
|
DELETE FROM `qrtz_fired_triggers`;
|
||||||
|
DELETE FROM `qrtz_triggers`;
|
||||||
|
DELETE FROM `qrtz_job_details`;
|
||||||
|
UPDATE `sys_quartz_job` SET `status` = '-1';
|
||||||
|
|
||||||
|
-- 不支持mariaDB数据库处理 issues/I3QID1
|
||||||
|
update sys_dict_item set item_text = 'MariaDB' where id ='1349250340104474626';
|
||||||
|
update sys_dict_item set item_text = 'Postgresql' where id ='1349254569766457345';
|
||||||
|
|
||||||
|
-- sys_announcement新增dt_task_id字段
|
||||||
|
ALTER TABLE `sys_announcement`
|
||||||
|
ADD COLUMN `dt_task_id` varchar(100) NULL COMMENT '钉钉task_id,用于撤回消息' AFTER `msg_abstract`;
|
||||||
|
|
||||||
|
|
||||||
|
-- 模板类型注释错误
|
||||||
|
ALTER TABLE `jimu_report`
|
||||||
|
MODIFY COLUMN `template` tinyint(1) NULL DEFAULT NULL COMMENT '是否是模板 0不是,1是' AFTER `api_code`;
|
||||||
|
|
||||||
|
-- 查询支持默认值
|
||||||
|
ALTER TABLE `jimu_report_db_field`
|
||||||
|
ADD COLUMN `search_value` varchar(100) NULL COMMENT '查询默认值' AFTER `dict_code`;
|
||||||
|
|
||||||
|
-- jimu_report_db增加JSON数据字段
|
||||||
|
ALTER TABLE `jimu_report_db`
|
||||||
|
ADD COLUMN `json_data` text NULL COMMENT 'json数据,直接解析json内容' AFTER `db_source_type`;
|
||||||
|
|
||||||
|
-- 连接失败次数
|
||||||
|
ALTER TABLE `jimu_report_data_source`
|
||||||
|
ADD COLUMN `connect_times` int(1) NULL COMMENT '连接失败次数' AFTER `update_time`;
|
||||||
|
|
||||||
|
-- 联动图表ID
|
||||||
|
ALTER TABLE `jimu_report_link`
|
||||||
|
ADD COLUMN `link_chart_id` varchar(50) NULL COMMENT '联动图表的ID' AFTER `api_url`;
|
||||||
|
|
||||||
|
-- 修复脚本的一些问题---
|
||||||
|
update sys_permission set url="{{ window._CONFIG['domianURL'] }}/jmreport/view/1352160857479581696?token=${token}" where id ='1352200630711652354';
|
||||||
|
UPDATE `jimu_report_db` SET `jimu_report_id` = '1352160857479581696', `create_by` = 'admin', `update_by` = 'admin', `create_time` = '2021-05-19 19:20:44', `update_time` = '2021-05-19 19:20:44', `db_code` = 'infoForReport', `db_ch_name` = '信息', `db_type` = '1', `db_table_name` = NULL, `db_dyn_sql` = NULL, `db_key` = NULL, `tb_db_key` = NULL, `tb_db_table_name` = NULL, `java_type` = NULL, `java_value` = NULL, `api_url` = '{{ domainURL }}/sys/actuator/redis/infoForReport', `api_method` = '0', `is_list` = 1, `is_page` = '1', `db_source` = '', `db_source_type` = NULL, `json_data` = NULL WHERE `id` = '60b3feffadc55eb49baa5a48fdf1ff0e';
|
||||||
|
UPDATE `jimu_report_db` SET `jimu_report_id` = '1352160857479581696', `create_by` = 'admin', `update_by` = 'admin', `create_time` = '2021-05-19 19:20:50', `update_time` = '2021-05-19 19:20:50', `db_code` = 'memoryForReport', `db_ch_name` = '内存', `db_type` = '1', `db_table_name` = NULL, `db_dyn_sql` = NULL, `db_key` = NULL, `tb_db_key` = NULL, `tb_db_table_name` = NULL, `java_type` = NULL, `java_value` = NULL, `api_url` = '{{ domainURL }}/sys/actuator/redis/memoryForReport', `api_method` = '0', `is_list` = 1, `is_page` = '0', `db_source` = '', `db_source_type` = NULL, `json_data` = NULL WHERE `id` = '6a1d22ca4c95e8fab655d3ceed43a84d';
|
||||||
|
UPDATE `jimu_report_db` SET `jimu_report_id` = '1352160857479581696', `create_by` = 'admin', `update_by` = 'admin', `create_time` = '2021-05-19 19:21:03', `update_time` = '2021-05-19 19:21:03', `db_code` = 'keysSizeForReport', `db_ch_name` = '数量', `db_type` = '1', `db_table_name` = NULL, `db_dyn_sql` = NULL, `db_key` = NULL, `tb_db_key` = NULL, `tb_db_table_name` = NULL, `java_type` = NULL, `java_value` = NULL, `api_url` = '{{ domainURL }}/sys/actuator/redis/keysSizeForReport', `api_method` = '0', `is_list` = 1, `is_page` = '0', `db_source` = '', `db_source_type` = NULL, `json_data` = NULL WHERE `id` = 'd4a29dfda94357308faf62be2b94db08';
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-base-api</artifactId>
|
<artifactId>jeecg-boot-base-api</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.3</version>
|
<version>2.4.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-base-api</artifactId>
|
<artifactId>jeecg-boot-base-api</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.3</version>
|
<version>2.4.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-base</artifactId>
|
<artifactId>jeecg-boot-base</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.3</version>
|
<version>2.4.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-boot-base</artifactId>
|
<artifactId>jeecg-boot-base</artifactId>
|
||||||
<version>2.4.3</version>
|
<version>2.4.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>hibernate-re</artifactId>
|
<artifactId>hibernate-re</artifactId>
|
||||||
<version>2.4.3-RC</version>
|
<version>2.4.5-RC</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--mysql-->
|
<!--mysql-->
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package org.jeecg.common.api.desform;
|
||||||
|
|
||||||
|
import org.jeecg.common.system.vo.DictModel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单设计器【System】翻译API接口
|
||||||
|
*
|
||||||
|
* @author sunjianlei
|
||||||
|
*/
|
||||||
|
public interface ISysTranslateAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询分类字典翻译
|
||||||
|
*/
|
||||||
|
List<String> categoryLoadDictItem(String ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典code加载字典text
|
||||||
|
*
|
||||||
|
* @param dictCode 顺序:tableName,text,code
|
||||||
|
* @param keys 要查询的key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> dictLoadDictItem(String dictCode, String keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字典数据
|
||||||
|
*
|
||||||
|
* @param dictCode 顺序:tableName,text,code
|
||||||
|
* @param dictCode 要查询的key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<DictModel> dictGetDictItems(String dictCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【JSearchSelectTag下拉搜索组件专用接口】
|
||||||
|
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||||
|
*
|
||||||
|
* @param dictCode 字典code格式:table,text,code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<DictModel> dictLoadDict(String dictCode, String keyword, Integer pageSize);
|
||||||
|
|
||||||
|
}
|
|
@ -23,6 +23,11 @@ public class MessageDTO implements Serializable {
|
||||||
*/
|
*/
|
||||||
protected String toUser;
|
protected String toUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送给所有人
|
||||||
|
*/
|
||||||
|
protected boolean toAll;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息主题
|
* 消息主题
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package org.jeecg.common.api.vo;
|
package org.jeecg.common.api.vo;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口返回数据格式
|
* 接口返回数据格式
|
||||||
|
@ -112,7 +112,16 @@ public class Result<T> implements Serializable {
|
||||||
r.setResult(data);
|
r.setResult(data);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static<T> Result<T> error(String msg, T data) {
|
||||||
|
Result<T> r = new Result<T>();
|
||||||
|
r.setSuccess(false);
|
||||||
|
r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500);
|
||||||
|
r.setMessage(msg);
|
||||||
|
r.setResult(data);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
public static Result<Object> error(String msg) {
|
public static Result<Object> error(String msg) {
|
||||||
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
|
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,15 @@ import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.enums.ModuleType;
|
import org.jeecg.common.constant.enums.ModuleType;
|
||||||
|
import org.jeecg.modules.base.service.BaseCommonService;
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
import org.jeecg.common.util.IPUtils;
|
import org.jeecg.common.util.IPUtils;
|
||||||
import org.jeecg.common.util.SpringContextUtils;
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.base.service.BaseCommonService;
|
|
||||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.modules.base.service.BaseCommonService;
|
import org.jeecg.modules.base.service.BaseCommonService;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
@ -38,6 +39,8 @@ public class DictAspect {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CommonAPI commonAPI;
|
private CommonAPI commonAPI;
|
||||||
|
@Autowired
|
||||||
|
public RedisTemplate redisTemplate;
|
||||||
|
|
||||||
// 定义切点Pointcut
|
// 定义切点Pointcut
|
||||||
@Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))")
|
@Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))")
|
||||||
|
@ -144,12 +147,33 @@ public class DictAspect {
|
||||||
if (k.trim().length() == 0) {
|
if (k.trim().length() == 0) {
|
||||||
continue; //跳过循环
|
continue; //跳过循环
|
||||||
}
|
}
|
||||||
|
//update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
|
||||||
if (!StringUtils.isEmpty(table)){
|
if (!StringUtils.isEmpty(table)){
|
||||||
log.debug("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
|
log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
|
||||||
tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim());
|
String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim());
|
||||||
|
if (redisTemplate.hasKey(keyString)){
|
||||||
|
try {
|
||||||
|
tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn(e.getMessage());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim());
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
tmpValue = commonAPI.translateDict(code, k.trim());
|
String keyString = String.format("sys:cache:dict::%s:%s",code,k.trim());
|
||||||
|
if (redisTemplate.hasKey(keyString)){
|
||||||
|
try {
|
||||||
|
tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn(e.getMessage());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
tmpValue = commonAPI.translateDict(code, k.trim());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//update-end--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
|
||||||
|
|
||||||
if (tmpValue != null) {
|
if (tmpValue != null) {
|
||||||
if (!"".equals(textValue.toString())) {
|
if (!"".equals(textValue.toString())) {
|
||||||
textValue.append(",");
|
textValue.append(",");
|
||||||
|
|
|
@ -305,4 +305,21 @@ public interface CommonConstant {
|
||||||
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用
|
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用
|
||||||
*/
|
*/
|
||||||
public final static String THIRD_LOGIN_CODE = "third_login_code";
|
public final static String THIRD_LOGIN_CODE = "third_login_code";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方APP同步方向:本地 --> 第三方APP
|
||||||
|
*/
|
||||||
|
String THIRD_SYNC_TO_APP = "SYNC_TO_APP";
|
||||||
|
/**
|
||||||
|
* 第三方APP同步方向:第三方APP --> 本地
|
||||||
|
*/
|
||||||
|
String THIRD_SYNC_TO_LOCAL = "SYNC_TO_LOCAL";
|
||||||
|
|
||||||
|
/** 系统通告消息状态:0=未发布 */
|
||||||
|
String ANNOUNCEMENT_SEND_STATUS_0 = "0";
|
||||||
|
/** 系统通告消息状态:1=已发布 */
|
||||||
|
String ANNOUNCEMENT_SEND_STATUS_1 = "1";
|
||||||
|
/** 系统通告消息状态:2=已撤销 */
|
||||||
|
String ANNOUNCEMENT_SEND_STATUS_2 = "2";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,14 @@ public interface DataBaseConstant {
|
||||||
public static final String DB_TYPE_DM = "DM";//达梦数据库
|
public static final String DB_TYPE_DM = "DM";//达梦数据库
|
||||||
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
||||||
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
||||||
|
public static final String DB_TYPE_MARIADB = "MARIADB";
|
||||||
|
|
||||||
// 数据库类型,对应 database_type 字典
|
// 数据库类型,对应 database_type 字典
|
||||||
public static final String DB_TYPE_MYSQL_NUM = "1";
|
public static final String DB_TYPE_MYSQL_NUM = "1";
|
||||||
public static final String DB_TYPE_ORACLE_NUM = "2";
|
public static final String DB_TYPE_ORACLE_NUM = "2";
|
||||||
public static final String DB_TYPE_SQLSERVER_NUM = "3";
|
public static final String DB_TYPE_SQLSERVER_NUM = "3";
|
||||||
public static final String DB_TYPE_POSTGRESQL_NUM = "4";
|
public static final String DB_TYPE_POSTGRESQL_NUM = "4";
|
||||||
|
public static final String DB_TYPE_MARIADB_NUM = "5";
|
||||||
//*********系统上下文变量****************************************
|
//*********系统上下文变量****************************************
|
||||||
/**
|
/**
|
||||||
* 数据-所属机构编码
|
* 数据-所属机构编码
|
||||||
|
@ -65,6 +67,10 @@ public interface DataBaseConstant {
|
||||||
* 系统时间"yyyy-MM-dd HH:mm"
|
* 系统时间"yyyy-MM-dd HH:mm"
|
||||||
*/
|
*/
|
||||||
public static final String SYS_TIME_TABLE = "sys_time";
|
public static final String SYS_TIME_TABLE = "sys_time";
|
||||||
|
/**
|
||||||
|
* 数据-所属机构编码
|
||||||
|
*/
|
||||||
|
public static final String SYS_BASE_PATH = "sys_base_path";
|
||||||
//*********系统上下文变量****************************************
|
//*********系统上下文变量****************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -221,20 +221,31 @@ public class QueryGenerator {
|
||||||
if(parameterMap!=null&& parameterMap.containsKey(ORDER_TYPE)) {
|
if(parameterMap!=null&& parameterMap.containsKey(ORDER_TYPE)) {
|
||||||
order = parameterMap.get(ORDER_TYPE)[0];
|
order = parameterMap.get(ORDER_TYPE)[0];
|
||||||
}
|
}
|
||||||
log.debug("排序规则>>列:"+column+",排序方式:"+order);
|
log.info("排序规则>>列:" + column + ",排序方式:" + order);
|
||||||
if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
|
if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
|
||||||
//字典字段,去掉字典翻译文本后缀
|
//字典字段,去掉字典翻译文本后缀
|
||||||
if(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
|
if(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
|
||||||
column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
|
column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
|
||||||
}
|
}
|
||||||
//SQL注入check
|
//SQL注入check
|
||||||
SqlInjectionUtil.filterContent(column);
|
SqlInjectionUtil.filterContent(column);
|
||||||
|
|
||||||
|
//update-begin--Author:scott Date:20210531 for:36 多条件排序无效问题修正-------
|
||||||
|
// 排序规则修改
|
||||||
|
// 将现有排序 _ 前端传递排序条件{....,column: 'column1,column2',order: 'desc'} 翻译成sql "column1,column2 desc"
|
||||||
|
// 修改为 _ 前端传递排序条件{....,column: 'column1,column2',order: 'desc'} 翻译成sql "column1 desc,column2 desc"
|
||||||
if (order.toUpperCase().indexOf(ORDER_TYPE_ASC)>=0) {
|
if (order.toUpperCase().indexOf(ORDER_TYPE_ASC)>=0) {
|
||||||
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
|
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
|
||||||
|
String columnStr = oConvertUtils.camelToUnderline(column);
|
||||||
|
String[] columnArray = columnStr.split(",");
|
||||||
|
queryWrapper.orderByAsc(columnArray);
|
||||||
} else {
|
} else {
|
||||||
queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
|
queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
|
||||||
|
String columnStr = oConvertUtils.camelToUnderline(column);
|
||||||
|
String[] columnArray = columnStr.split(",");
|
||||||
|
queryWrapper.orderByDesc(columnArray);
|
||||||
}
|
}
|
||||||
|
//update-end--Author:scott Date:20210531 for:36 多条件排序无效问题修正-------
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1073,7 +1084,7 @@ public class QueryGenerator {
|
||||||
* @Return: java.lang.String
|
* @Return: java.lang.String
|
||||||
*/
|
*/
|
||||||
private static String specialStrConvert(String value) {
|
private static String specialStrConvert(String value) {
|
||||||
if (DataBaseConstant.DB_TYPE_MYSQL.equals(getDbType())) {
|
if (DataBaseConstant.DB_TYPE_MYSQL.equals(getDbType()) || DataBaseConstant.DB_TYPE_MARIADB.equals(getDbType())) {
|
||||||
String[] special_str = QueryGenerator.LIKE_MYSQL_SPECIAL_STRS.split(",");
|
String[] special_str = QueryGenerator.LIKE_MYSQL_SPECIAL_STRS.split(",");
|
||||||
for (String str : special_str) {
|
for (String str : special_str) {
|
||||||
if (value.indexOf(str) !=-1) {
|
if (value.indexOf(str) !=-1) {
|
||||||
|
|
|
@ -6,6 +6,11 @@ import com.auth0.jwt.algorithms.Algorithm;
|
||||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.DataBaseConstant;
|
import org.jeecg.common.constant.DataBaseConstant;
|
||||||
|
@ -16,10 +21,6 @@ import org.jeecg.common.util.DateUtils;
|
||||||
import org.jeecg.common.util.SpringContextUtils;
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author Scott
|
* @Author Scott
|
||||||
* @Date 2018-07-12 14:23
|
* @Date 2018-07-12 14:23
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
|
@ -74,7 +75,8 @@ public class CommonUtils {
|
||||||
fileName = fileName.substring(pos + 1);
|
fileName = fileName.substring(pos + 1);
|
||||||
}
|
}
|
||||||
//替换上传文件名字的特殊字符
|
//替换上传文件名字的特殊字符
|
||||||
fileName = fileName.replace("=","").replace(",","").replace("&","").replace("#", "");
|
fileName = fileName.replace("=","").replace(",","").replace("&","")
|
||||||
|
.replace("#", "").replace("“", "").replace("”", "");
|
||||||
//替换上传文件名字中的空格
|
//替换上传文件名字中的空格
|
||||||
fileName=fileName.replaceAll("\\s","");
|
fileName=fileName.replaceAll("\\s","");
|
||||||
return fileName;
|
return fileName;
|
||||||
|
@ -106,6 +108,44 @@ public class CommonUtils {
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 本地文件上传
|
||||||
|
* @param mf 文件
|
||||||
|
* @param bizPath 自定义路径
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String uploadLocal(MultipartFile mf,String bizPath,String uploadpath){
|
||||||
|
try {
|
||||||
|
String fileName = null;
|
||||||
|
File file = new File(uploadpath + File.separator + bizPath + File.separator );
|
||||||
|
if (!file.exists()) {
|
||||||
|
file.mkdirs();// 创建文件根目录
|
||||||
|
}
|
||||||
|
String orgName = mf.getOriginalFilename();// 获取文件名
|
||||||
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
|
if(orgName.indexOf(".")!=-1){
|
||||||
|
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||||
|
}else{
|
||||||
|
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
String savePath = file.getPath() + File.separator + fileName;
|
||||||
|
File savefile = new File(savePath);
|
||||||
|
FileCopyUtils.copy(mf.getBytes(), savefile);
|
||||||
|
String dbpath = null;
|
||||||
|
if(oConvertUtils.isNotEmpty(bizPath)){
|
||||||
|
dbpath = bizPath + File.separator + fileName;
|
||||||
|
}else{
|
||||||
|
dbpath = fileName;
|
||||||
|
}
|
||||||
|
if (dbpath.contains("\\")) {
|
||||||
|
dbpath = dbpath.replace("\\", "/");
|
||||||
|
}
|
||||||
|
return dbpath;
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一全局上传 带桶
|
* 统一全局上传 带桶
|
||||||
|
@ -132,7 +172,7 @@ public class CommonUtils {
|
||||||
return getDatabaseTypeByDataSource(dataSource);
|
return getDatabaseTypeByDataSource(dataSource);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
//e.printStackTrace();
|
//e.printStackTrace();
|
||||||
log.warn(e.getMessage());
|
log.warn(e.getMessage(),e);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,8 +197,11 @@ public class CommonUtils {
|
||||||
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
|
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
|
||||||
}else if(dbType.indexOf("postgresql")>=0) {
|
}else if(dbType.indexOf("postgresql")>=0) {
|
||||||
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
|
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
|
||||||
|
}else if(dbType.indexOf("mariadb")>=0) {
|
||||||
|
DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
|
||||||
}else {
|
}else {
|
||||||
throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
|
log.error("数据库类型:[" + dbType + "]不识别!");
|
||||||
|
//throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
|
|
|
@ -75,7 +75,11 @@ public class MinioUtil {
|
||||||
orgName=file.getName();
|
orgName=file.getName();
|
||||||
}
|
}
|
||||||
orgName = CommonUtils.getFileName(orgName);
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
String objectName = bizPath+"/"+orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
String objectName = bizPath+"/"
|
||||||
|
+( orgName.indexOf(".")==-1
|
||||||
|
?orgName + "_" + System.currentTimeMillis()
|
||||||
|
:orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."))
|
||||||
|
);
|
||||||
|
|
||||||
// 使用putObject上传一个本地文件到存储桶中。
|
// 使用putObject上传一个本地文件到存储桶中。
|
||||||
if(objectName.startsWith("/")){
|
if(objectName.startsWith("/")){
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
||||||
public class SqlUtils {
|
public class SqlUtils {
|
||||||
|
|
||||||
public static final String DATABSE_TYPE_MYSQL = "mysql";
|
public static final String DATABSE_TYPE_MYSQL = "mysql";
|
||||||
|
public static final String DATABSE_TYPE_MARIADB = "mariadb";
|
||||||
public static final String DATABSE_TYPE_POSTGRE = "postgresql";
|
public static final String DATABSE_TYPE_POSTGRE = "postgresql";
|
||||||
public static final String DATABSE_TYPE_ORACLE = "oracle";
|
public static final String DATABSE_TYPE_ORACLE = "oracle";
|
||||||
public static final String DATABSE_TYPE_SQLSERVER = "sqlserver";
|
public static final String DATABSE_TYPE_SQLSERVER = "sqlserver";
|
||||||
|
@ -47,7 +48,7 @@ public class SqlUtils {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static boolean dbTypeIsMySQL(String dbType) {
|
public static boolean dbTypeIsMySQL(String dbType) {
|
||||||
return dbTypeIf(dbType, DATABSE_TYPE_MYSQL, DataBaseConstant.DB_TYPE_MYSQL_NUM);
|
return dbTypeIf(dbType, DATABSE_TYPE_MYSQL, DataBaseConstant.DB_TYPE_MYSQL_NUM) || dbTypeIf(dbType, DATABSE_TYPE_MARIADB, DataBaseConstant.DB_TYPE_MARIADB_NUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean dbTypeIsOracle(String dbType) {
|
public static boolean dbTypeIsOracle(String dbType) {
|
||||||
|
|
|
@ -111,7 +111,9 @@ public class OssBootUtil {
|
||||||
orgName=file.getName();
|
orgName=file.getName();
|
||||||
}
|
}
|
||||||
orgName = CommonUtils.getFileName(orgName);
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
String fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
String fileName = orgName.indexOf(".")==-1
|
||||||
|
?orgName + "_" + System.currentTimeMillis()
|
||||||
|
:orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||||
if (!fileDir.endsWith("/")) {
|
if (!fileDir.endsWith("/")) {
|
||||||
fileDir = fileDir.concat("/");
|
fileDir = fileDir.concat("/");
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import springfox.documentation.service.*;
|
||||||
import springfox.documentation.spi.DocumentationType;
|
import springfox.documentation.spi.DocumentationType;
|
||||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||||
import springfox.documentation.spring.web.plugins.Docket;
|
import springfox.documentation.spring.web.plugins.Docket;
|
||||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -33,7 +33,7 @@ import java.util.List;
|
||||||
* @Author scott
|
* @Author scott
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableSwagger2
|
@EnableSwagger2WebMvc
|
||||||
@EnableKnife4j
|
@EnableKnife4j
|
||||||
@Import(BeanValidatorPluginsConfiguration.class)
|
@Import(BeanValidatorPluginsConfiguration.class)
|
||||||
public class Swagger2Config implements WebMvcConfigurer {
|
public class Swagger2Config implements WebMvcConfigurer {
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class OssConfiguration {
|
||||||
private String accessKeySecret;
|
private String accessKeySecret;
|
||||||
@Value("${jeecg.oss.bucketName}")
|
@Value("${jeecg.oss.bucketName}")
|
||||||
private String bucketName;
|
private String bucketName;
|
||||||
@Value("${jeecg.oss.staticDomain}")
|
@Value("${jeecg.oss.staticDomain:}")
|
||||||
private String staticDomain;
|
private String staticDomain;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.jeecg.config.shiro;
|
package org.jeecg.config.shiro;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||||
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
|
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
|
||||||
import org.apache.shiro.mgt.DefaultSubjectDAO;
|
import org.apache.shiro.mgt.DefaultSubjectDAO;
|
||||||
import org.apache.shiro.mgt.SecurityManager;
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
|
@ -110,6 +111,11 @@ public class ShiroConfig {
|
||||||
filterChainDefinitionMap.put("/webjars/**", "anon");
|
filterChainDefinitionMap.put("/webjars/**", "anon");
|
||||||
filterChainDefinitionMap.put("/v2/**", "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");
|
filterChainDefinitionMap.put("/jmreport/**", "anon");
|
||||||
filterChainDefinitionMap.put("/**/*.js.map", "anon");
|
filterChainDefinitionMap.put("/**/*.js.map", "anon");
|
||||||
|
@ -127,7 +133,7 @@ public class ShiroConfig {
|
||||||
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
|
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
|
||||||
filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
|
filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
|
||||||
filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
|
filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
|
||||||
filterChainDefinitionMap.put("/eoaSocket/**","anon");//我的聊天
|
|
||||||
|
|
||||||
//性能监控 TODO 存在安全漏洞泄露TOEKN(durid连接池也有)
|
//性能监控 TODO 存在安全漏洞泄露TOEKN(durid连接池也有)
|
||||||
filterChainDefinitionMap.put("/actuator/**", "anon");
|
filterChainDefinitionMap.put("/actuator/**", "anon");
|
||||||
|
@ -241,8 +247,17 @@ public class ShiroConfig {
|
||||||
RedisClusterManager redisManager = new RedisClusterManager();
|
RedisClusterManager redisManager = new RedisClusterManager();
|
||||||
Set<HostAndPort> portSet = new HashSet<>();
|
Set<HostAndPort> portSet = new HashSet<>();
|
||||||
lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));
|
lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));
|
||||||
JedisCluster jedisCluster = new JedisCluster(portSet);
|
//update-begin--Author:scott Date:20210531 for:修改集群模式下未设置redis密码的bug issues/I3QNIC
|
||||||
redisManager.setJedisCluster(jedisCluster);
|
if (oConvertUtils.isNotEmpty(lettuceConnectionFactory.getPassword())) {
|
||||||
|
JedisCluster jedisCluster = new JedisCluster(portSet, 2000, 2000, 5,
|
||||||
|
lettuceConnectionFactory.getPassword(), new GenericObjectPoolConfig());
|
||||||
|
redisManager.setPassword(lettuceConnectionFactory.getPassword());
|
||||||
|
redisManager.setJedisCluster(jedisCluster);
|
||||||
|
} else {
|
||||||
|
JedisCluster jedisCluster = new JedisCluster(portSet);
|
||||||
|
redisManager.setJedisCluster(jedisCluster);
|
||||||
|
}
|
||||||
|
//update-end--Author:scott Date:20210531 for:修改集群模式下未设置redis密码的bug issues/I3QNIC
|
||||||
manager = redisManager;
|
manager = redisManager;
|
||||||
}
|
}
|
||||||
return manager;
|
return manager;
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package org.jeecg.config.thirdapp;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方App对接配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class ThirdAppConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 钉钉
|
||||||
|
*/
|
||||||
|
public final static String DINGTALK = "DINGTALK";
|
||||||
|
/**
|
||||||
|
* 企业微信
|
||||||
|
*/
|
||||||
|
public final static String WECHAT_ENTERPRISE = "WECHAT_ENTERPRISE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用 第三方App对接
|
||||||
|
*/
|
||||||
|
@Value("${third-app.enabled:false}")
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统类型,目前支持:WECHAT_ENTERPRISE(企业微信);DINGTALK (钉钉)
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private ThirdAppTypeConfig type;
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThirdAppConfig setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取企业微信配置
|
||||||
|
*/
|
||||||
|
public ThirdAppTypeItemVo getWechatEnterprise() {
|
||||||
|
return this.type.getWECHAT_ENTERPRISE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取钉钉配置
|
||||||
|
*/
|
||||||
|
public ThirdAppTypeItemVo getDingtalk() {
|
||||||
|
return this.type.getDINGTALK();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取企业微信是否启用
|
||||||
|
*/
|
||||||
|
public boolean isWechatEnterpriseEnabled() {
|
||||||
|
try {
|
||||||
|
return this.enabled && this.getWechatEnterprise().isEnabled();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取钉钉是否启用
|
||||||
|
*/
|
||||||
|
public boolean isDingtalkEnabled() {
|
||||||
|
try {
|
||||||
|
return this.enabled && this.getDingtalk().isEnabled();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.jeecg.config.thirdapp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方APP配置
|
||||||
|
*
|
||||||
|
* @author sunjianlei
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "third-app.type")
|
||||||
|
public class ThirdAppTypeConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对应企业微信配置
|
||||||
|
*/
|
||||||
|
private ThirdAppTypeItemVo WECHAT_ENTERPRISE;
|
||||||
|
/**
|
||||||
|
* 对应钉钉配置
|
||||||
|
*/
|
||||||
|
private ThirdAppTypeItemVo DINGTALK;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.jeecg.config.thirdapp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方App对接
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ThirdAppTypeItemVo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
private boolean enabled;
|
||||||
|
/**
|
||||||
|
* 应用Key
|
||||||
|
*/
|
||||||
|
private String clientId;
|
||||||
|
/**
|
||||||
|
* 应用Secret
|
||||||
|
*/
|
||||||
|
private String clientSecret;
|
||||||
|
/**
|
||||||
|
* 应用ID
|
||||||
|
*/
|
||||||
|
private String agentId;
|
||||||
|
/**
|
||||||
|
* 目前仅企业微信用到:自建应用Secret
|
||||||
|
*/
|
||||||
|
private String agentAppSecret;
|
||||||
|
|
||||||
|
public int getAgentIdInt() {
|
||||||
|
return Integer.parseInt(agentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-boot-base</artifactId>
|
<artifactId>jeecg-boot-base</artifactId>
|
||||||
<version>2.4.3</version>
|
<version>2.4.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<description>公共模块</description>
|
<description>公共模块</description>
|
||||||
|
|
|
@ -81,4 +81,14 @@ public interface CacheConstant {
|
||||||
* online表单页配置信息缓存key
|
* online表单页配置信息缓存key
|
||||||
*/
|
*/
|
||||||
public static final String ONLINE_FORM = "sys:cache:online:form";
|
public static final String ONLINE_FORM = "sys:cache:online:form";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* online报表
|
||||||
|
*/
|
||||||
|
public static final String ONLINE_RP = "sys:cache:online:rp";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* online图表
|
||||||
|
*/
|
||||||
|
public static final String ONLINE_GRAPH = "sys:cache:online:graph";
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,11 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||||
@Bean
|
@Bean
|
||||||
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
|
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
|
||||||
log.info(" --- redis config init --- ");
|
log.info(" --- redis config init --- ");
|
||||||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =jacksonSerializer();
|
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = jacksonSerializer();
|
||||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
|
||||||
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
|
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||||
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
|
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
|
||||||
|
|
||||||
// key序列化
|
// key序列化
|
||||||
redisTemplate.setKeySerializer(stringSerializer);
|
redisTemplate.setKeySerializer(stringSerializer);
|
||||||
// value序列化
|
// value序列化
|
||||||
|
@ -98,10 +99,13 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public CacheManager cacheManager(LettuceConnectionFactory factory) {
|
public CacheManager cacheManager(LettuceConnectionFactory factory) {
|
||||||
// 配置序列化(缓存默认有效期 6小时)
|
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = jacksonSerializer();
|
||||||
|
// 配置序列化(解决乱码的问题),并且配置缓存默认有效期 6小时
|
||||||
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6));
|
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6));
|
||||||
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
|
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
|
||||||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
|
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
|
||||||
|
//.disableCachingNullValues();
|
||||||
|
|
||||||
// 以锁写入的方式创建RedisCacheWriter对象
|
// 以锁写入的方式创建RedisCacheWriter对象
|
||||||
//update-begin-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符*
|
//update-begin-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符*
|
||||||
RedisCacheWriter writer = new JeecgRedisCacheWriter(factory, Duration.ofMillis(50L));
|
RedisCacheWriter writer = new JeecgRedisCacheWriter(factory, Duration.ofMillis(50L));
|
||||||
|
@ -111,6 +115,9 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||||
//RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));
|
//RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));
|
||||||
/* 自定义配置test:demo 的超时时间为 5分钟*/
|
/* 自定义配置test:demo 的超时时间为 5分钟*/
|
||||||
RedisCacheManager cacheManager = RedisCacheManager.builder(writer).cacheDefaults(redisCacheConfiguration)
|
RedisCacheManager cacheManager = RedisCacheManager.builder(writer).cacheDefaults(redisCacheConfiguration)
|
||||||
|
.withInitialCacheConfigurations(singletonMap(CacheConstant.SYS_DICT_TABLE_CACHE,
|
||||||
|
RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)).disableCachingNullValues()
|
||||||
|
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))))
|
||||||
.withInitialCacheConfigurations(singletonMap(CacheConstant.TEST_DEMO_CACHE, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).disableCachingNullValues()))
|
.withInitialCacheConfigurations(singletonMap(CacheConstant.TEST_DEMO_CACHE, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).disableCachingNullValues()))
|
||||||
.withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_RANKING, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues()))
|
.withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_RANKING, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues()))
|
||||||
.withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_PAGE_LIST, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues()))
|
.withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_PAGE_LIST, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues()))
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-parent</artifactId>
|
<artifactId>jeecg-boot-parent</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.3</version>
|
<version>2.4.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jeecg-boot-parent</artifactId>
|
<artifactId>jeecg-boot-parent</artifactId>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<version>2.4.3</version>
|
<version>2.4.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,6 @@ WORKDIR /jeecg-boot
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
ADD ./target/jeecg-boot-module-system-2.4.3.jar ./
|
ADD ./target/jeecg-boot-module-system-2.4.5.jar ./
|
||||||
|
|
||||||
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-2.4.3.jar
|
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-2.4.5.jar
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-boot-parent</artifactId>
|
<artifactId>jeecg-boot-parent</artifactId>
|
||||||
<version>2.4.3</version>
|
<version>2.4.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -34,16 +34,21 @@
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-system-local-api</artifactId>
|
<artifactId>jeecg-system-local-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework</groupId>
|
||||||
|
<artifactId>jeewx-api</artifactId>
|
||||||
|
<version>1.4.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-boot-module-demo</artifactId>
|
<artifactId>jeecg-boot-module-demo</artifactId>
|
||||||
<version>${jeecgboot.version}</version>
|
<version>${jeecgboot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- 积木报表 -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.jimureport</groupId>
|
<groupId>org.jeecgframework.jimureport</groupId>
|
||||||
<artifactId>spring-boot-starter-jimureport</artifactId>
|
<artifactId>spring-boot-starter-jimureport</artifactId>
|
||||||
<version>1.3.1-beta4</version>
|
<version>1.3.3-beta</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.jeecgframework</groupId>
|
<groupId>org.jeecgframework</groupId>
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
package org.jeecg.modules.quartz.controller;
|
package org.jeecg.modules.quartz.controller;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import java.util.ArrayList;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import java.util.Arrays;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import java.util.List;
|
import io.swagger.annotations.Api;
|
||||||
import java.util.Map;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.exception.JeecgBootException;
|
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
import org.jeecg.common.util.ImportExcelUtil;
|
import org.jeecg.common.util.ImportExcelUtil;
|
||||||
import org.jeecg.modules.quartz.entity.QuartzJob;
|
import org.jeecg.modules.quartz.entity.QuartzJob;
|
||||||
|
@ -22,28 +18,21 @@ import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
import org.quartz.JobKey;
|
|
||||||
import org.quartz.Scheduler;
|
import org.quartz.Scheduler;
|
||||||
import org.quartz.SchedulerException;
|
import org.quartz.SchedulerException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import java.io.IOException;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import io.swagger.annotations.Api;
|
import java.util.List;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import java.util.Map;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 定时任务在线管理
|
* @Description: 定时任务在线管理
|
||||||
|
@ -89,10 +78,6 @@ public class QuartzJobController {
|
||||||
//@RequiresRoles("admin")
|
//@RequiresRoles("admin")
|
||||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||||
public Result<?> add(@RequestBody QuartzJob quartzJob) {
|
public Result<?> add(@RequestBody QuartzJob quartzJob) {
|
||||||
List<QuartzJob> list = quartzJobService.findByJobClassName(quartzJob.getJobClassName());
|
|
||||||
if (list != null && list.size() > 0) {
|
|
||||||
return Result.error("该定时任务类名已存在");
|
|
||||||
}
|
|
||||||
quartzJobService.saveAndScheduleJob(quartzJob);
|
quartzJobService.saveAndScheduleJob(quartzJob);
|
||||||
return Result.ok("创建定时任务成功");
|
return Result.ok("创建定时任务成功");
|
||||||
}
|
}
|
||||||
|
@ -155,15 +140,14 @@ public class QuartzJobController {
|
||||||
/**
|
/**
|
||||||
* 暂停定时任务
|
* 暂停定时任务
|
||||||
*
|
*
|
||||||
* @param jobClassName
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
//@RequiresRoles("admin")
|
//@RequiresRoles("admin")
|
||||||
@GetMapping(value = "/pause")
|
@GetMapping(value = "/pause")
|
||||||
@ApiOperation(value = "暂停定时任务")
|
@ApiOperation(value = "暂停定时任务")
|
||||||
public Result<Object> pauseJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
|
public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
|
||||||
QuartzJob job = null;
|
QuartzJob job = quartzJobService.getById(id);
|
||||||
job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
|
|
||||||
if (job == null) {
|
if (job == null) {
|
||||||
return Result.error("定时任务不存在!");
|
return Result.error("定时任务不存在!");
|
||||||
}
|
}
|
||||||
|
@ -174,14 +158,14 @@ public class QuartzJobController {
|
||||||
/**
|
/**
|
||||||
* 启动定时任务
|
* 启动定时任务
|
||||||
*
|
*
|
||||||
* @param jobClassName
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
//@RequiresRoles("admin")
|
//@RequiresRoles("admin")
|
||||||
@GetMapping(value = "/resume")
|
@GetMapping(value = "/resume")
|
||||||
@ApiOperation(value = "恢复定时任务")
|
@ApiOperation(value = "恢复定时任务")
|
||||||
public Result<Object> resumeJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
|
public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
|
||||||
QuartzJob job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
|
QuartzJob job = quartzJobService.getById(id);
|
||||||
if (job == null) {
|
if (job == null) {
|
||||||
return Result.error("定时任务不存在!");
|
return Result.error("定时任务不存在!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class SampleParamJob implements Job {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||||
|
log.info(" Job Execution key:"+jobExecutionContext.getJobDetail().getKey());
|
||||||
log.info(String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
|
log.info( String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package org.jeecg.modules.quartz.service.impl;
|
package org.jeecg.modules.quartz.service.impl;
|
||||||
|
|
||||||
import java.util.Date;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import java.util.List;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.exception.JeecgBootException;
|
import org.jeecg.common.exception.JeecgBootException;
|
||||||
import org.jeecg.common.util.DateUtils;
|
import org.jeecg.common.util.DateUtils;
|
||||||
|
@ -13,9 +12,8 @@ import org.quartz.*;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 定时任务在线管理
|
* @Description: 定时任务在线管理
|
||||||
|
@ -46,13 +44,16 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean saveAndScheduleJob(QuartzJob quartzJob) {
|
public boolean saveAndScheduleJob(QuartzJob quartzJob) {
|
||||||
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
|
||||||
// 定时器添加
|
|
||||||
this.schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
|
||||||
}
|
|
||||||
// DB设置修改
|
// DB设置修改
|
||||||
quartzJob.setDelFlag(CommonConstant.DEL_FLAG_0);
|
quartzJob.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||||
return this.save(quartzJob);
|
boolean success = this.save(quartzJob);
|
||||||
|
if (success) {
|
||||||
|
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
||||||
|
// 定时器添加
|
||||||
|
this.schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,8 +61,8 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean resumeJob(QuartzJob quartzJob) {
|
public boolean resumeJob(QuartzJob quartzJob) {
|
||||||
schedulerDelete(quartzJob.getJobClassName().trim());
|
schedulerDelete(quartzJob.getId());
|
||||||
schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||||
quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
|
quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
|
||||||
return this.updateById(quartzJob);
|
return this.updateById(quartzJob);
|
||||||
}
|
}
|
||||||
|
@ -73,10 +74,10 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||||
@Override
|
@Override
|
||||||
public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
|
public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
|
||||||
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
||||||
schedulerDelete(quartzJob.getJobClassName().trim());
|
schedulerDelete(quartzJob.getId());
|
||||||
schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||||
}else{
|
}else{
|
||||||
scheduler.pauseJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));
|
scheduler.pauseJob(JobKey.jobKey(quartzJob.getId()));
|
||||||
}
|
}
|
||||||
return this.updateById(quartzJob);
|
return this.updateById(quartzJob);
|
||||||
}
|
}
|
||||||
|
@ -86,7 +87,7 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteAndStopJob(QuartzJob job) {
|
public boolean deleteAndStopJob(QuartzJob job) {
|
||||||
schedulerDelete(job.getJobClassName().trim());
|
schedulerDelete(job.getId());
|
||||||
boolean ok = this.removeById(job.getId());
|
boolean ok = this.removeById(job.getId());
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +99,9 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||||
String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
|
String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
|
||||||
String identity = jobName + ymd;
|
String identity = jobName + ymd;
|
||||||
//3秒后执行 只执行一次
|
//3秒后执行 只执行一次
|
||||||
startDate.setTime(startDate.getTime()+3000L);
|
// update-begin--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||||
|
startDate.setTime(startDate.getTime() + 100L);
|
||||||
|
// update-end--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||||
// 定义一个Trigger
|
// 定义一个Trigger
|
||||||
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
|
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
|
||||||
.withIdentity(identity, JOB_TEST_GROUP)
|
.withIdentity(identity, JOB_TEST_GROUP)
|
||||||
|
@ -114,31 +117,31 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pause(QuartzJob quartzJob){
|
public void pause(QuartzJob quartzJob){
|
||||||
schedulerDelete(quartzJob.getJobClassName().trim());
|
schedulerDelete(quartzJob.getId());
|
||||||
quartzJob.setStatus(CommonConstant.STATUS_DISABLE);
|
quartzJob.setStatus(CommonConstant.STATUS_DISABLE);
|
||||||
this.updateById(quartzJob);
|
this.updateById(quartzJob);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加定时任务
|
* 添加定时任务
|
||||||
*
|
*
|
||||||
* @param jobClassName
|
* @param jobClassName
|
||||||
* @param cronExpression
|
* @param cronExpression
|
||||||
* @param parameter
|
* @param parameter
|
||||||
*/
|
*/
|
||||||
private void schedulerAdd(String jobClassName, String cronExpression, String parameter) {
|
private void schedulerAdd(String id, String jobClassName, String cronExpression, String parameter) {
|
||||||
try {
|
try {
|
||||||
// 启动调度器
|
// 启动调度器
|
||||||
scheduler.start();
|
scheduler.start();
|
||||||
|
|
||||||
// 构建job信息
|
// 构建job信息
|
||||||
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName).usingJobData("parameter", parameter).build();
|
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(id).usingJobData("parameter", parameter).build();
|
||||||
|
|
||||||
// 表达式调度构建器(即任务执行的时间)
|
// 表达式调度构建器(即任务执行的时间)
|
||||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
|
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
|
||||||
|
|
||||||
// 按新的cronExpression表达式构建一个新的trigger
|
// 按新的cronExpression表达式构建一个新的trigger
|
||||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build();
|
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(id).withSchedule(scheduleBuilder).build();
|
||||||
|
|
||||||
scheduler.scheduleJob(jobDetail, trigger);
|
scheduler.scheduleJob(jobDetail, trigger);
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
|
@ -153,13 +156,13 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||||
/**
|
/**
|
||||||
* 删除定时任务
|
* 删除定时任务
|
||||||
*
|
*
|
||||||
* @param jobClassName
|
* @param id
|
||||||
*/
|
*/
|
||||||
private void schedulerDelete(String jobClassName) {
|
private void schedulerDelete(String id) {
|
||||||
try {
|
try {
|
||||||
scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
|
scheduler.pauseTrigger(TriggerKey.triggerKey(id));
|
||||||
scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
|
scheduler.unscheduleJob(TriggerKey.triggerKey(id));
|
||||||
scheduler.deleteJob(JobKey.jobKey(jobClassName));
|
scheduler.deleteJob(JobKey.jobKey(id));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
throw new JeecgBootException("删除定时任务失败");
|
throw new JeecgBootException("删除定时任务失败");
|
||||||
|
|
|
@ -133,7 +133,7 @@ public class CommonController {
|
||||||
String orgName = mf.getOriginalFilename();// 获取文件名
|
String orgName = mf.getOriginalFilename();// 获取文件名
|
||||||
orgName = CommonUtils.getFileName(orgName);
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
if(orgName.indexOf(".")!=-1){
|
if(orgName.indexOf(".")!=-1){
|
||||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||||
}else{
|
}else{
|
||||||
fileName = orgName+ "_" + System.currentTimeMillis();
|
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +1,54 @@
|
||||||
package org.jeecg.modules.system.controller;
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
|
||||||
import org.jeecg.common.api.vo.Result;
|
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
|
||||||
import org.jeecg.common.constant.CommonSendStatus;
|
|
||||||
import org.jeecg.common.constant.WebsocketConst;
|
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
|
||||||
import org.jeecg.common.system.util.JwtUtil;
|
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
|
||||||
import org.jeecg.modules.message.websocket.WebSocket;
|
|
||||||
import org.jeecg.modules.system.entity.SysAnnouncement;
|
|
||||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
|
||||||
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
|
||||||
import org.jeecg.modules.system.service.ISysAnnouncementService;
|
|
||||||
|
|
||||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
|
||||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
|
||||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
|
||||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
|
||||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.jeecg.dingtalk.api.core.response.Response;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.constant.CommonSendStatus;
|
||||||
|
import org.jeecg.common.constant.WebsocketConst;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.common.util.RedisUtil;
|
||||||
|
import org.jeecg.common.util.TokenUtils;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.message.websocket.WebSocket;
|
||||||
|
import org.jeecg.modules.system.entity.SysAnnouncement;
|
||||||
|
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||||
|
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
||||||
|
import org.jeecg.modules.system.service.ISysAnnouncementService;
|
||||||
|
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
|
||||||
|
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.jeecg.common.constant.CommonConstant.ANNOUNCEMENT_SEND_STATUS_1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Title: Controller
|
* @Title: Controller
|
||||||
|
@ -67,6 +67,15 @@ public class SysAnnouncementController {
|
||||||
private ISysAnnouncementSendService sysAnnouncementSendService;
|
private ISysAnnouncementSendService sysAnnouncementSendService;
|
||||||
@Resource
|
@Resource
|
||||||
private WebSocket webSocket;
|
private WebSocket webSocket;
|
||||||
|
@Autowired
|
||||||
|
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||||
|
@Autowired
|
||||||
|
ThirdAppDingtalkServiceImpl dingtalkService;
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseAPI;
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private RedisUtil redisUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页列表查询
|
* 分页列表查询
|
||||||
|
@ -242,6 +251,19 @@ public class SysAnnouncementController {
|
||||||
obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
|
obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
|
||||||
webSocket.sendMessage(userIds, obj.toJSONString());
|
webSocket.sendMessage(userIds, obj.toJSONString());
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
// 同步企业微信、钉钉的消息通知
|
||||||
|
Response<String> dtResponse = dingtalkService.sendActionCardMessage(sysAnnouncement, true);
|
||||||
|
wechatEnterpriseService.sendTextCardMessage(sysAnnouncement, true);
|
||||||
|
|
||||||
|
if (dtResponse != null && dtResponse.isSuccess()) {
|
||||||
|
String taskId = dtResponse.getResult();
|
||||||
|
sysAnnouncement.setDtTaskId(taskId);
|
||||||
|
sysAnnouncementService.updateById(sysAnnouncement);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("同步发送第三方APP消息失败:", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,6 +287,13 @@ public class SysAnnouncementController {
|
||||||
boolean ok = sysAnnouncementService.updateById(sysAnnouncement);
|
boolean ok = sysAnnouncementService.updateById(sysAnnouncement);
|
||||||
if(ok) {
|
if(ok) {
|
||||||
result.success("该系统通知撤销成功");
|
result.success("该系统通知撤销成功");
|
||||||
|
if (oConvertUtils.isNotEmpty(sysAnnouncement.getDtTaskId())) {
|
||||||
|
try {
|
||||||
|
dingtalkService.recallMessage(sysAnnouncement.getDtTaskId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("第三方APP撤回消息失败:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,4 +452,33 @@ public class SysAnnouncementController {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通告查看详情页面(用于第三方APP)
|
||||||
|
* @param modelAndView
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/show/{id}")
|
||||||
|
public ModelAndView showContent(ModelAndView modelAndView, @PathVariable("id") String id, HttpServletRequest request) {
|
||||||
|
SysAnnouncement announcement = sysAnnouncementService.getById(id);
|
||||||
|
if (announcement != null) {
|
||||||
|
boolean tokenOK = false;
|
||||||
|
try {
|
||||||
|
// 验证Token有效性
|
||||||
|
tokenOK = TokenUtils.verifyToken(request, sysBaseAPI, redisUtil);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
// 判断是否传递了Token,并且Token有效,如果传了就不做查看限制,直接返回
|
||||||
|
// 如果Token无效,就做查看限制:只能查看已发布的
|
||||||
|
if (tokenOK || ANNOUNCEMENT_SEND_STATUS_1.equals(announcement.getSendStatus())) {
|
||||||
|
modelAndView.addObject("data", announcement);
|
||||||
|
modelAndView.setViewName("announcement/showContent");
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modelAndView.setStatus(HttpStatus.NOT_FOUND);
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,10 +409,11 @@ public class SysCategoryController {
|
||||||
* 分类字典控件数据回显[表单页面]
|
* 分类字典控件数据回显[表单页面]
|
||||||
*
|
*
|
||||||
* @param ids
|
* @param ids
|
||||||
|
* @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/loadDictItem", method = RequestMethod.GET)
|
@RequestMapping(value = "/loadDictItem", method = RequestMethod.GET)
|
||||||
public Result<List<String>> loadDictItem(@RequestParam(name = "ids") String ids) {
|
public Result<List<String>> loadDictItem(@RequestParam(name = "ids") String ids, @RequestParam(name = "delNotExist", required = false, defaultValue = "true") boolean delNotExist) {
|
||||||
Result<List<String>> result = new Result<>();
|
Result<List<String>> result = new Result<>();
|
||||||
// 非空判断
|
// 非空判断
|
||||||
if (StringUtils.isBlank(ids)) {
|
if (StringUtils.isBlank(ids)) {
|
||||||
|
@ -420,13 +421,8 @@ public class SysCategoryController {
|
||||||
result.setMessage("ids 不能为空");
|
result.setMessage("ids 不能为空");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
String[] idArray = ids.split(",");
|
|
||||||
LambdaQueryWrapper<SysCategory> query = new LambdaQueryWrapper<>();
|
|
||||||
query.in(SysCategory::getId, Arrays.asList(idArray));
|
|
||||||
// 查询数据
|
// 查询数据
|
||||||
List<SysCategory> list = this.sysCategoryService.list(query);
|
List<String> textList = sysCategoryService.loadDictItem(ids, delNotExist);
|
||||||
// 取出name并返回
|
|
||||||
List<String> textList = list.stream().map(SysCategory::getName).collect(Collectors.toList());
|
|
||||||
result.setSuccess(true);
|
result.setSuccess(true);
|
||||||
result.setResult(textList);
|
result.setResult(textList);
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
package org.jeecg.modules.system.controller;
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
@ -23,28 +20,25 @@ import org.jeecg.modules.system.entity.SysUser;
|
||||||
import org.jeecg.modules.system.model.DepartIdModel;
|
import org.jeecg.modules.system.model.DepartIdModel;
|
||||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||||
import org.jeecg.modules.system.service.ISysDepartService;
|
import org.jeecg.modules.system.service.ISysDepartService;
|
||||||
import org.jeecg.modules.system.service.ISysPositionService;
|
|
||||||
import org.jeecg.modules.system.service.ISysUserDepartService;
|
import org.jeecg.modules.system.service.ISysUserDepartService;
|
||||||
import org.jeecg.modules.system.service.ISysUserService;
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
import org.jeecg.modules.system.util.FindsDepartsChildrenUtil;
|
|
||||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -132,6 +126,33 @@ public class SysDepartController {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取某个部门的所有父级部门的ID
|
||||||
|
*
|
||||||
|
* @param departId 根据departId查
|
||||||
|
* @param orgCode 根据orgCode查,departId和orgCode必须有一个不为空
|
||||||
|
*/
|
||||||
|
@GetMapping("/queryAllParentId")
|
||||||
|
public Result queryParentIds(
|
||||||
|
@RequestParam(name = "departId", required = false) String departId,
|
||||||
|
@RequestParam(name = "orgCode", required = false) String orgCode
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
JSONObject data;
|
||||||
|
if (oConvertUtils.isNotEmpty(departId)) {
|
||||||
|
data = sysDepartService.queryAllParentIdByDepartId(departId);
|
||||||
|
} else if (oConvertUtils.isNotEmpty(orgCode)) {
|
||||||
|
data = sysDepartService.queryAllParentIdByOrgCode(orgCode);
|
||||||
|
} else {
|
||||||
|
return Result.error("departId 和 orgCode 不能都为空!");
|
||||||
|
}
|
||||||
|
return Result.OK(data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加新数据 添加用户新建的部门对象数据,并保存到数据库
|
* 添加新数据 添加用户新建的部门对象数据,并保存到数据库
|
||||||
*
|
*
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
import org.jeecgframework.poi.excel.entity.result.ExcelImportResult;
|
|
||||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -122,44 +121,20 @@ public class SysDictController {
|
||||||
public Result<List<DictModel>> getDictItems(@PathVariable String dictCode, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
|
public Result<List<DictModel>> getDictItems(@PathVariable String dictCode, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
|
||||||
log.info(" dictCode : "+ dictCode);
|
log.info(" dictCode : "+ dictCode);
|
||||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||||
List<DictModel> ls = null;
|
|
||||||
try {
|
try {
|
||||||
if(dictCode.indexOf(",")!=-1) {
|
List<DictModel> ls = sysDictService.getDictItems(dictCode);
|
||||||
//关联表字典(举例:sys_user,realname,id)
|
if (ls == null) {
|
||||||
String[] params = dictCode.split(",");
|
result.error500("字典Code格式不正确!");
|
||||||
|
return result;
|
||||||
if(params.length<3) {
|
|
||||||
result.error500("字典Code格式不正确!");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
//SQL注入校验(只限制非法串改数据库)
|
|
||||||
final String[] sqlInjCheck = {params[0],params[1],params[2]};
|
|
||||||
SqlInjectionUtil.filterContent(sqlInjCheck);
|
|
||||||
|
|
||||||
if(params.length==4) {
|
|
||||||
//SQL注入校验(查询条件SQL 特殊check,此方法仅供此处使用)
|
|
||||||
SqlInjectionUtil.specialFilterContent(params[3]);
|
|
||||||
ls = sysDictService.queryTableDictItemsByCodeAndFilter(params[0],params[1],params[2],params[3]);
|
|
||||||
}else if (params.length==3) {
|
|
||||||
ls = sysDictService.queryTableDictItemsByCode(params[0],params[1],params[2]);
|
|
||||||
}else{
|
|
||||||
result.error500("字典Code格式不正确!");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
//字典表
|
|
||||||
ls = sysDictService.queryDictItemsByCode(dictCode);
|
|
||||||
}
|
}
|
||||||
|
result.setSuccess(true);
|
||||||
result.setSuccess(true);
|
result.setResult(ls);
|
||||||
result.setResult(ls);
|
log.debug(result.toString());
|
||||||
log.debug(result.toString());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(),e);
|
log.error(e.getMessage(), e);
|
||||||
result.error500("操作失败");
|
result.error500("操作失败");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,8 +173,9 @@ public class SysDictController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 【JSearchSelectTag下拉搜索组件专用接口】
|
||||||
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||||
* @param dictCode
|
* @param dictCode 字典code格式:table,text,code
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/loadDict/{dictCode}", method = RequestMethod.GET)
|
@RequestMapping(value = "/loadDict/{dictCode}", method = RequestMethod.GET)
|
||||||
|
@ -209,39 +185,75 @@ public class SysDictController {
|
||||||
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
||||||
log.info(" 加载字典表数据,加载关键字: "+ keyword);
|
log.info(" 加载字典表数据,加载关键字: "+ keyword);
|
||||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||||
List<DictModel> ls = null;
|
|
||||||
try {
|
try {
|
||||||
if(dictCode.indexOf(",")!=-1) {
|
List<DictModel> ls = sysDictService.loadDict(dictCode, keyword, pageSize);
|
||||||
String[] params = dictCode.split(",");
|
if (ls == null) {
|
||||||
if(params.length!=3) {
|
|
||||||
result.error500("字典Code格式不正确!");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if(pageSize!=null){
|
|
||||||
ls = sysDictService.queryLittleTableDictItems(params[0],params[1],params[2],keyword, pageSize);
|
|
||||||
}else{
|
|
||||||
ls = sysDictService.queryTableDictItems(params[0],params[1],params[2],keyword);
|
|
||||||
}
|
|
||||||
result.setSuccess(true);
|
|
||||||
result.setResult(ls);
|
|
||||||
log.info(result.toString());
|
|
||||||
}else {
|
|
||||||
result.error500("字典Code格式不正确!");
|
result.error500("字典Code格式不正确!");
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
result.setSuccess(true);
|
||||||
|
result.setResult(ls);
|
||||||
|
log.info(result.toString());
|
||||||
|
return result;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(),e);
|
log.error(e.getMessage(),e);
|
||||||
result.error500("操作失败");
|
result.error500("操作失败");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【给表单设计器的表字典使用】下拉搜索模式,有值时动态拼接数据
|
||||||
|
* @param dictCode
|
||||||
|
* @param keyword 当前控件的值,可以逗号分割
|
||||||
|
* @param sign
|
||||||
|
* @param pageSize
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "/loadDictOrderByValue/{dictCode}", method = RequestMethod.GET)
|
||||||
|
public Result<List<DictModel>> loadDictOrderByValue(
|
||||||
|
@PathVariable String dictCode,
|
||||||
|
@RequestParam(name = "keyword") String keyword,
|
||||||
|
@RequestParam(value = "sign", required = false) String sign,
|
||||||
|
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
||||||
|
// 首次查询查出来用户选中的值,并且不分页
|
||||||
|
Result<List<DictModel>> firstRes = this.loadDict(dictCode, keyword, sign, null);
|
||||||
|
if (!firstRes.isSuccess()) {
|
||||||
|
return firstRes;
|
||||||
|
}
|
||||||
|
// 然后再查询出第一页的数据
|
||||||
|
Result<List<DictModel>> result = this.loadDict(dictCode, "", sign, pageSize);
|
||||||
|
if (!result.isSuccess()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// 合并两次查询的数据
|
||||||
|
List<DictModel> firstList = firstRes.getResult();
|
||||||
|
List<DictModel> list = result.getResult();
|
||||||
|
for (DictModel firstItem : firstList) {
|
||||||
|
// anyMatch 表示:判断的条件里,任意一个元素匹配成功,返回true
|
||||||
|
// allMatch 表示:判断条件里的元素,所有的都匹配成功,返回true
|
||||||
|
// noneMatch 跟 allMatch 相反,表示:判断条件里的元素,所有的都匹配失败,返回true
|
||||||
|
boolean none = list.stream().noneMatch(item -> item.getValue().equals(firstItem.getValue()));
|
||||||
|
// 当元素不存在时,再添加到集合里
|
||||||
|
if (none) {
|
||||||
|
list.add(0, firstItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
* 根据字典code加载字典text 返回
|
* 根据字典code加载字典text 返回
|
||||||
|
* @param dictCode 顺序:tableName,text,code
|
||||||
|
* @param keys 要查询的key
|
||||||
|
* @param sign
|
||||||
|
* @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/loadDictItem/{dictCode}", method = RequestMethod.GET)
|
@RequestMapping(value = "/loadDictItem/{dictCode}", method = RequestMethod.GET)
|
||||||
public Result<List<String>> loadDictItem(@PathVariable String dictCode,@RequestParam(name="key") String keys, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
|
public Result<List<String>> loadDictItem(@PathVariable String dictCode,@RequestParam(name="key") String keys, @RequestParam(value = "sign",required = false) String sign,@RequestParam(value = "delNotExist",required = false,defaultValue = "true") boolean delNotExist,HttpServletRequest request) {
|
||||||
Result<List<String>> result = new Result<>();
|
Result<List<String>> result = new Result<>();
|
||||||
try {
|
try {
|
||||||
if(dictCode.indexOf(",")!=-1) {
|
if(dictCode.indexOf(",")!=-1) {
|
||||||
|
@ -250,7 +262,7 @@ public class SysDictController {
|
||||||
result.error500("字典Code格式不正确!");
|
result.error500("字典Code格式不正确!");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
List<String> texts = sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys);
|
List<String> texts = sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys, delNotExist);
|
||||||
|
|
||||||
result.setSuccess(true);
|
result.setSuccess(true);
|
||||||
result.setResult(texts);
|
result.setResult(texts);
|
||||||
|
@ -407,12 +419,14 @@ public class SysDictController {
|
||||||
//清空字典缓存
|
//清空字典缓存
|
||||||
Set keys = redisTemplate.keys(CacheConstant.SYS_DICT_CACHE + "*");
|
Set keys = redisTemplate.keys(CacheConstant.SYS_DICT_CACHE + "*");
|
||||||
Set keys2 = redisTemplate.keys(CacheConstant.SYS_DICT_TABLE_CACHE + "*");
|
Set keys2 = redisTemplate.keys(CacheConstant.SYS_DICT_TABLE_CACHE + "*");
|
||||||
|
Set keys21 = redisTemplate.keys(CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE + "*");
|
||||||
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||||
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||||
Set keys5 = redisTemplate.keys( "jmreport:cache:dict*");
|
Set keys5 = redisTemplate.keys( "jmreport:cache:dict*");
|
||||||
Set keys6 = redisTemplate.keys( "jmreport:cache:dictTable*");
|
Set keys6 = redisTemplate.keys( "jmreport:cache:dictTable*");
|
||||||
redisTemplate.delete(keys);
|
redisTemplate.delete(keys);
|
||||||
redisTemplate.delete(keys2);
|
redisTemplate.delete(keys2);
|
||||||
|
redisTemplate.delete(keys21);
|
||||||
redisTemplate.delete(keys3);
|
redisTemplate.delete(keys3);
|
||||||
redisTemplate.delete(keys4);
|
redisTemplate.delete(keys4);
|
||||||
redisTemplate.delete(keys5);
|
redisTemplate.delete(keys5);
|
||||||
|
|
|
@ -145,8 +145,8 @@ public class SysUserController {
|
||||||
user.setPassword(passwordEncode);
|
user.setPassword(passwordEncode);
|
||||||
user.setStatus(1);
|
user.setStatus(1);
|
||||||
user.setDelFlag(CommonConstant.DEL_FLAG_0);
|
user.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||||
sysUserService.addUserWithRole(user, selectedRoles);
|
// 保存用户走一个service 保证事务
|
||||||
sysUserService.addUserWithDepart(user, selectedDeparts);
|
sysUserService.saveUser(user, selectedRoles, selectedDeparts);
|
||||||
result.success("添加成功!");
|
result.success("添加成功!");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
|
@ -172,9 +172,8 @@ public class SysUserController {
|
||||||
user.setPassword(sysUser.getPassword());
|
user.setPassword(sysUser.getPassword());
|
||||||
String roles = jsonObject.getString("selectedroles");
|
String roles = jsonObject.getString("selectedroles");
|
||||||
String departs = jsonObject.getString("selecteddeparts");
|
String departs = jsonObject.getString("selecteddeparts");
|
||||||
sysUserService.editUserWithRole(user, roles);
|
// 修改用户走一个service 保证事务
|
||||||
sysUserService.editUserWithDepart(user, departs);
|
sysUserService.editUser(user, roles, departs);
|
||||||
sysUserService.updateNullPhoneEmail();
|
|
||||||
result.success("修改成功!");
|
result.success("修改成功!");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -279,6 +278,7 @@ public class SysUserController {
|
||||||
result.setResult(true);
|
result.setResult(true);
|
||||||
try {
|
try {
|
||||||
//通过传入信息查询新的用户信息
|
//通过传入信息查询新的用户信息
|
||||||
|
sysUser.setPassword(null);
|
||||||
SysUser user = sysUserService.getOne(new QueryWrapper<SysUser>(sysUser));
|
SysUser user = sysUserService.getOne(new QueryWrapper<SysUser>(sysUser));
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
result.setSuccess(false);
|
result.setSuccess(false);
|
||||||
|
@ -298,6 +298,7 @@ public class SysUserController {
|
||||||
/**
|
/**
|
||||||
* 修改密码
|
* 修改密码
|
||||||
*/
|
*/
|
||||||
|
//@RequiresRoles({"admin"})
|
||||||
@RequestMapping(value = "/changePassword", method = RequestMethod.PUT)
|
@RequestMapping(value = "/changePassword", method = RequestMethod.PUT)
|
||||||
public Result<?> changePassword(@RequestBody SysUser sysUser) {
|
public Result<?> changePassword(@RequestBody SysUser sysUser) {
|
||||||
SysUser u = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysUser.getUsername()));
|
SysUser u = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysUser.getUsername()));
|
||||||
|
@ -388,6 +389,23 @@ public class SysUserController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户选择组件 专用 根据用户账号或部门分页查询
|
||||||
|
* @param departId
|
||||||
|
* @param username
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "/queryUserComponentData", method = RequestMethod.GET)
|
||||||
|
public Result<IPage<SysUser>> queryUserComponentData(
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
@RequestParam(name = "departId", required = false) String departId,
|
||||||
|
@RequestParam(name="realname",required=false) String realname,
|
||||||
|
@RequestParam(name="username",required=false) String username) {
|
||||||
|
IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出excel
|
* 导出excel
|
||||||
*
|
*
|
||||||
|
@ -521,13 +539,17 @@ public class SysUserController {
|
||||||
/**
|
/**
|
||||||
* 首页用户重置密码
|
* 首页用户重置密码
|
||||||
*/
|
*/
|
||||||
//@RequiresRoles({"admin"})
|
//@RequiresRoles({"admin"})
|
||||||
@RequestMapping(value = "/updatePassword", method = RequestMethod.PUT)
|
@RequestMapping(value = "/updatePassword", method = RequestMethod.PUT)
|
||||||
public Result<?> changPassword(@RequestBody JSONObject json) {
|
public Result<?> updatePassword(@RequestBody JSONObject json) {
|
||||||
String username = json.getString("username");
|
String username = json.getString("username");
|
||||||
String oldpassword = json.getString("oldpassword");
|
String oldpassword = json.getString("oldpassword");
|
||||||
String password = json.getString("password");
|
String password = json.getString("password");
|
||||||
String confirmpassword = json.getString("confirmpassword");
|
String confirmpassword = json.getString("confirmpassword");
|
||||||
|
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||||
|
if(!sysUser.getUsername().equals(username)){
|
||||||
|
return Result.error("只允许修改自己的密码!");
|
||||||
|
}
|
||||||
SysUser user = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
|
SysUser user = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
|
||||||
if(user==null) {
|
if(user==null) {
|
||||||
return Result.error("用户不存在!");
|
return Result.error("用户不存在!");
|
||||||
|
@ -1338,4 +1360,6 @@ public class SysUserController {
|
||||||
sysUserService.updateById(user);
|
sysUserService.updateById(user);
|
||||||
return Result.ok("手机号设置成功!");
|
return Result.ok("手机号设置成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,261 @@
|
||||||
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.jeecg.dingtalk.api.core.response.Response;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.config.thirdapp.ThirdAppConfig;
|
||||||
|
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
|
||||||
|
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
|
||||||
|
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方App对接
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController("thirdAppController")
|
||||||
|
@RequestMapping("/sys/thirdApp")
|
||||||
|
public class ThirdAppController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ThirdAppConfig thirdAppConfig;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||||
|
@Autowired
|
||||||
|
ThirdAppDingtalkServiceImpl dingtalkService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取启用的系统
|
||||||
|
*/
|
||||||
|
@GetMapping("/getEnabledType")
|
||||||
|
public Result getEnabledType() {
|
||||||
|
Map<String, Boolean> enabledMap = new HashMap<>();
|
||||||
|
enabledMap.put("wechatEnterprise", thirdAppConfig.isWechatEnterpriseEnabled());
|
||||||
|
enabledMap.put("dingtalk", thirdAppConfig.isDingtalkEnabled());
|
||||||
|
return Result.OK(enabledMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步本地[用户]到【企业微信】
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sync/wechatEnterprise/user/toApp")
|
||||||
|
public Result syncWechatEnterpriseUserToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||||
|
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||||
|
SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalUserToThirdApp(ids);
|
||||||
|
if (syncInfo.getFailInfo().size() == 0) {
|
||||||
|
return Result.OK("同步成功", syncInfo);
|
||||||
|
} else {
|
||||||
|
return Result.error("同步失败", syncInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.error("企业微信同步功能已禁用");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步【企业微信】[用户]到本地
|
||||||
|
*
|
||||||
|
* @param ids 作废
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sync/wechatEnterprise/user/toLocal")
|
||||||
|
public Result syncWechatEnterpriseUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
|
||||||
|
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||||
|
SyncInfoVo syncInfo = wechatEnterpriseService.syncThirdAppUserToLocal();
|
||||||
|
if (syncInfo.getFailInfo().size() == 0) {
|
||||||
|
return Result.OK("同步成功", syncInfo);
|
||||||
|
} else {
|
||||||
|
return Result.error("同步失败", syncInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.error("企业微信同步功能已禁用");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步本地[部门]到【企业微信】
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sync/wechatEnterprise/depart/toApp")
|
||||||
|
public Result syncWechatEnterpriseDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||||
|
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||||
|
boolean flag = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
|
||||||
|
return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
|
||||||
|
}
|
||||||
|
return Result.error("企业微信同步功能已禁用");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步【企业微信】[部门]到本地
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sync/wechatEnterprise/depart/toLocal")
|
||||||
|
public Result syncWechatEnterpriseDepartToLocal(@RequestParam(value = "ids", required = false) String ids) {
|
||||||
|
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||||
|
SyncInfoVo syncInfo = wechatEnterpriseService.syncThirdAppDepartmentToLocal(ids);
|
||||||
|
if (syncInfo.getFailInfo().size() == 0) {
|
||||||
|
return Result.OK("同步成功", syncInfo);
|
||||||
|
} else {
|
||||||
|
return Result.error("同步失败", syncInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.error("企业微信同步功能已禁用");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步本地[部门]到【钉钉】
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sync/dingtalk/depart/toApp")
|
||||||
|
public Result syncDingtalkDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||||
|
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||||
|
boolean flag = dingtalkService.syncLocalDepartmentToThirdApp(ids);
|
||||||
|
return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
|
||||||
|
}
|
||||||
|
return Result.error("钉钉同步功能已禁用");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步【钉钉】[部门]到本地
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sync/dingtalk/depart/toLocal")
|
||||||
|
public Result syncDingtalkDepartToLocal(@RequestParam(value = "ids", required = false) String ids) {
|
||||||
|
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||||
|
SyncInfoVo syncInfo = dingtalkService.syncThirdAppDepartmentToLocal(ids);
|
||||||
|
if (syncInfo.getFailInfo().size() == 0) {
|
||||||
|
return Result.OK("同步成功", syncInfo);
|
||||||
|
} else {
|
||||||
|
return Result.error("同步失败", syncInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.error("钉钉同步功能已禁用");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步本地[用户]到【钉钉】
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sync/dingtalk/user/toApp")
|
||||||
|
public Result syncDingtalkUserToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||||
|
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||||
|
SyncInfoVo syncInfo = dingtalkService.syncLocalUserToThirdApp(ids);
|
||||||
|
if (syncInfo.getFailInfo().size() == 0) {
|
||||||
|
return Result.OK("同步成功", syncInfo);
|
||||||
|
} else {
|
||||||
|
return Result.error("同步失败", syncInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.error("钉钉同步功能已禁用");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步【钉钉】[用户]到本地
|
||||||
|
*
|
||||||
|
* @param ids 作废
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sync/dingtalk/user/toLocal")
|
||||||
|
public Result syncDingtalkUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
|
||||||
|
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||||
|
SyncInfoVo syncInfo = dingtalkService.syncThirdAppUserToLocal();
|
||||||
|
if (syncInfo.getFailInfo().size() == 0) {
|
||||||
|
return Result.OK("同步成功", syncInfo);
|
||||||
|
} else {
|
||||||
|
return Result.error("同步失败", syncInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.error("钉钉同步功能已禁用");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息测试
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/sendMessageTest")
|
||||||
|
public Result sendMessageTest(@RequestBody JSONObject params, HttpServletRequest request) {
|
||||||
|
/* 获取前台传递的参数 */
|
||||||
|
// 第三方app的类型
|
||||||
|
String app = params.getString("app");
|
||||||
|
// 是否发送给全部人
|
||||||
|
boolean sendAll = params.getBooleanValue("sendAll");
|
||||||
|
// 消息接收者,传sys_user表的username字段,多个用逗号分割
|
||||||
|
String receiver = params.getString("receiver");
|
||||||
|
// 消息内容
|
||||||
|
String content = params.getString("content");
|
||||||
|
|
||||||
|
String fromUser = JwtUtil.getUserNameByToken(request);
|
||||||
|
String title = "第三方APP消息测试";
|
||||||
|
MessageDTO message = new MessageDTO(fromUser, receiver, title, content);
|
||||||
|
message.setToAll(sendAll);
|
||||||
|
|
||||||
|
if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) {
|
||||||
|
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||||
|
JSONObject response = wechatEnterpriseService.sendMessageResponse(message, false);
|
||||||
|
return Result.OK(response);
|
||||||
|
}
|
||||||
|
return Result.error("企业微信已被禁用");
|
||||||
|
} else if (ThirdAppConfig.DINGTALK.equals(app)) {
|
||||||
|
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||||
|
Response<String> response = dingtalkService.sendMessageResponse(message, false);
|
||||||
|
return Result.OK(response);
|
||||||
|
}
|
||||||
|
return Result.error("钉钉已被禁用");
|
||||||
|
}
|
||||||
|
return Result.error("不识别的第三方APP");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回消息测试
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/recallMessageTest")
|
||||||
|
public Result recallMessageTest(@RequestBody JSONObject params) {
|
||||||
|
/* 获取前台传递的参数 */
|
||||||
|
// 第三方app的类型
|
||||||
|
String app = params.getString("app");
|
||||||
|
// 消息id
|
||||||
|
String msg_task_id = params.getString("msg_task_id");
|
||||||
|
|
||||||
|
if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) {
|
||||||
|
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||||
|
return Result.error("企业微信不支持撤回消息");
|
||||||
|
}
|
||||||
|
return Result.error("企业微信已被禁用");
|
||||||
|
} else if (ThirdAppConfig.DINGTALK.equals(app)) {
|
||||||
|
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||||
|
Response<JSONObject> response = dingtalkService.recallMessageResponse(msg_task_id);
|
||||||
|
if (response.isSuccess()) {
|
||||||
|
return Result.OK("撤回成功", response);
|
||||||
|
} else {
|
||||||
|
return Result.error("撤回失败:" + response.getErrcode() + "——" + response.getErrmsg(), response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.error("钉钉已被禁用");
|
||||||
|
}
|
||||||
|
return Result.error("不识别的第三方APP");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,17 +1,16 @@
|
||||||
package org.jeecg.modules.system.entity;
|
package org.jeecg.modules.system.entity;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
import org.jeecg.common.aspect.annotation.Dict;
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 系统通告表
|
* @Description: 系统通告表
|
||||||
* @Author: jeecg-boot
|
* @Author: jeecg-boot
|
||||||
|
@ -144,4 +143,8 @@ public class SysAnnouncement implements Serializable {
|
||||||
* 摘要
|
* 摘要
|
||||||
*/
|
*/
|
||||||
private java.lang.String msgAbstract;
|
private java.lang.String msgAbstract;
|
||||||
|
/**
|
||||||
|
* 钉钉task_id,用于撤回消息
|
||||||
|
*/
|
||||||
|
private java.lang.String dtTaskId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,11 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.jeecg.common.aspect.annotation.Dict;
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
|
||||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,6 +71,8 @@ public class SysDepart implements Serializable {
|
||||||
/**删除状态(0,正常,1已删除)*/
|
/**删除状态(0,正常,1已删除)*/
|
||||||
@Dict(dicCode = "del_flag")
|
@Dict(dicCode = "del_flag")
|
||||||
private String delFlag;
|
private String delFlag;
|
||||||
|
/**对接企业微信的ID*/
|
||||||
|
private String qywxIdentifier;
|
||||||
/**创建人*/
|
/**创建人*/
|
||||||
private String createBy;
|
private String createBy;
|
||||||
/**创建日期*/
|
/**创建日期*/
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
package org.jeecg.modules.system.entity;
|
package org.jeecg.modules.system.entity;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,4 +55,8 @@ public class SysThirdAccount {
|
||||||
@Excel(name = "真实姓名", width = 15)
|
@Excel(name = "真实姓名", width = 15)
|
||||||
@ApiModelProperty(value = "真实姓名")
|
@ApiModelProperty(value = "真实姓名")
|
||||||
private java.lang.String thirdUserUuid;
|
private java.lang.String thirdUserUuid;
|
||||||
|
/**真实姓名*/
|
||||||
|
@Excel(name = "第三方用户账号", width = 15)
|
||||||
|
@ApiModelProperty(value = "第三方用户账号")
|
||||||
|
private java.lang.String thirdUserId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import java.util.Map;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.apache.ibatis.annotations.ResultType;
|
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
import org.apache.ibatis.annotations.Update;
|
import org.apache.ibatis.annotations.Update;
|
||||||
import org.jeecg.common.system.vo.DictModel;
|
import org.jeecg.common.system.vo.DictModel;
|
||||||
|
@ -132,4 +131,26 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Page<DictModel> queryDictTablePageList(Page page, @Param("query") DictQuery query);
|
public Page<DictModel> queryDictTablePageList(Page page, @Param("query") DictQuery query);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 字典表数据 支持查询条件 分页
|
||||||
|
* @param page
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param filterSql
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
IPage<DictModel> queryTableDictWithFilter(Page<DictModel> page, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 字典表数据 支持查询条件 查询所有
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param filterSql
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<DictModel> queryAllTableDictItems(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,26 @@
|
||||||
package org.jeecg.modules.system.mapper;
|
package org.jeecg.modules.system.mapper;
|
||||||
|
|
||||||
import java.util.List;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.jeecg.modules.system.entity.SysThirdAccount;
|
import org.jeecg.modules.system.entity.SysThirdAccount;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 第三方登录账号表
|
* @Description: 第三方登录账号表
|
||||||
* @Author: jeecg-boot
|
* @Author: jeecg-boot
|
||||||
* @Date: 2020-11-17
|
* @Date: 2020-11-17
|
||||||
* @Version: V1.0
|
* @Version: V1.0
|
||||||
*/
|
*/
|
||||||
public interface SysThirdAccountMapper extends BaseMapper<SysThirdAccount> {
|
public interface SysThirdAccountMapper extends BaseMapper<SysThirdAccount> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 sysUsername 集合批量查询
|
||||||
|
*
|
||||||
|
* @param sysUsernameArr username集合
|
||||||
|
* @param thirdType 第三方类型
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<SysThirdAccount> selectThirdIdsByUsername(@Param("sysUsernameArr") String[] sysUsernameArr, @Param("thirdType") String thirdType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,32 @@
|
||||||
package org.jeecg.modules.system.mapper;
|
package org.jeecg.modules.system.mapper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
import org.jeecg.modules.system.entity.SysUserDepart;
|
import org.jeecg.modules.system.entity.SysUserDepart;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
|
public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
|
||||||
|
|
||||||
List<SysUserDepart> getUserDepartByUid(@Param("userId") String userId);
|
List<SysUserDepart> getUserDepartByUid(@Param("userId") String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询指定部门下的用户 并且支持用户真实姓名模糊查询
|
||||||
|
* @param orgCode
|
||||||
|
* @param realname
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<SysUser> queryDepartUserList(@Param("orgCode") String orgCode, @Param("realname") String realname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据部门查询部门用户
|
||||||
|
* @param page
|
||||||
|
* @param orgCode
|
||||||
|
* @param username
|
||||||
|
* @param realname
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
IPage<SysUser> queryDepartUserPageList(Page<SysUser> page, @Param("orgCode") String orgCode, @Param("username") String username, @Param("realname") String realname);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,4 +106,22 @@
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!--通过查询指定table的 text code 获取字典数据,且支持关键字和自定义查询条件查询 分页-->
|
||||||
|
<select id="queryTableDictWithFilter" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
|
||||||
|
select ${text} as "text", ${code} as "value" from ${table}
|
||||||
|
<if test="filterSql != null and filterSql != ''">
|
||||||
|
${filterSql}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!--通过查询指定table的 text code 获取字典数据,且支持关键字和自定义查询条件查询 获取所有 -->
|
||||||
|
<select id="queryAllTableDictItems" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
|
||||||
|
select ${text} as "text", ${code} as "value" from ${table}
|
||||||
|
<if test="filterSql != null and filterSql != ''">
|
||||||
|
${filterSql}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
<!-- 首页访问统计 -->
|
<!-- 首页访问统计 -->
|
||||||
<select id="findVisitCount" resultType="java.util.HashMap">
|
<select id="findVisitCount" resultType="java.util.HashMap">
|
||||||
<if test="dbType == 'MYSQL'">
|
<if test="dbType == 'MYSQL' || dbType == 'MARIADB'">
|
||||||
select count(*) as visit
|
select count(*) as visit
|
||||||
,count(distinct(ip)) as ip
|
,count(distinct(ip)) as ip
|
||||||
,DATE_FORMAT(create_time, '%Y-%m-%d') as tian
|
,DATE_FORMAT(create_time, '%Y-%m-%d') as tian
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
group by tian,type
|
group by tian,type
|
||||||
order by tian asc
|
order by tian asc
|
||||||
</if>
|
</if>
|
||||||
<if test="dbType == 'ORACLE'">
|
<if test="dbType == 'ORACLE' || dbType == 'DM'">
|
||||||
select count(*) as visit
|
select count(*) as visit
|
||||||
,count(distinct(ip)) as ip
|
,count(distinct(ip)) as ip
|
||||||
,to_char(create_time, 'yyyy-mm-dd') as tian
|
,to_char(create_time, 'yyyy-mm-dd') as tian
|
||||||
|
|
|
@ -2,4 +2,13 @@
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="org.jeecg.modules.system.mapper.SysThirdAccountMapper">
|
<mapper namespace="org.jeecg.modules.system.mapper.SysThirdAccountMapper">
|
||||||
|
|
||||||
|
<!-- 通过 sysUsername 集合批量查询 -->
|
||||||
|
<select id="selectThirdIdsByUsername" resultType="org.jeecg.modules.system.entity.SysThirdAccount">
|
||||||
|
SELECT third_user_id FROM sys_third_account
|
||||||
|
INNER JOIN sys_user ON sys_user.id = sys_third_account.sys_user_id
|
||||||
|
WHERE third_type = #{thirdType} AND
|
||||||
|
<!-- TODO in 查询数据量大的时候可能会报错 -->
|
||||||
|
<foreach collection="sysUsernameArr" item="item" open=" sys_user.username IN (" close=")" separator=",">#{item}</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
|
@ -6,4 +6,29 @@
|
||||||
FROM sys_user_depart
|
FROM sys_user_depart
|
||||||
WHERE user_id = #{userId, jdbcType=VARCHAR}
|
WHERE user_id = #{userId, jdbcType=VARCHAR}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询指定部门下的用户 并且支持用户账号模糊查询 -->
|
||||||
|
<select id="queryDepartUserList" resultType="org.jeecg.modules.system.entity.SysUser">
|
||||||
|
select a.* from sys_user a
|
||||||
|
join sys_user_depart b on b.user_id = a.id
|
||||||
|
join sys_depart c on b.dep_id = c.id
|
||||||
|
where a.del_flag = 0 and c.org_code like '${orgCode}%'
|
||||||
|
<if test="realname!=null and realname!=''">
|
||||||
|
and a.realname like '%${realname}%'
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 根据部门查询部门用户 分页 -->
|
||||||
|
<select id="queryDepartUserPageList" resultType="org.jeecg.modules.system.entity.SysUser">
|
||||||
|
select a.*, c.depart_name as org_code_txt from sys_user a
|
||||||
|
join sys_user_depart b on b.user_id = a.id
|
||||||
|
join sys_depart c on b.dep_id = c.id
|
||||||
|
where a.del_flag = 0 and c.org_code like '${orgCode}%'
|
||||||
|
<if test="username!=null and username!=''">
|
||||||
|
and a.username like '%${username}%'
|
||||||
|
</if>
|
||||||
|
<if test="realname!=null and realname!=''">
|
||||||
|
and a.realname like '%${realname}%'
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
|
@ -65,6 +65,8 @@ public class SysDepartTreeModel implements Serializable{
|
||||||
|
|
||||||
private String delFlag;
|
private String delFlag;
|
||||||
|
|
||||||
|
private String qywxIdentifier;
|
||||||
|
|
||||||
private String createBy;
|
private String createBy;
|
||||||
|
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
@ -100,6 +102,7 @@ public class SysDepartTreeModel implements Serializable{
|
||||||
this.memo = sysDepart.getMemo();
|
this.memo = sysDepart.getMemo();
|
||||||
this.status = sysDepart.getStatus();
|
this.status = sysDepart.getStatus();
|
||||||
this.delFlag = sysDepart.getDelFlag();
|
this.delFlag = sysDepart.getDelFlag();
|
||||||
|
this.qywxIdentifier = sysDepart.getQywxIdentifier();
|
||||||
this.createBy = sysDepart.getCreateBy();
|
this.createBy = sysDepart.getCreateBy();
|
||||||
this.createTime = sysDepart.getCreateTime();
|
this.createTime = sysDepart.getCreateTime();
|
||||||
this.updateBy = sysDepart.getUpdateBy();
|
this.updateBy = sysDepart.getUpdateBy();
|
||||||
|
@ -287,6 +290,14 @@ public class SysDepartTreeModel implements Serializable{
|
||||||
this.delFlag = delFlag;
|
this.delFlag = delFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getQywxIdentifier() {
|
||||||
|
return qywxIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQywxIdentifier(String qywxIdentifier) {
|
||||||
|
this.qywxIdentifier = qywxIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
public String getCreateBy() {
|
public String getCreateBy() {
|
||||||
return createBy;
|
return createBy;
|
||||||
}
|
}
|
||||||
|
@ -349,6 +360,7 @@ public class SysDepartTreeModel implements Serializable{
|
||||||
Objects.equals(memo, model.memo) &&
|
Objects.equals(memo, model.memo) &&
|
||||||
Objects.equals(status, model.status) &&
|
Objects.equals(status, model.status) &&
|
||||||
Objects.equals(delFlag, model.delFlag) &&
|
Objects.equals(delFlag, model.delFlag) &&
|
||||||
|
Objects.equals(qywxIdentifier, model.qywxIdentifier) &&
|
||||||
Objects.equals(createBy, model.createBy) &&
|
Objects.equals(createBy, model.createBy) &&
|
||||||
Objects.equals(createTime, model.createTime) &&
|
Objects.equals(createTime, model.createTime) &&
|
||||||
Objects.equals(updateBy, model.updateBy) &&
|
Objects.equals(updateBy, model.updateBy) &&
|
||||||
|
@ -364,7 +376,7 @@ public class SysDepartTreeModel implements Serializable{
|
||||||
|
|
||||||
return Objects.hash(id, parentId, departName, departNameEn, departNameAbbr,
|
return Objects.hash(id, parentId, departName, departNameEn, departNameAbbr,
|
||||||
departOrder, description, orgCategory, orgType, orgCode, mobile, fax, address,
|
departOrder, description, orgCategory, orgType, orgCode, mobile, fax, address,
|
||||||
memo, status, delFlag, createBy, createTime, updateBy, updateTime,
|
memo, status, delFlag, qywxIdentifier, createBy, createTime, updateBy, updateTime,
|
||||||
children);
|
children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package org.jeecg.modules.system.service;
|
package org.jeecg.modules.system.service;
|
||||||
|
|
||||||
import java.util.List;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jeecg.common.exception.JeecgBootException;
|
import org.jeecg.common.exception.JeecgBootException;
|
||||||
import org.jeecg.modules.system.entity.SysCategory;
|
import org.jeecg.modules.system.entity.SysCategory;
|
||||||
import org.jeecg.modules.system.model.TreeSelectModel;
|
import org.jeecg.modules.system.model.TreeSelectModel;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 分类字典
|
* @Description: 分类字典
|
||||||
|
@ -58,5 +57,22 @@ public interface ISysCategoryService extends IService<SysCategory> {
|
||||||
* @param ids
|
* @param ids
|
||||||
*/
|
*/
|
||||||
void deleteSysCategory(String ids);
|
void deleteSysCategory(String ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类字典控件数据回显[表单页面]
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> loadDictItem(String ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类字典控件数据回显[表单页面]
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @param delNotExist 是否移除不存在的项,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> loadDictItem(String ids, boolean delNotExist);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.jeecg.modules.system.service;
|
package org.jeecg.modules.system.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.jeecg.modules.system.entity.SysDepart;
|
import org.jeecg.modules.system.entity.SysDepart;
|
||||||
import org.jeecg.modules.system.model.DepartIdModel;
|
import org.jeecg.modules.system.model.DepartIdModel;
|
||||||
|
@ -112,6 +113,20 @@ public interface ISysDepartService extends IService<SysDepart>{
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<SysDepartTreeModel> queryTreeListByPid(String parentId);
|
List<SysDepartTreeModel> queryTreeListByPid(String parentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取某个部门的所有父级部门的ID
|
||||||
|
*
|
||||||
|
* @param departId 根据departId查
|
||||||
|
*/
|
||||||
|
JSONObject queryAllParentIdByDepartId(String departId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取某个部门的所有父级部门的ID
|
||||||
|
*
|
||||||
|
* @param orgCode 根据orgCode查
|
||||||
|
*/
|
||||||
|
JSONObject queryAllParentIdByOrgCode(String orgCode);
|
||||||
/**
|
/**
|
||||||
* 获取公司信息
|
* 获取公司信息
|
||||||
* @return
|
* @return
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package org.jeecg.modules.system.service;
|
package org.jeecg.modules.system.service;
|
||||||
|
|
||||||
import java.util.List;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jeecg.common.system.vo.DictModel;
|
import org.jeecg.common.system.vo.DictModel;
|
||||||
import org.jeecg.common.system.vo.DictQuery;
|
import org.jeecg.common.system.vo.DictQuery;
|
||||||
import org.jeecg.modules.system.entity.SysDict;
|
import org.jeecg.modules.system.entity.SysDict;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
|
||||||
import org.jeecg.modules.system.entity.SysDictItem;
|
import org.jeecg.modules.system.entity.SysDictItem;
|
||||||
import org.jeecg.modules.system.model.TreeSelectModel;
|
import org.jeecg.modules.system.model.TreeSelectModel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 字典表 服务类
|
* 字典表 服务类
|
||||||
|
@ -37,6 +37,8 @@ public interface ISysDictService extends IService<SysDict> {
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<String> queryTableDictByKeys(String table, String text, String code, String keys);
|
List<String> queryTableDictByKeys(String table, String text, String code, String keys);
|
||||||
|
@Deprecated
|
||||||
|
List<String> queryTableDictByKeys(String table, String text, String code, String keys,boolean delNotExist);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据字典类型删除关联表中其对应的数据
|
* 根据字典类型删除关联表中其对应的数据
|
||||||
|
@ -50,19 +52,19 @@ public interface ISysDictService extends IService<SysDict> {
|
||||||
* 添加一对多
|
* 添加一对多
|
||||||
*/
|
*/
|
||||||
public Integer saveMain(SysDict sysDict, List<SysDictItem> sysDictItemList);
|
public Integer saveMain(SysDict sysDict, List<SysDictItem> sysDictItemList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有部门 作为字典信息 id -->value,departName -->text
|
* 查询所有部门 作为字典信息 id -->value,departName -->text
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<DictModel> queryAllDepartBackDictModel();
|
public List<DictModel> queryAllDepartBackDictModel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有用户 作为字典信息 username -->value,realname -->text
|
* 查询所有用户 作为字典信息 username -->value,realname -->text
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<DictModel> queryAllUserBackDictModel();
|
public List<DictModel> queryAllUserBackDictModel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过关键字查询字典表
|
* 通过关键字查询字典表
|
||||||
* @param table
|
* @param table
|
||||||
|
@ -82,7 +84,18 @@ public interface ISysDictService extends IService<SysDict> {
|
||||||
* @param keyword
|
* @param keyword
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<DictModel> queryLittleTableDictItems(String table, String text, String code,String keyword, int pageSize);
|
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询字典表所有数据
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param condition
|
||||||
|
* @param keyword
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<DictModel> queryAllTableDictItems(String table, String text, String code, String condition, String keyword);
|
||||||
/**
|
/**
|
||||||
* 根据表名、显示字段名、存储字段名 查询树
|
* 根据表名、显示字段名、存储字段名 查询树
|
||||||
* @param table
|
* @param table
|
||||||
|
@ -125,4 +138,21 @@ public interface ISysDictService extends IService<SysDict> {
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public List<DictModel> queryDictTablePageList(DictQuery query,int pageSize, int pageNo);
|
public List<DictModel> queryDictTablePageList(DictQuery query,int pageSize, int pageNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字典数据
|
||||||
|
* @param dictCode 字典code
|
||||||
|
* @param dictCode 表名,文本字段,code字段 | 举例:sys_user,realname,id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<DictModel> getDictItems(String dictCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【JSearchSelectTag下拉搜索组件专用接口】
|
||||||
|
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||||
|
*
|
||||||
|
* @param dictCode 字典code格式:table,text,code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<DictModel> loadDict(String dictCode, String keyword, Integer pageSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,4 +11,9 @@ import org.jeecg.modules.system.entity.SysPosition;
|
||||||
*/
|
*/
|
||||||
public interface ISysPositionService extends IService<SysPosition> {
|
public interface ISysPositionService extends IService<SysPosition> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过code查询
|
||||||
|
*/
|
||||||
|
SysPosition getByCode(String code);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package org.jeecg.modules.system.service;
|
package org.jeecg.modules.system.service;
|
||||||
|
|
||||||
import org.jeecg.modules.system.entity.SysThirdAccount;
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.jeecg.modules.system.entity.SysThirdAccount;
|
||||||
import org.jeecg.modules.system.entity.SysUser;
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 第三方登录账号表
|
* @Description: 第三方登录账号表
|
||||||
* @Author: jeecg-boot
|
* @Author: jeecg-boot
|
||||||
|
@ -15,5 +17,19 @@ public interface ISysThirdAccountService extends IService<SysThirdAccount> {
|
||||||
void updateThirdUserId(SysUser sysUser,String thirdUserUuid);
|
void updateThirdUserId(SysUser sysUser,String thirdUserUuid);
|
||||||
/**创建第三方用户*/
|
/**创建第三方用户*/
|
||||||
SysUser createUser(String phone, String thirdUserUuid);
|
SysUser createUser(String phone, String thirdUserUuid);
|
||||||
|
|
||||||
|
/** 根据本地userId查询数据 */
|
||||||
|
SysThirdAccount getOneBySysUserId(String sysUserId, String thirdType);
|
||||||
|
/** 根据第三方userId查询数据 */
|
||||||
|
SysThirdAccount getOneByThirdUserId(String thirdUserId, String thirdType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 sysUsername 集合批量查询
|
||||||
|
*
|
||||||
|
* @param sysUsernameArr username集合
|
||||||
|
* @param thirdType 第三方类型
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<SysThirdAccount> listThirdUserIdByUsername(String[] sysUsernameArr, String thirdType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.jeecg.modules.system.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import org.jeecg.modules.system.entity.SysUser;
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
import org.jeecg.modules.system.entity.SysUserDepart;
|
import org.jeecg.modules.system.entity.SysUserDepart;
|
||||||
import org.jeecg.modules.system.model.DepartIdModel;
|
import org.jeecg.modules.system.model.DepartIdModel;
|
||||||
|
@ -37,5 +38,16 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
|
||||||
/**
|
/**
|
||||||
* 根据部门code,查询当前部门和下级部门的用户信息
|
* 根据部门code,查询当前部门和下级部门的用户信息
|
||||||
*/
|
*/
|
||||||
public List<SysUser> queryUserByDepCode(String depCode,String realname);
|
List<SysUser> queryUserByDepCode(String depCode,String realname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户组件数据查询
|
||||||
|
* @param departId
|
||||||
|
* @param username
|
||||||
|
* @param pageSize
|
||||||
|
* @param pageNo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
package org.jeecg.modules.system.service;
|
package org.jeecg.modules.system.service;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.system.vo.SysUserCacheInfo;
|
import org.jeecg.common.system.vo.SysUserCacheInfo;
|
||||||
import org.jeecg.modules.system.entity.SysUser;
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
|
||||||
import org.jeecg.modules.system.model.SysUserSysDepartModel;
|
import org.jeecg.modules.system.model.SysUserSysDepartModel;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 用户表 服务类
|
* 用户表 服务类
|
||||||
|
@ -233,4 +232,24 @@ public interface ISysUserService extends IService<SysUser> {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<SysUser> queryByDepIds(List<String> departIds, String username);
|
List<SysUser> queryByDepIds(List<String> departIds, String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存用户
|
||||||
|
* @param user 用户
|
||||||
|
* @param selectedRoles 选择的角色id,多个以逗号隔开
|
||||||
|
* @param selectedDeparts 选择的部门id,多个以逗号隔开
|
||||||
|
*/
|
||||||
|
void saveUser(SysUser user, String selectedRoles, String selectedDeparts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑用户
|
||||||
|
* @param user 用户
|
||||||
|
* @param roles 选择的角色id,多个以逗号隔开
|
||||||
|
* @param departs 选择的部门id,多个以逗号隔开
|
||||||
|
*/
|
||||||
|
void editUser(SysUser user, String roles, String departs);
|
||||||
|
|
||||||
|
/** userId转为username */
|
||||||
|
List<String> userIdToUsername(Collection<String> userIdList);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package org.jeecg.modules.system.service;
|
||||||
|
|
||||||
|
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||||
|
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方App对接
|
||||||
|
*/
|
||||||
|
public interface IThirdAppService {
|
||||||
|
|
||||||
|
String getAccessToken();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将本地部门同步到第三方App<br>
|
||||||
|
* 同步方向:本地 --> 第三方APP
|
||||||
|
* 同步逻辑:<br>
|
||||||
|
* 1. 先判断是否同步过,有则修改,无则创建;<br>
|
||||||
|
* 2. 本地没有但第三方App里有则删除第三方App里的。
|
||||||
|
*
|
||||||
|
* @return 成功返回true
|
||||||
|
*/
|
||||||
|
boolean syncLocalDepartmentToThirdApp(String ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将第三方App部门同步到本地<br>
|
||||||
|
* 同步方向:第三方APP --> 本地
|
||||||
|
* 同步逻辑:<br>
|
||||||
|
* 1. 先判断是否同步过,有则修改,无则创建;<br>
|
||||||
|
* 2. 本地没有但第三方App里有则删除第三方App里的。
|
||||||
|
*
|
||||||
|
* @return 成功返回true
|
||||||
|
*/
|
||||||
|
SyncInfoVo syncThirdAppDepartmentToLocal(String ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将本地用户同步到第三方App<br>
|
||||||
|
* 同步方向:本地 --> 第三方APP <br>
|
||||||
|
* 同步逻辑:先判断是否同步过,有则修改、无则创建<br>
|
||||||
|
* 注意:同步人员的状态,比如离职、禁用、逻辑删除等。
|
||||||
|
* (特殊点:1、目前逻辑特意做的不删除用户,防止企业微信提前上线,用户已经存在,但是平台无此用户。
|
||||||
|
* 企业微信支持禁用账号;钉钉不支持
|
||||||
|
* 2、企业微信里面是手机号激活,只能用户自己改,不允许通过接口改)
|
||||||
|
*
|
||||||
|
* @return 成功返回空数组,失败返回错误信息
|
||||||
|
*/
|
||||||
|
SyncInfoVo syncLocalUserToThirdApp(String ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将第三方App用户同步到本地<br>
|
||||||
|
* 同步方向:第三方APP --> 本地 <br>
|
||||||
|
* 同步逻辑:先判断是否同步过,有则修改、无则创建<br>
|
||||||
|
* 注意:同步人员的状态,比如离职、禁用、逻辑删除等。
|
||||||
|
*
|
||||||
|
* @return 成功返回空数组,失败返回错误信息
|
||||||
|
*/
|
||||||
|
SyncInfoVo syncThirdAppUserToLocal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据本地用户ID,删除第三方APP的用户
|
||||||
|
*
|
||||||
|
* @param userIdList 本地用户ID列表
|
||||||
|
* @return 0表示成功,其他值表示失败
|
||||||
|
*/
|
||||||
|
int removeThirdAppUser(List<String> userIdList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* @param verifyConfig 是否验证配置(未启用的APP会拒绝发送)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean sendMessage(MessageDTO message, boolean verifyConfig);
|
||||||
|
|
||||||
|
boolean sendMessage(MessageDTO message);
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,4 @@
|
||||||
package org.jeecg.modules.system.service.impl;
|
package org.jeecg.modules.system.service.impl;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
@ -95,6 +92,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysPermissionDataRuleService sysPermissionDataRuleService;
|
private ISysPermissionDataRuleService sysPermissionDataRuleService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||||
|
@Autowired
|
||||||
|
private ThirdAppDingtalkServiceImpl dingtalkService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
|
@Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
|
||||||
public LoginUser getUserByName(String username) {
|
public LoginUser getUserByName(String username) {
|
||||||
|
@ -201,6 +203,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
info.setSysUserCode(user.getUsername());
|
info.setSysUserCode(user.getUsername());
|
||||||
info.setSysUserName(user.getRealname());
|
info.setSysUserName(user.getRealname());
|
||||||
info.setSysOrgCode(user.getOrgCode());
|
info.setSysOrgCode(user.getOrgCode());
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
//多部门支持in查询
|
//多部门支持in查询
|
||||||
List<SysDepart> list = departMapper.queryUserDeparts(user.getId());
|
List<SysDepart> list = departMapper.queryUserDeparts(user.getId());
|
||||||
|
@ -267,7 +271,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code")
|
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code", unless = "#result == null ")
|
||||||
public List<DictModel> queryDictItemsByCode(String code) {
|
public List<DictModel> queryDictItemsByCode(String code) {
|
||||||
return sysDictService.queryDictItemsByCode(code);
|
return sysDictService.queryDictItemsByCode(code);
|
||||||
}
|
}
|
||||||
|
@ -294,6 +298,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
message.getTitle(),
|
message.getTitle(),
|
||||||
message.getContent(),
|
message.getContent(),
|
||||||
message.getCategory());
|
message.getCategory());
|
||||||
|
try {
|
||||||
|
// 同步发送第三方APP消息
|
||||||
|
wechatEnterpriseService.sendMessage(message, true);
|
||||||
|
dingtalkService.sendMessage(message, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("同步发送第三方APP消息失败!", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -305,6 +316,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
message.getCategory(),
|
message.getCategory(),
|
||||||
message.getBusType(),
|
message.getBusType(),
|
||||||
message.getBusId());
|
message.getBusId());
|
||||||
|
try {
|
||||||
|
// 同步发送第三方APP消息
|
||||||
|
wechatEnterpriseService.sendMessage(message, true);
|
||||||
|
dingtalkService.sendMessage(message, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("同步发送第三方APP消息失败!", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -368,6 +386,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
// 同步企业微信、钉钉的消息通知
|
||||||
|
dingtalkService.sendActionCardMessage(announcement, true);
|
||||||
|
wechatEnterpriseService.sendTextCardMessage(announcement, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("同步发送第三方APP消息失败!", e);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,6 +460,14 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
// 同步企业微信、钉钉的消息通知
|
||||||
|
dingtalkService.sendActionCardMessage(announcement, true);
|
||||||
|
wechatEnterpriseService.sendTextCardMessage(announcement, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("同步发送第三方APP消息失败!", e);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -492,8 +525,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
|
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
|
||||||
}else if(dbType.indexOf("postgresql")>=0) {
|
}else if(dbType.indexOf("postgresql")>=0) {
|
||||||
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
|
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
|
||||||
|
}else if(dbType.indexOf("mariadb")>=0) {
|
||||||
|
DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
|
||||||
}else {
|
}else {
|
||||||
throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
|
log.error("数据库类型:[" + dbType + "]不识别!");
|
||||||
|
//throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
|
@ -848,7 +884,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 36根据多个用户账号(逗号分隔),查询返回多个用户信息
|
* 36根据多个用户账号(逗号分隔),查询返回多个用户信息
|
||||||
* @param orgCodes
|
* @param usernames
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -867,7 +903,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 37根据多个部门编码(逗号分隔),查询返回多个部门信息
|
* 37根据多个部门编码(逗号分隔),查询返回多个部门信息
|
||||||
* @param usernames
|
* @param orgCodes
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
package org.jeecg.modules.system.service.impl;
|
package org.jeecg.modules.system.service.impl;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import org.jeecg.common.constant.FillRuleConstant;
|
import org.jeecg.common.constant.FillRuleConstant;
|
||||||
import org.jeecg.common.exception.JeecgBootException;
|
import org.jeecg.common.exception.JeecgBootException;
|
||||||
import org.jeecg.common.util.FillRuleUtil;
|
import org.jeecg.common.util.FillRuleUtil;
|
||||||
import org.jeecg.common.util.YouBianCodeUtil;
|
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.system.entity.SysCategory;
|
import org.jeecg.modules.system.entity.SysCategory;
|
||||||
import org.jeecg.modules.system.mapper.SysCategoryMapper;
|
import org.jeecg.modules.system.mapper.SysCategoryMapper;
|
||||||
import org.jeecg.modules.system.model.TreeSelectModel;
|
import org.jeecg.modules.system.model.TreeSelectModel;
|
||||||
import org.jeecg.modules.system.service.ISysCategoryService;
|
import org.jeecg.modules.system.service.ISysCategoryService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
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.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 分类字典
|
* @Description: 分类字典
|
||||||
* @Author: jeecg-boot
|
* @Author: jeecg-boot
|
||||||
|
@ -204,4 +204,32 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> loadDictItem(String ids) {
|
||||||
|
return this.loadDictItem(ids, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> loadDictItem(String ids, boolean delNotExist) {
|
||||||
|
String[] idArray = ids.split(",");
|
||||||
|
LambdaQueryWrapper<SysCategory> query = new LambdaQueryWrapper<>();
|
||||||
|
query.in(SysCategory::getId, Arrays.asList(idArray));
|
||||||
|
// 查询数据
|
||||||
|
List<SysCategory> list = super.list(query);
|
||||||
|
// 取出name并返回
|
||||||
|
List<String> textList;
|
||||||
|
// update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||||
|
if (delNotExist) {
|
||||||
|
textList = list.stream().map(SysCategory::getName).collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
textList = new ArrayList<>();
|
||||||
|
for (String id : idArray) {
|
||||||
|
List<SysCategory> res = list.stream().filter(i -> id.equals(i.getId())).collect(Collectors.toList());
|
||||||
|
textList.add(res.size() > 0 ? res.get(0).getName() : id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update-end--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||||
|
return textList;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package org.jeecg.modules.system.service.impl;
|
package org.jeecg.modules.system.service.impl;
|
||||||
|
|
||||||
import java.util.*;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
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.extension.service.impl.ServiceImpl;
|
||||||
|
import io.netty.util.internal.StringUtil;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.jeecg.common.constant.CacheConstant;
|
import org.jeecg.common.constant.CacheConstant;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
@ -21,10 +24,7 @@ import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import java.util.*;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
||||||
|
|
||||||
import io.netty.util.internal.StringUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -468,7 +468,8 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||||
SysDepart depart = list.get(i);
|
SysDepart depart = list.get(i);
|
||||||
SysDepartTreeModel treeModel = new SysDepartTreeModel(depart);
|
SysDepartTreeModel treeModel = new SysDepartTreeModel(depart);
|
||||||
//TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据
|
//TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据
|
||||||
treeModel.setKey(treeModel.getKey()+"__"+System.currentTimeMillis());
|
//treeModel.setKey(treeModel.getKey()+"__"+System.currentTimeMillis());
|
||||||
|
treeModel.setKey(treeModel.getKey());
|
||||||
Integer count=this.baseMapper.queryCountByPid(depart.getId());
|
Integer count=this.baseMapper.queryCountByPid(depart.getId());
|
||||||
if(count>0){
|
if(count>0){
|
||||||
treeModel.setIsLeaf(false);
|
treeModel.setIsLeaf(false);
|
||||||
|
@ -479,6 +480,59 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||||
}
|
}
|
||||||
return records;
|
return records;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject queryAllParentIdByDepartId(String departId) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (String id : departId.split(",")) {
|
||||||
|
JSONObject all = this.queryAllParentId("id", id);
|
||||||
|
result.put(id, all);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject queryAllParentIdByOrgCode(String orgCode) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (String code : orgCode.split(",")) {
|
||||||
|
JSONObject all = this.queryAllParentId("org_code", code);
|
||||||
|
result.put(code, all);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询某个部门的所有父ID信息
|
||||||
|
*
|
||||||
|
* @param fieldName 字段名
|
||||||
|
* @param value 值
|
||||||
|
*/
|
||||||
|
private JSONObject queryAllParentId(String fieldName, String value) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
// 父ID集合,有序
|
||||||
|
data.put("parentIds", new JSONArray());
|
||||||
|
// 父ID的部门数据,key是id,value是数据
|
||||||
|
data.put("parentMap", new JSONObject());
|
||||||
|
this.queryAllParentIdRecursion(fieldName, value, data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归调用查询父部门接口
|
||||||
|
*/
|
||||||
|
private void queryAllParentIdRecursion(String fieldName, String value, JSONObject data) {
|
||||||
|
QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq(fieldName, value);
|
||||||
|
SysDepart depart = super.getOne(queryWrapper);
|
||||||
|
if (depart != null) {
|
||||||
|
data.getJSONArray("parentIds").add(0, depart.getId());
|
||||||
|
data.getJSONObject("parentMap").put(depart.getId(), depart);
|
||||||
|
if (oConvertUtils.isNotEmpty(depart.getParentId())) {
|
||||||
|
this.queryAllParentIdRecursion("id", depart.getParentId(), data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SysDepart queryCompByOrgCode(String orgCode) {
|
public SysDepart queryCompByOrgCode(String orgCode) {
|
||||||
int length = YouBianCodeUtil.zhanweiLength;
|
int length = YouBianCodeUtil.zhanweiLength;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.jeecg.common.constant.CacheConstant;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.system.vo.DictModel;
|
import org.jeecg.common.system.vo.DictModel;
|
||||||
import org.jeecg.common.system.vo.DictQuery;
|
import org.jeecg.common.system.vo.DictQuery;
|
||||||
|
import org.jeecg.common.util.SqlInjectionUtil;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.system.entity.SysDict;
|
import org.jeecg.modules.system.entity.SysDict;
|
||||||
import org.jeecg.modules.system.entity.SysDictItem;
|
import org.jeecg.modules.system.entity.SysDictItem;
|
||||||
|
@ -50,7 +51,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code")
|
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code", unless = "#result == null ")
|
||||||
public List<DictModel> queryDictItemsByCode(String code) {
|
public List<DictModel> queryDictItemsByCode(String code) {
|
||||||
log.debug("无缓存dictCache的时候调用这里!");
|
log.debug("无缓存dictCache的时候调用这里!");
|
||||||
return sysDictMapper.queryDictItemsByCode(code);
|
return sysDictMapper.queryDictItemsByCode(code);
|
||||||
|
@ -86,7 +87,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code+':'+#key")
|
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code+':'+#key", unless = "#result == null ")
|
||||||
public String queryDictTextByKey(String code, String key) {
|
public String queryDictTextByKey(String code, String key) {
|
||||||
log.debug("无缓存dictText的时候调用这里!");
|
log.debug("无缓存dictText的时候调用这里!");
|
||||||
return sysDictMapper.queryDictTextByKey(code, key);
|
return sysDictMapper.queryDictTextByKey(code, key);
|
||||||
|
@ -123,12 +124,17 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = CacheConstant.SYS_DICT_TABLE_CACHE)
|
@Cacheable(value = CacheConstant.SYS_DICT_TABLE_CACHE, unless = "#result == null ")
|
||||||
public String queryTableDictTextByKey(String table,String text,String code, String key) {
|
public String queryTableDictTextByKey(String table,String text,String code, String key) {
|
||||||
log.debug("无缓存dictTable的时候调用这里!");
|
log.debug("无缓存dictTable的时候调用这里!");
|
||||||
return sysDictMapper.queryTableDictTextByKey(table,text,code,key);
|
return sysDictMapper.queryTableDictTextByKey(table,text,code,key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> queryTableDictByKeys(String table, String text, String code, String keys) {
|
||||||
|
return this.queryTableDictByKeys(table, text, code, keys, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过查询指定table的 text code 获取字典,包含text和value
|
* 通过查询指定table的 text code 获取字典,包含text和value
|
||||||
* dictTableCache采用redis缓存有效期10分钟
|
* dictTableCache采用redis缓存有效期10分钟
|
||||||
|
@ -136,28 +142,33 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||||
* @param text
|
* @param text
|
||||||
* @param code
|
* @param code
|
||||||
* @param keys (逗号分隔)
|
* @param keys (逗号分隔)
|
||||||
|
* @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
//update-begin--Author:lvdandan Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存
|
//update-begin--Author:lvdandan Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存
|
||||||
//@Cacheable(value = CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE)
|
//@Cacheable(value = CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE)
|
||||||
//update-end--Author:lvdandan Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存
|
//update-end--Author:lvdandan Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存
|
||||||
public List<String> queryTableDictByKeys(String table, String text, String code, String keys) {
|
public List<String> queryTableDictByKeys(String table, String text, String code, String keys, boolean delNotExist) {
|
||||||
if(oConvertUtils.isEmpty(keys)){
|
if(oConvertUtils.isEmpty(keys)){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String[] keyArray = keys.split(",");
|
String[] keyArray = keys.split(",");
|
||||||
List<DictModel> dicts = sysDictMapper.queryTableDictByKeys(table, text, code, keyArray);
|
List<DictModel> dicts = sysDictMapper.queryTableDictByKeys(table, text, code, keyArray);
|
||||||
List<String> texts = new ArrayList<>(dicts.size());
|
List<String> texts = new ArrayList<>(dicts.size());
|
||||||
|
|
||||||
|
// update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||||
// 查询出来的顺序可能是乱的,需要排个序
|
// 查询出来的顺序可能是乱的,需要排个序
|
||||||
for (String key : keyArray) {
|
for (String key : keyArray) {
|
||||||
for (DictModel dict : dicts) {
|
List<DictModel> res = dicts.stream().filter(i -> key.equals(i.getValue())).collect(Collectors.toList());
|
||||||
if (key.equals(dict.getValue())) {
|
if (res.size() > 0) {
|
||||||
texts.add(dict.getText());
|
texts.add(res.get(0).getText());
|
||||||
break;
|
} else if (!delNotExist) {
|
||||||
}
|
texts.add(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// update-end--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||||
|
|
||||||
return texts;
|
return texts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,12 +216,49 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String keyword, int pageSize) {
|
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize) {
|
||||||
Page<DictModel> page = new Page<DictModel>(1, pageSize);
|
Page<DictModel> page = new Page<DictModel>(1, pageSize);
|
||||||
IPage<DictModel> pageList = baseMapper.queryTableDictItems(page, table, text, code, "%"+keyword+"%");
|
page.setSearchCount(false);
|
||||||
|
String filterSql = getFilterSql(text, code, condition, keyword);
|
||||||
|
IPage<DictModel> pageList = baseMapper.queryTableDictWithFilter(page, table, text, code, filterSql);
|
||||||
return pageList.getRecords();
|
return pageList.getRecords();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取条件语句
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param condition
|
||||||
|
* @param keyword
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getFilterSql(String text, String code, String condition, String keyword){
|
||||||
|
String keywordSql = null, filterSql = "", sql_where = " where ";
|
||||||
|
if(oConvertUtils.isNotEmpty(keyword)){
|
||||||
|
// 判断是否是多选
|
||||||
|
if (keyword.contains(",")) {
|
||||||
|
String inKeywords = "\"" + keyword.replaceAll(",", "\",\"") + "\"";
|
||||||
|
keywordSql = "(" + text + " in (" + inKeywords + ") or " + code + " in (" + inKeywords + "))";
|
||||||
|
} else {
|
||||||
|
keywordSql = "("+text + " like '%"+keyword+"%' or "+ code + " like '%"+keyword+"%')";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)){
|
||||||
|
filterSql+= sql_where + condition + " and " + keywordSql;
|
||||||
|
}else if(oConvertUtils.isNotEmpty(condition)){
|
||||||
|
filterSql+= sql_where + condition;
|
||||||
|
}else if(oConvertUtils.isNotEmpty(keywordSql)){
|
||||||
|
filterSql+= sql_where + keywordSql;
|
||||||
|
}
|
||||||
|
return filterSql;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public List<DictModel> queryAllTableDictItems(String table, String text, String code, String condition, String keyword) {
|
||||||
|
String filterSql = getFilterSql(text, code, condition, keyword);
|
||||||
|
List<DictModel> ls = baseMapper.queryAllTableDictItems(table, text, code, filterSql);
|
||||||
|
return ls;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField) {
|
public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField) {
|
||||||
return baseMapper.queryTreeList(query,table, text, code, pidField, pid,hasChildField);
|
return baseMapper.queryTreeList(query,table, text, code, pidField, pid,hasChildField);
|
||||||
|
@ -238,4 +286,61 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||||
Page<DictModel> pageList = baseMapper.queryDictTablePageList(page, query);
|
Page<DictModel> pageList = baseMapper.queryDictTablePageList(page, query);
|
||||||
return pageList.getRecords();
|
return pageList.getRecords();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DictModel> getDictItems(String dictCode) {
|
||||||
|
List<DictModel> ls;
|
||||||
|
if (dictCode.contains(",")) {
|
||||||
|
//关联表字典(举例:sys_user,realname,id)
|
||||||
|
String[] params = dictCode.split(",");
|
||||||
|
if (params.length < 3) {
|
||||||
|
// 字典Code格式不正确
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//SQL注入校验(只限制非法串改数据库)
|
||||||
|
final String[] sqlInjCheck = {params[0], params[1], params[2]};
|
||||||
|
SqlInjectionUtil.filterContent(sqlInjCheck);
|
||||||
|
if (params.length == 4) {
|
||||||
|
// SQL注入校验(查询条件SQL 特殊check,此方法仅供此处使用)
|
||||||
|
SqlInjectionUtil.specialFilterContent(params[3]);
|
||||||
|
ls = this.queryTableDictItemsByCodeAndFilter(params[0], params[1], params[2], params[3]);
|
||||||
|
} else if (params.length == 3) {
|
||||||
|
ls = this.queryTableDictItemsByCode(params[0], params[1], params[2]);
|
||||||
|
} else {
|
||||||
|
// 字典Code格式不正确
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//字典表
|
||||||
|
ls = this.queryDictItemsByCode(dictCode);
|
||||||
|
}
|
||||||
|
return ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DictModel> loadDict(String dictCode, String keyword, Integer pageSize) {
|
||||||
|
if (dictCode.contains(",")) {
|
||||||
|
//update-begin-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件
|
||||||
|
String[] params = dictCode.split(",");
|
||||||
|
String condition = null;
|
||||||
|
if (params.length != 3 && params.length != 4) {
|
||||||
|
// 字典Code格式不正确
|
||||||
|
return null;
|
||||||
|
} else if (params.length == 4) {
|
||||||
|
condition = params[3];
|
||||||
|
}
|
||||||
|
List<DictModel> ls;
|
||||||
|
if (pageSize != null) {
|
||||||
|
ls = this.queryLittleTableDictItems(params[0], params[1], params[2], condition, keyword, pageSize);
|
||||||
|
} else {
|
||||||
|
ls = this.queryAllTableDictItems(params[0], params[1], params[2], condition, keyword);
|
||||||
|
}
|
||||||
|
//update-end-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件
|
||||||
|
return ls;
|
||||||
|
} else {
|
||||||
|
// 字典Code格式不正确
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.jeecg.modules.system.service.impl;
|
package org.jeecg.modules.system.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import org.jeecg.modules.system.entity.SysPosition;
|
import org.jeecg.modules.system.entity.SysPosition;
|
||||||
import org.jeecg.modules.system.mapper.SysPositionMapper;
|
import org.jeecg.modules.system.mapper.SysPositionMapper;
|
||||||
|
@ -15,4 +16,11 @@ import org.springframework.stereotype.Service;
|
||||||
@Service
|
@Service
|
||||||
public class SysPositionServiceImpl extends ServiceImpl<SysPositionMapper, SysPosition> implements ISysPositionService {
|
public class SysPositionServiceImpl extends ServiceImpl<SysPositionMapper, SysPosition> implements ISysPositionService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysPosition getByCode(String code) {
|
||||||
|
LambdaQueryWrapper<SysPosition> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysPosition::getCode, code);
|
||||||
|
return super.getOne(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package org.jeecg.modules.system.service.impl;
|
package org.jeecg.modules.system.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.util.DateUtils;
|
||||||
import org.jeecg.common.util.PasswordUtil;
|
import org.jeecg.common.util.PasswordUtil;
|
||||||
import org.jeecg.common.util.UUIDGenerator;
|
import org.jeecg.common.util.UUIDGenerator;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
@ -14,12 +16,10 @@ import org.jeecg.modules.system.mapper.SysThirdAccountMapper;
|
||||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||||
import org.jeecg.modules.system.mapper.SysUserRoleMapper;
|
import org.jeecg.modules.system.mapper.SysUserRoleMapper;
|
||||||
import org.jeecg.modules.system.service.ISysThirdAccountService;
|
import org.jeecg.modules.system.service.ISysThirdAccountService;
|
||||||
import org.jeecg.modules.system.service.ISysUserService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import java.util.Date;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +55,8 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||||
thirdQuery.eq(SysThirdAccount::getThirdType,account.getThirdType());
|
thirdQuery.eq(SysThirdAccount::getThirdType,account.getThirdType());
|
||||||
SysThirdAccount sysThirdAccounts = sysThirdAccountMapper.selectOne(thirdQuery);
|
SysThirdAccount sysThirdAccounts = sysThirdAccountMapper.selectOne(thirdQuery);
|
||||||
if(sysThirdAccounts!=null){
|
if(sysThirdAccounts!=null){
|
||||||
sysThirdAccountMapper.deleteById(sysThirdAccounts.getId());
|
sysThirdAccount.setThirdUserId(sysThirdAccounts.getThirdUserId());
|
||||||
|
sysThirdAccountMapper.deleteById(sysThirdAccounts.getId());
|
||||||
}
|
}
|
||||||
//更新用户账户表sys_user_id
|
//更新用户账户表sys_user_id
|
||||||
sysThirdAccountMapper.update(sysThirdAccount,query);
|
sysThirdAccountMapper.update(sysThirdAccount,query);
|
||||||
|
@ -67,6 +68,13 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||||
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
|
||||||
query.eq(SysThirdAccount::getThirdUserUuid,thirdUserUuid);
|
query.eq(SysThirdAccount::getThirdUserUuid,thirdUserUuid);
|
||||||
SysThirdAccount account = sysThirdAccountMapper.selectOne(query);
|
SysThirdAccount account = sysThirdAccountMapper.selectOne(query);
|
||||||
|
//通过用户名查询数据库是否已存在
|
||||||
|
SysUser userByName = sysUserMapper.getUserByName(thirdUserUuid);
|
||||||
|
if(null!=userByName){
|
||||||
|
//如果账号存在的话,则自动加上一个时间戳
|
||||||
|
String format = DateUtils.yyyymmddhhmmss.get().format(new Date());
|
||||||
|
thirdUserUuid = thirdUserUuid + format;
|
||||||
|
}
|
||||||
//添加用户
|
//添加用户
|
||||||
SysUser user = new SysUser();
|
SysUser user = new SysUser();
|
||||||
user.setActivitiSync(CommonConstant.ACT_SYNC_0);
|
user.setActivitiSync(CommonConstant.ACT_SYNC_0);
|
||||||
|
@ -103,4 +111,26 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||||
sysUserRoleMapper.insert(userRole);
|
sysUserRoleMapper.insert(userRole);
|
||||||
return userid;
|
return userid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysThirdAccount getOneBySysUserId(String sysUserId, String thirdType) {
|
||||||
|
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysThirdAccount::getSysUserId, sysUserId);
|
||||||
|
queryWrapper.eq(SysThirdAccount::getThirdType, thirdType);
|
||||||
|
return super.getOne(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysThirdAccount getOneByThirdUserId(String thirdUserId, String thirdType) {
|
||||||
|
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysThirdAccount::getThirdUserId, thirdUserId);
|
||||||
|
queryWrapper.eq(SysThirdAccount::getThirdType, thirdType);
|
||||||
|
return super.getOne(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SysThirdAccount> listThirdUserIdByUsername(String[] sysUsernameArr, String thirdType) {
|
||||||
|
return sysThirdAccountMapper.selectThirdIdsByUsername(sysUsernameArr, thirdType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package org.jeecg.modules.system.service.impl;
|
package org.jeecg.modules.system.service.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.system.entity.SysDepart;
|
import org.jeecg.modules.system.entity.SysDepart;
|
||||||
import org.jeecg.modules.system.entity.SysUser;
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
@ -100,34 +104,58 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<SysUser> queryUserByDepCode(String depCode,String realname) {
|
public List<SysUser> queryUserByDepCode(String depCode,String realname) {
|
||||||
LambdaQueryWrapper<SysDepart> queryByDepCode = new LambdaQueryWrapper<SysDepart>();
|
//update-begin-author:taoyan date:20210422 for: 根据部门选择用户接口代码优化
|
||||||
queryByDepCode.likeRight(SysDepart::getOrgCode,depCode);
|
if(oConvertUtils.isNotEmpty(realname)){
|
||||||
List<SysDepart> sysDepartList = sysDepartService.list(queryByDepCode);
|
realname = realname.trim();
|
||||||
List<String> depIds = sysDepartList.stream().map(SysDepart::getId).collect(Collectors.toList());
|
|
||||||
|
|
||||||
LambdaQueryWrapper<SysUserDepart> queryUDep = new LambdaQueryWrapper<SysUserDepart>();
|
|
||||||
queryUDep.in(SysUserDepart::getDepId, depIds);
|
|
||||||
List<String> userIdList = new ArrayList<>();
|
|
||||||
List<SysUserDepart> uDepList = this.list(queryUDep);
|
|
||||||
if(uDepList != null && uDepList.size() > 0) {
|
|
||||||
for(SysUserDepart uDep : uDepList) {
|
|
||||||
userIdList.add(uDep.getUserId());
|
|
||||||
}
|
|
||||||
LambdaQueryWrapper<SysUser> queryUser = new LambdaQueryWrapper<SysUser>();
|
|
||||||
queryUser.in(SysUser::getId,userIdList);
|
|
||||||
if(oConvertUtils.isNotEmpty(realname)){
|
|
||||||
queryUser.like(SysUser::getRealname,realname.trim());
|
|
||||||
}
|
|
||||||
List<SysUser> userList = (List<SysUser>) sysUserService.list(queryUser);
|
|
||||||
//update-begin-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
|
|
||||||
for (SysUser sysUser : userList) {
|
|
||||||
sysUser.setSalt("");
|
|
||||||
sysUser.setPassword("");
|
|
||||||
}
|
|
||||||
//update-end-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
|
|
||||||
return userList;
|
|
||||||
}
|
}
|
||||||
return new ArrayList<SysUser>();
|
List<SysUser> userList = this.baseMapper.queryDepartUserList(depCode, realname);
|
||||||
|
Map<String, SysUser> map = new HashMap<String, SysUser>();
|
||||||
|
for (SysUser sysUser : userList) {
|
||||||
|
// 返回的用户数据去掉密码信息
|
||||||
|
sysUser.setSalt("");
|
||||||
|
sysUser.setPassword("");
|
||||||
|
map.put(sysUser.getId(), sysUser);
|
||||||
|
}
|
||||||
|
return new ArrayList<SysUser>(map.values());
|
||||||
|
//update-end-author:taoyan date:20210422 for: 根据部门选择用户接口代码优化
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo) {
|
||||||
|
IPage<SysUser> pageList = null;
|
||||||
|
// 部门ID不存在 直接查询用户表即可
|
||||||
|
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
|
||||||
|
if(oConvertUtils.isEmpty(departId)){
|
||||||
|
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||||
|
if(oConvertUtils.isNotEmpty(username)){
|
||||||
|
query.like(SysUser::getUsername, username);
|
||||||
|
}
|
||||||
|
pageList = sysUserService.page(page, query);
|
||||||
|
}else{
|
||||||
|
// 有部门ID 需要走自定义sql
|
||||||
|
SysDepart sysDepart = sysDepartService.getById(departId);
|
||||||
|
pageList = this.baseMapper.queryDepartUserPageList(page, sysDepart.getOrgCode(), username, realname);
|
||||||
|
}
|
||||||
|
List<SysUser> userList = pageList.getRecords();
|
||||||
|
if(userList!=null && userList.size()>0){
|
||||||
|
List<String> userIds = userList.stream().map(SysUser::getId).collect(Collectors.toList());
|
||||||
|
Map<String, SysUser> map = new HashMap<String, SysUser>();
|
||||||
|
if(userIds!=null && userIds.size()>0){
|
||||||
|
// 查部门名称
|
||||||
|
Map<String,String> useDepNames = sysUserService.getDepNamesByUserIds(userIds);
|
||||||
|
userList.forEach(item->{
|
||||||
|
//TODO 临时借用这个字段用于页面展示
|
||||||
|
item.setOrgCodeTxt(useDepNames.get(item.getId()));
|
||||||
|
item.setSalt("");
|
||||||
|
item.setPassword("");
|
||||||
|
// 去重
|
||||||
|
map.put(item.getId(), item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pageList.setRecords(new ArrayList<SysUser>(map.values()));
|
||||||
|
}
|
||||||
|
return pageList;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,12 @@ import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CacheConstant;
|
import org.jeecg.common.constant.CacheConstant;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
import org.jeecg.modules.base.service.BaseCommonService;
|
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
import org.jeecg.common.system.vo.SysUserCacheInfo;
|
import org.jeecg.common.system.vo.SysUserCacheInfo;
|
||||||
import org.jeecg.common.util.PasswordUtil;
|
import org.jeecg.common.util.PasswordUtil;
|
||||||
import org.jeecg.common.util.UUIDGenerator;
|
import org.jeecg.common.util.UUIDGenerator;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.base.service.BaseCommonService;
|
||||||
import org.jeecg.modules.system.entity.*;
|
import org.jeecg.modules.system.entity.*;
|
||||||
import org.jeecg.modules.system.mapper.*;
|
import org.jeecg.modules.system.mapper.*;
|
||||||
import org.jeecg.modules.system.model.SysUserSysDepartModel;
|
import org.jeecg.modules.system.model.SysUserSysDepartModel;
|
||||||
|
@ -62,6 +62,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||||
private SysDepartRoleMapper sysDepartRoleMapper;
|
private SysDepartRoleMapper sysDepartRoleMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private BaseCommonService baseCommonService;
|
private BaseCommonService baseCommonService;
|
||||||
|
@Autowired
|
||||||
|
private SysThirdAccountMapper sysThirdAccountMapper;
|
||||||
|
@Autowired
|
||||||
|
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||||
|
@Autowired
|
||||||
|
ThirdAppDingtalkServiceImpl dingtalkService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true)
|
@CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true)
|
||||||
|
@ -408,6 +414,16 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||||
line += sysUserDepartMapper.delete(new LambdaQueryWrapper<SysUserDepart>().in(SysUserDepart::getUserId, userIds));
|
line += sysUserDepartMapper.delete(new LambdaQueryWrapper<SysUserDepart>().in(SysUserDepart::getUserId, userIds));
|
||||||
//3. 删除用户角色关系
|
//3. 删除用户角色关系
|
||||||
line += sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, userIds));
|
line += sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, userIds));
|
||||||
|
//4.同步删除第三方App的用户
|
||||||
|
try {
|
||||||
|
dingtalkService.removeThirdAppUser(userIds);
|
||||||
|
wechatEnterpriseService.removeThirdAppUser(userIds);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("同步删除第三方App的用户失败:", e);
|
||||||
|
}
|
||||||
|
//5. 删除第三方用户表(因为第4步需要用到第三方用户表,所以在他之后删)
|
||||||
|
line += sysThirdAccountMapper.delete(new LambdaQueryWrapper<SysThirdAccount>().in(SysThirdAccount::getSysUserId, userIds));
|
||||||
|
|
||||||
return line != 0;
|
return line != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,4 +455,88 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||||
return userMapper.queryByDepIds(departIds,username);
|
return userMapper.queryByDepIds(departIds,username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void saveUser(SysUser user, String selectedRoles, String selectedDeparts) {
|
||||||
|
//step.1 保存用户
|
||||||
|
this.save(user);
|
||||||
|
//step.2 保存角色
|
||||||
|
if(oConvertUtils.isNotEmpty(selectedRoles)) {
|
||||||
|
String[] arr = selectedRoles.split(",");
|
||||||
|
for (String roleId : arr) {
|
||||||
|
SysUserRole userRole = new SysUserRole(user.getId(), roleId);
|
||||||
|
sysUserRoleMapper.insert(userRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//step.3 保存所属部门
|
||||||
|
if(oConvertUtils.isNotEmpty(selectedDeparts)) {
|
||||||
|
String[] arr = selectedDeparts.split(",");
|
||||||
|
for (String deaprtId : arr) {
|
||||||
|
SysUserDepart userDeaprt = new SysUserDepart(user.getId(), deaprtId);
|
||||||
|
sysUserDepartMapper.insert(userDeaprt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
|
||||||
|
public void editUser(SysUser user, String roles, String departs) {
|
||||||
|
//step.1 修改用户基础信息
|
||||||
|
this.updateById(user);
|
||||||
|
//step.2 修改角色
|
||||||
|
//处理用户角色 先删后加
|
||||||
|
sysUserRoleMapper.delete(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, user.getId()));
|
||||||
|
if(oConvertUtils.isNotEmpty(roles)) {
|
||||||
|
String[] arr = roles.split(",");
|
||||||
|
for (String roleId : arr) {
|
||||||
|
SysUserRole userRole = new SysUserRole(user.getId(), roleId);
|
||||||
|
sysUserRoleMapper.insert(userRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//step.3 修改部门
|
||||||
|
String[] arr = {};
|
||||||
|
if(oConvertUtils.isNotEmpty(departs)){
|
||||||
|
arr = departs.split(",");
|
||||||
|
}
|
||||||
|
//查询已关联部门
|
||||||
|
List<SysUserDepart> userDepartList = sysUserDepartMapper.selectList(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
|
||||||
|
if(userDepartList != null && userDepartList.size()>0){
|
||||||
|
for(SysUserDepart depart : userDepartList ){
|
||||||
|
//修改已关联部门删除部门用户角色关系
|
||||||
|
if(!Arrays.asList(arr).contains(depart.getDepId())){
|
||||||
|
List<SysDepartRole> sysDepartRoleList = sysDepartRoleMapper.selectList(
|
||||||
|
new QueryWrapper<SysDepartRole>().lambda().eq(SysDepartRole::getDepartId,depart.getDepId()));
|
||||||
|
List<String> roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList());
|
||||||
|
if(roleIds != null && roleIds.size()>0){
|
||||||
|
departRoleUserMapper.delete(new QueryWrapper<SysDepartRoleUser>().lambda().eq(SysDepartRoleUser::getUserId, user.getId())
|
||||||
|
.in(SysDepartRoleUser::getDroleId,roleIds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//先删后加
|
||||||
|
sysUserDepartMapper.delete(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
|
||||||
|
if(oConvertUtils.isNotEmpty(departs)) {
|
||||||
|
for (String departId : arr) {
|
||||||
|
SysUserDepart userDepart = new SysUserDepart(user.getId(), departId);
|
||||||
|
sysUserDepartMapper.insert(userDepart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//step.4 修改手机号和邮箱
|
||||||
|
// 更新手机号、邮箱空字符串为 null
|
||||||
|
userMapper.updateNullByEmptyString("email");
|
||||||
|
userMapper.updateNullByEmptyString("phone");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> userIdToUsername(Collection<String> userIdList) {
|
||||||
|
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.in(SysUser::getId, userIdList);
|
||||||
|
List<SysUser> userList = super.list(queryWrapper);
|
||||||
|
return userList.stream().map(SysUser::getUsername).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,769 @@
|
||||||
|
package org.jeecg.modules.system.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.jeecg.dingtalk.api.base.JdtBaseAPI;
|
||||||
|
import com.jeecg.dingtalk.api.core.response.Response;
|
||||||
|
import com.jeecg.dingtalk.api.core.vo.AccessToken;
|
||||||
|
import com.jeecg.dingtalk.api.core.vo.PageResult;
|
||||||
|
import com.jeecg.dingtalk.api.department.JdtDepartmentAPI;
|
||||||
|
import com.jeecg.dingtalk.api.department.vo.Department;
|
||||||
|
import com.jeecg.dingtalk.api.message.JdtMessageAPI;
|
||||||
|
import com.jeecg.dingtalk.api.message.vo.ActionCardMessage;
|
||||||
|
import com.jeecg.dingtalk.api.message.vo.Message;
|
||||||
|
import com.jeecg.dingtalk.api.message.vo.TextMessage;
|
||||||
|
import com.jeecg.dingtalk.api.user.JdtUserAPI;
|
||||||
|
import com.jeecg.dingtalk.api.user.body.GetUserListBody;
|
||||||
|
import com.jeecg.dingtalk.api.user.vo.User;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
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.thirdapp.ThirdAppConfig;
|
||||||
|
import org.jeecg.modules.system.entity.*;
|
||||||
|
import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
|
||||||
|
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||||
|
import org.jeecg.modules.system.service.*;
|
||||||
|
import org.jeecg.modules.system.vo.thirdapp.JdtDepartmentTreeVo;
|
||||||
|
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方App对接:钉钉实现类
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ThirdAppConfig thirdAppConfig;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysDepartService sysDepartService;
|
||||||
|
@Autowired
|
||||||
|
private ISysUserService sysUserService;
|
||||||
|
@Autowired
|
||||||
|
private ISysThirdAccountService sysThirdAccountService;
|
||||||
|
@Autowired
|
||||||
|
private ISysUserDepartService sysUserDepartService;
|
||||||
|
@Autowired
|
||||||
|
private ISysPositionService sysPositionService;
|
||||||
|
@Autowired
|
||||||
|
private SysAnnouncementSendMapper sysAnnouncementSendMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccessToken() {
|
||||||
|
String appKey = thirdAppConfig.getDingtalk().getClientId();
|
||||||
|
String appSecret = thirdAppConfig.getDingtalk().getClientSecret();
|
||||||
|
AccessToken accessToken = JdtBaseAPI.getAccessToken(appKey, appSecret);
|
||||||
|
if (accessToken != null) {
|
||||||
|
return accessToken.getAccessToken();
|
||||||
|
}
|
||||||
|
log.warn("获取AccessToken失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean syncLocalDepartmentToThirdApp(String ids) {
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 获取【钉钉】所有的部门
|
||||||
|
List<Department> departments = JdtDepartmentAPI.listAll(accessToken);
|
||||||
|
// 删除钉钉有但本地没有的部门(以本地部门数据为主)(钉钉不能创建同名部门,只能先删除)
|
||||||
|
List<SysDepart> sysDepartList = sysDepartService.list();
|
||||||
|
for1:
|
||||||
|
for (Department department : departments) {
|
||||||
|
for (SysDepart depart : sysDepartList) {
|
||||||
|
// id相同,代表已存在,不删除
|
||||||
|
String sourceIdentifier = department.getSource_identifier();
|
||||||
|
if (sourceIdentifier != null && sourceIdentifier.equals(depart.getId())) {
|
||||||
|
continue for1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 循环到此说明本地没有,删除
|
||||||
|
int deptId = department.getDept_id();
|
||||||
|
// 钉钉不允许删除带有用户的部门,所以需要判断下,将有用户的部门的用户移动至根部门
|
||||||
|
Response<List<String>> userIdRes = JdtUserAPI.getUserListIdByDeptId(deptId, accessToken);
|
||||||
|
if (userIdRes.isSuccess() && userIdRes.getResult().size() > 0) {
|
||||||
|
for (String userId : userIdRes.getResult()) {
|
||||||
|
User updateUser = new User();
|
||||||
|
updateUser.setUserid(userId);
|
||||||
|
updateUser.setDept_id_list(1);
|
||||||
|
JdtUserAPI.update(updateUser, accessToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JdtDepartmentAPI.delete(deptId, accessToken);
|
||||||
|
}
|
||||||
|
// 获取本地所有部门树结构
|
||||||
|
List<SysDepartTreeModel> sysDepartsTree = sysDepartService.queryTreeList();
|
||||||
|
// -- 钉钉不能创建新的顶级部门,所以新的顶级部门的parentId就为1
|
||||||
|
Department parent = new Department();
|
||||||
|
parent.setDept_id(1);
|
||||||
|
// 递归同步部门
|
||||||
|
departments = JdtDepartmentAPI.listAll(accessToken);
|
||||||
|
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归同步部门到本地
|
||||||
|
public void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Department> departments, Department parent, String accessToken) {
|
||||||
|
if (sysDepartsTree != null && sysDepartsTree.size() != 0) {
|
||||||
|
for1:
|
||||||
|
for (SysDepartTreeModel depart : sysDepartsTree) {
|
||||||
|
for (Department department : departments) {
|
||||||
|
// id相同,代表已存在,执行修改操作
|
||||||
|
String sourceIdentifier = department.getSource_identifier();
|
||||||
|
if (sourceIdentifier != null && sourceIdentifier.equals(depart.getId())) {
|
||||||
|
this.sysDepartToDtDepartment(depart, department, parent.getDept_id());
|
||||||
|
JdtDepartmentAPI.update(department, accessToken);
|
||||||
|
// 紧接着同步子级
|
||||||
|
this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken);
|
||||||
|
// 跳出外部循环
|
||||||
|
continue for1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 循环到此说明是新部门,直接调接口创建
|
||||||
|
Department newDepartment = this.sysDepartToDtDepartment(depart, parent.getDept_id());
|
||||||
|
Response<Integer> response = JdtDepartmentAPI.create(newDepartment, accessToken);
|
||||||
|
// 创建成功,将返回的id绑定到本地
|
||||||
|
if (response.getResult() != null) {
|
||||||
|
Department newParent = new Department();
|
||||||
|
newParent.setDept_id(response.getResult());
|
||||||
|
// 紧接着同步子级
|
||||||
|
this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken);
|
||||||
|
}
|
||||||
|
// 收集错误信息
|
||||||
|
// this.syncUserCollectErrInfo(errCode, sysUser, errInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 = JdtDepartmentAPI.listAll(accessToken);
|
||||||
|
String username = JwtUtil.getUserNameByToken(SpringContextUtils.getHttpServletRequest());
|
||||||
|
List<JdtDepartmentTreeVo> departmentTreeList = JdtDepartmentTreeVo.listToTree(departments);
|
||||||
|
// 递归同步部门
|
||||||
|
this.syncDepartmentToLocalRecursion(departmentTreeList, null, username, syncInfo, accessToken);
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void syncDepartmentToLocalRecursion(List<JdtDepartmentTreeVo> departmentTreeList, String sysParentId, String username, SyncInfoVo syncInfo, String accessToken) {
|
||||||
|
|
||||||
|
if (departmentTreeList != null && departmentTreeList.size() != 0) {
|
||||||
|
for (JdtDepartmentTreeVo departmentTree : departmentTreeList) {
|
||||||
|
LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
// 根据 source_identifier 字段查询
|
||||||
|
queryWrapper.eq(SysDepart::getId, departmentTree.getSource_identifier());
|
||||||
|
SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
|
||||||
|
if (sysDepart != null) {
|
||||||
|
// 执行更新操作
|
||||||
|
SysDepart updateSysDepart = this.dtDepartmentToSysDepart(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, accessToken);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 执行新增操作
|
||||||
|
SysDepart newSysDepart = this.dtDepartmentToSysDepart(departmentTree, null);
|
||||||
|
if (sysParentId != null) {
|
||||||
|
newSysDepart.setParentId(sysParentId);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sysDepartService.saveDepartData(newSysDepart, username);
|
||||||
|
// 更新钉钉 source_identifier
|
||||||
|
Department updateDtDepart = new Department();
|
||||||
|
updateDtDepart.setDept_id(departmentTree.getDept_id());
|
||||||
|
updateDtDepart.setSource_identifier(newSysDepart.getId());
|
||||||
|
Response response = JdtDepartmentAPI.update(updateDtDepart, accessToken);
|
||||||
|
if (!response.isSuccess()) {
|
||||||
|
throw new RuntimeException(response.getErrmsg());
|
||||||
|
}
|
||||||
|
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, accessToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean syncDepartCollectErrInfo(Exception e, Department department, SyncInfoVo syncInfo) {
|
||||||
|
String msg;
|
||||||
|
if (e instanceof DuplicateKeyException) {
|
||||||
|
msg = e.getCause().getMessage();
|
||||||
|
} else {
|
||||||
|
msg = e.getMessage();
|
||||||
|
}
|
||||||
|
String str = String.format("部门 %s(%s) 同步失败!错误信息:%s", department.getName(), department.getDept_id(), msg);
|
||||||
|
syncInfo.addFailInfo(str);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SyncInfoVo syncLocalUserToThirdApp(String ids) {
|
||||||
|
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
syncInfo.addFailInfo("accessToken获取失败!");
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
List<SysUser> sysUsers;
|
||||||
|
if (StringUtils.isNotBlank(ids)) {
|
||||||
|
String[] idList = ids.split(",");
|
||||||
|
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.in(SysUser::getId, (Object[]) idList);
|
||||||
|
// 获取本地指定用户
|
||||||
|
sysUsers = sysUserService.list(queryWrapper);
|
||||||
|
} else {
|
||||||
|
// 获取本地所有用户
|
||||||
|
sysUsers = sysUserService.list();
|
||||||
|
}
|
||||||
|
// 查询钉钉所有的部门,用于同步用户和部门的关系
|
||||||
|
List<Department> allDepartment = JdtDepartmentAPI.listAll(accessToken);
|
||||||
|
|
||||||
|
for (SysUser sysUser : sysUsers) {
|
||||||
|
// 外部模拟登陆临时账号,不同步
|
||||||
|
if ("_reserve_user_external".equals(sysUser.getUsername())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 钉钉用户信息,不为null代表已同步过
|
||||||
|
Response<User> dtUserInfo;
|
||||||
|
/*
|
||||||
|
* 判断是否同步过的逻辑:
|
||||||
|
* 1. 查询 sys_third_account(第三方账号表)是否有数据,如果有代表已同步
|
||||||
|
* 2. 本地表里没有,就先用手机号判断,不通过再用username判断。
|
||||||
|
*/
|
||||||
|
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneBySysUserId(sysUser.getId(), ThirdAppConfig.DINGTALK.toLowerCase());
|
||||||
|
if (sysThirdAccount != null && oConvertUtils.isNotEmpty(sysThirdAccount.getThirdUserId())) {
|
||||||
|
// sys_third_account 表匹配成功,通过第三方userId查询出第三方userInfo
|
||||||
|
dtUserInfo = JdtUserAPI.getUserById(sysThirdAccount.getThirdUserId(), accessToken);
|
||||||
|
} else {
|
||||||
|
// 手机号匹配
|
||||||
|
Response<String> thirdUserId = JdtUserAPI.getUseridByMobile(sysUser.getPhone(), accessToken);
|
||||||
|
// 手机号匹配成功
|
||||||
|
if (thirdUserId.isSuccess() && oConvertUtils.isNotEmpty(thirdUserId.getResult())) {
|
||||||
|
// 通过查询到的userId查询用户详情
|
||||||
|
dtUserInfo = JdtUserAPI.getUserById(thirdUserId.getResult(), accessToken);
|
||||||
|
} else {
|
||||||
|
// 手机号匹配失败,尝试使用username匹配
|
||||||
|
dtUserInfo = JdtUserAPI.getUserById(sysUser.getUsername(), accessToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String dtUserId;
|
||||||
|
// api 接口是否执行成功
|
||||||
|
boolean apiSuccess;
|
||||||
|
// 已同步就更新,否则就创建
|
||||||
|
if (dtUserInfo != null && dtUserInfo.isSuccess() && dtUserInfo.getResult() != null) {
|
||||||
|
User dtUser = dtUserInfo.getResult();
|
||||||
|
dtUserId = dtUser.getUserid();
|
||||||
|
User updateQwUser = this.sysUserToDtUser(sysUser, dtUser, allDepartment);
|
||||||
|
Response<JSONObject> updateRes = JdtUserAPI.update(updateQwUser, accessToken);
|
||||||
|
// 收集成功/失败信息
|
||||||
|
apiSuccess = this.syncUserCollectErrInfo(updateRes, sysUser, syncInfo);
|
||||||
|
} else {
|
||||||
|
User newQwUser = this.sysUserToDtUser(sysUser, allDepartment);
|
||||||
|
Response<String> createRes = JdtUserAPI.create(newQwUser, accessToken);
|
||||||
|
dtUserId = createRes.getResult();
|
||||||
|
// 收集成功/失败信息
|
||||||
|
apiSuccess = this.syncUserCollectErrInfo(createRes, sysUser, syncInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// api 接口执行成功,并且 sys_third_account 表匹配失败,就向 sys_third_account 里插入一条数据
|
||||||
|
if (apiSuccess && (sysThirdAccount == null || oConvertUtils.isEmpty(sysThirdAccount.getThirdUserId()))) {
|
||||||
|
if (sysThirdAccount == null) {
|
||||||
|
sysThirdAccount = new SysThirdAccount();
|
||||||
|
sysThirdAccount.setSysUserId(sysUser.getId());
|
||||||
|
sysThirdAccount.setStatus(1);
|
||||||
|
sysThirdAccount.setDelFlag(0);
|
||||||
|
sysThirdAccount.setThirdType(ThirdAppConfig.DINGTALK.toLowerCase());
|
||||||
|
}
|
||||||
|
// 设置第三方app用户ID
|
||||||
|
sysThirdAccount.setThirdUserId(dtUserId);
|
||||||
|
sysThirdAccountService.saveOrUpdate(sysThirdAccount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SyncInfoVo syncThirdAppUserToLocal() {
|
||||||
|
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
syncInfo.addFailInfo("accessToken获取失败!");
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取本地用户
|
||||||
|
List<SysUser> sysUsersList = sysUserService.list();
|
||||||
|
|
||||||
|
// 查询钉钉所有的部门,用于同步用户和部门的关系
|
||||||
|
List<Department> allDepartment = JdtDepartmentAPI.listAll(accessToken);
|
||||||
|
// 根据钉钉部门查询所有钉钉用户,用于反向同步到本地
|
||||||
|
List<User> ddUserList = this.getDtAllUserByDepartment(allDepartment, accessToken);
|
||||||
|
|
||||||
|
for (User dtUserInfo : ddUserList) {
|
||||||
|
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneByThirdUserId(dtUserInfo.getUserid(), ThirdAppConfig.DINGTALK.toLowerCase());
|
||||||
|
List<SysUser> collect = sysUsersList.stream().filter(user -> (dtUserInfo.getMobile().equals(user.getPhone()) || dtUserInfo.getUserid().equals(user.getUsername()))
|
||||||
|
).collect(Collectors.toList());
|
||||||
|
if (collect != null && collect.size() > 0) {
|
||||||
|
SysUser sysUserTemp = collect.get(0);
|
||||||
|
// 循环到此说明用户匹配成功,进行更新操作
|
||||||
|
SysUser updateSysUser = this.dtUserToSysUser(dtUserInfo, sysUserTemp);
|
||||||
|
try {
|
||||||
|
sysUserService.updateById(updateSysUser);
|
||||||
|
String str = String.format("用户 %s(%s) 更新成功!", updateSysUser.getRealname(), updateSysUser.getUsername());
|
||||||
|
syncInfo.addSuccessInfo(str);
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.syncUserCollectErrInfo(e, dtUserInfo, syncInfo);
|
||||||
|
}
|
||||||
|
//第三方账号关系表
|
||||||
|
this.thirdAccountSaveOrUpdate(sysThirdAccount, updateSysUser.getId(), dtUserInfo.getUserid());
|
||||||
|
}else{
|
||||||
|
// 如果没有匹配到用户,则走创建逻辑
|
||||||
|
SysUser newSysUser = this.dtUserToSysUser(dtUserInfo);
|
||||||
|
try {
|
||||||
|
sysUserService.save(newSysUser);
|
||||||
|
String str = String.format("用户 %s(%s) 创建成功!", newSysUser.getRealname(), newSysUser.getUsername());
|
||||||
|
syncInfo.addSuccessInfo(str);
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.syncUserCollectErrInfo(e, dtUserInfo, syncInfo);
|
||||||
|
}
|
||||||
|
//第三方账号关系表
|
||||||
|
this.thirdAccountSaveOrUpdate(null, newSysUser.getId(), dtUserInfo.getUserid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<User> getDtAllUserByDepartment(List<Department> allDepartment, String accessToken) {
|
||||||
|
// 根据钉钉部门查询所有钉钉用户,用于反向同步到本地
|
||||||
|
List<User> userList = new ArrayList<>();
|
||||||
|
for (Department department : allDepartment) {
|
||||||
|
this.getUserListByDeptIdRecursion(department.getDept_id(), 0, userList, accessToken);
|
||||||
|
}
|
||||||
|
return userList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归查询所有用户
|
||||||
|
*/
|
||||||
|
private void getUserListByDeptIdRecursion(int deptId, int cursor, List<User> userList, String accessToken) {
|
||||||
|
// 根据钉钉部门查询所有钉钉用户,用于反向同步到本地
|
||||||
|
GetUserListBody getUserListBody = new GetUserListBody(deptId, cursor, 100);
|
||||||
|
Response<PageResult<User>> response = JdtUserAPI.getUserListByDeptId(getUserListBody, accessToken);
|
||||||
|
if (response.isSuccess()) {
|
||||||
|
PageResult<User> page = response.getResult();
|
||||||
|
userList.addAll(page.getList());
|
||||||
|
if (page.getHas_more()) {
|
||||||
|
this.getUserListByDeptIdRecursion(deptId, page.getNext_cursor(), userList, accessToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存或修改第三方登录表
|
||||||
|
*
|
||||||
|
* @param sysThirdAccount 第三方账户表对象,为null就新增数据,否则就修改
|
||||||
|
* @param sysUserId 本地系统用户ID
|
||||||
|
* @param dtUserId 钉钉用户ID
|
||||||
|
*/
|
||||||
|
private void thirdAccountSaveOrUpdate(SysThirdAccount sysThirdAccount, String sysUserId, String dtUserId) {
|
||||||
|
if (sysThirdAccount == null) {
|
||||||
|
sysThirdAccount = new SysThirdAccount();
|
||||||
|
sysThirdAccount.setSysUserId(sysUserId);
|
||||||
|
sysThirdAccount.setStatus(1);
|
||||||
|
sysThirdAccount.setDelFlag(0);
|
||||||
|
sysThirdAccount.setThirdType(ThirdAppConfig.DINGTALK.toLowerCase());
|
||||||
|
}
|
||||||
|
sysThirdAccount.setThirdUserId(dtUserId);
|
||||||
|
sysThirdAccountService.saveOrUpdate(sysThirdAccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】收集同步过程中的错误信息
|
||||||
|
*/
|
||||||
|
private boolean syncUserCollectErrInfo(Response<?> response, SysUser sysUser, SyncInfoVo syncInfo) {
|
||||||
|
if (!response.isSuccess()) {
|
||||||
|
String str = String.format("用户 %s(%s) 同步失败!错误码:%s——%s", sysUser.getUsername(), sysUser.getRealname(), response.getErrcode(), response.getErrmsg());
|
||||||
|
syncInfo.addFailInfo(str);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
String str = String.format("用户 %s(%s) 同步成功!", sysUser.getUsername(), sysUser.getRealname());
|
||||||
|
syncInfo.addSuccessInfo(str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】收集同步过程中的错误信息
|
||||||
|
*/
|
||||||
|
private boolean syncUserCollectErrInfo(Exception e, User dtUser, SyncInfoVo syncInfo) {
|
||||||
|
String msg;
|
||||||
|
if (e instanceof DuplicateKeyException) {
|
||||||
|
msg = e.getCause().getMessage();
|
||||||
|
} else {
|
||||||
|
msg = e.getMessage();
|
||||||
|
}
|
||||||
|
String str = String.format("用户 %s(%s) 同步失败!错误信息:%s", dtUser.getUserid(), dtUser.getName(), msg);
|
||||||
|
syncInfo.addFailInfo(str);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】将SysUser转为【钉钉】的User对象(创建新用户)
|
||||||
|
*/
|
||||||
|
private User sysUserToDtUser(SysUser sysUser, List<Department> allDepartment) {
|
||||||
|
User user = new User();
|
||||||
|
// 通过 username 来关联
|
||||||
|
user.setUserid(sysUser.getUsername());
|
||||||
|
return this.sysUserToDtUser(sysUser, user, allDepartment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】将SysUser转为【钉钉】的User对象(更新旧用户)
|
||||||
|
*/
|
||||||
|
private User sysUserToDtUser(SysUser sysUser, User user, List<Department> allDepartment) {
|
||||||
|
user.setName(sysUser.getRealname());
|
||||||
|
user.setMobile(sysUser.getPhone());
|
||||||
|
user.setTelephone(sysUser.getTelephone());
|
||||||
|
user.setJob_number(sysUser.getWorkNo());
|
||||||
|
// 职务翻译
|
||||||
|
if (oConvertUtils.isNotEmpty(sysUser.getPost())) {
|
||||||
|
SysPosition position = sysPositionService.getByCode(sysUser.getPost());
|
||||||
|
if (position != null) {
|
||||||
|
user.setTitle(position.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user.setEmail(sysUser.getEmail());
|
||||||
|
// 查询并同步用户部门关系
|
||||||
|
List<SysDepart> departList = this.getUserDepart(sysUser);
|
||||||
|
if (departList != null) {
|
||||||
|
List<Integer> departmentIdList = new ArrayList<>();
|
||||||
|
for (SysDepart sysDepart : departList) {
|
||||||
|
// 企业微信的部门id
|
||||||
|
Department department = this.getDepartmentByDepartId(sysDepart.getId(), allDepartment);
|
||||||
|
if (department != null) {
|
||||||
|
departmentIdList.add(department.getDept_id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user.setDept_id_list(departmentIdList.toArray(new Integer[]{}));
|
||||||
|
user.setDept_order_list(null);
|
||||||
|
}
|
||||||
|
if (oConvertUtils.isEmpty(user.getDept_id_list())) {
|
||||||
|
// 没有找到匹配部门,同步到根部门下
|
||||||
|
user.setDept_id_list(1);
|
||||||
|
user.setDept_order_list(null);
|
||||||
|
}
|
||||||
|
// --- 钉钉没有逻辑删除功能
|
||||||
|
// sysUser.getDelFlag()
|
||||||
|
// --- 钉钉没有冻结、启用禁用功能
|
||||||
|
// sysUser.getStatus()
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】将【钉钉】的User对象转为SysUser(创建新用户)
|
||||||
|
*/
|
||||||
|
private SysUser dtUserToSysUser(User dtUser) {
|
||||||
|
SysUser sysUser = new SysUser();
|
||||||
|
sysUser.setDelFlag(0);
|
||||||
|
// 通过 username 来关联
|
||||||
|
sysUser.setUsername(dtUser.getUserid());
|
||||||
|
// 密码默认为 “123456”,随机加盐
|
||||||
|
String password = "123456", salt = oConvertUtils.randomGen(8);
|
||||||
|
String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
|
||||||
|
sysUser.setSalt(salt);
|
||||||
|
sysUser.setPassword(passwordEncode);
|
||||||
|
return this.dtUserToSysUser(dtUser, sysUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】将【钉钉】的User对象转为SysUser(更新旧用户)
|
||||||
|
*/
|
||||||
|
private SysUser dtUserToSysUser(User dtUser, SysUser oldSysUser) {
|
||||||
|
SysUser sysUser = new SysUser();
|
||||||
|
BeanUtils.copyProperties(oldSysUser, sysUser);
|
||||||
|
sysUser.setRealname(dtUser.getName());
|
||||||
|
sysUser.setPhone(dtUser.getMobile());
|
||||||
|
sysUser.setTelephone(dtUser.getTelephone());
|
||||||
|
|
||||||
|
// 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
|
||||||
|
if (oConvertUtils.isNotEmpty(dtUser.getEmail()) && !dtUser.getEmail().equals(sysUser.getEmail())) {
|
||||||
|
sysUser.setEmail(dtUser.getEmail());
|
||||||
|
} else {
|
||||||
|
sysUser.setEmail(null);
|
||||||
|
}
|
||||||
|
// 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
|
||||||
|
if (oConvertUtils.isNotEmpty(dtUser.getMobile()) && !dtUser.getMobile().equals(sysUser.getPhone())) {
|
||||||
|
sysUser.setPhone(dtUser.getMobile());
|
||||||
|
} else {
|
||||||
|
sysUser.setPhone(null);
|
||||||
|
}
|
||||||
|
sysUser.setWorkNo(null);
|
||||||
|
// --- 钉钉没有逻辑删除功能
|
||||||
|
// sysUser.getDelFlag()
|
||||||
|
// --- 钉钉没有冻结、启用禁用功能
|
||||||
|
// sysUser.getStatus()
|
||||||
|
return sysUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户和部门的关系
|
||||||
|
*/
|
||||||
|
private List<SysDepart> getUserDepart(SysUser sysUser) {
|
||||||
|
// 根据用户部门关系表查询出用户的部门
|
||||||
|
LambdaQueryWrapper<SysUserDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysUserDepart::getUserId, sysUser.getId());
|
||||||
|
List<SysUserDepart> sysUserDepartList = sysUserDepartService.list(queryWrapper);
|
||||||
|
if (sysUserDepartList.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 根据用户部门
|
||||||
|
LambdaQueryWrapper<SysDepart> departQueryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
List<String> departIdList = sysUserDepartList.stream().map(SysUserDepart::getDepId).collect(Collectors.toList());
|
||||||
|
departQueryWrapper.in(SysDepart::getId, departIdList);
|
||||||
|
List<SysDepart> departList = sysDepartService.list(departQueryWrapper);
|
||||||
|
return departList.size() == 0 ? null : departList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据sysDepartId查询钉钉的部门
|
||||||
|
*/
|
||||||
|
private Department getDepartmentByDepartId(String departId, List<Department> allDepartment) {
|
||||||
|
for (Department department : allDepartment) {
|
||||||
|
if (departId.equals(department.getSource_identifier())) {
|
||||||
|
return department;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步部门】将SysDepartTreeModel转为【钉钉】的Department对象(创建新部门)
|
||||||
|
*/
|
||||||
|
private Department sysDepartToDtDepartment(SysDepartTreeModel departTree, Integer parentId) {
|
||||||
|
Department department = new Department();
|
||||||
|
department.setSource_identifier(departTree.getId());
|
||||||
|
return this.sysDepartToDtDepartment(departTree, department, parentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步部门】将SysDepartTreeModel转为【钉钉】的Department对象
|
||||||
|
*/
|
||||||
|
private Department sysDepartToDtDepartment(SysDepartTreeModel departTree, Department department, Integer parentId) {
|
||||||
|
department.setName(departTree.getDepartName());
|
||||||
|
department.setParent_id(parentId);
|
||||||
|
department.setOrder(departTree.getDepartOrder());
|
||||||
|
return department;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步部门】将【钉钉】的Department对象转为SysDepartTreeModel
|
||||||
|
*/
|
||||||
|
private SysDepart dtDepartmentToSysDepart(Department department, SysDepart departTree) {
|
||||||
|
SysDepart sysDepart = new SysDepart();
|
||||||
|
if (departTree != null) {
|
||||||
|
BeanUtils.copyProperties(departTree, sysDepart);
|
||||||
|
}
|
||||||
|
sysDepart.setDepartName(department.getName());
|
||||||
|
sysDepart.setDepartOrder(department.getOrder());
|
||||||
|
return sysDepart;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int removeThirdAppUser(List<String> userIdList) {
|
||||||
|
// 判断启用状态
|
||||||
|
if (!thirdAppConfig.isDingtalkEnabled()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
if (userIdList != null && userIdList.size() > 0) {
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysThirdAccount::getThirdType, ThirdAppConfig.DINGTALK.toLowerCase());
|
||||||
|
queryWrapper.in(SysThirdAccount::getSysUserId, userIdList);
|
||||||
|
// 根据userId,获取第三方用户的id
|
||||||
|
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.list(queryWrapper);
|
||||||
|
List<String> thirdUserIdList = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (String thirdUserId : thirdUserIdList) {
|
||||||
|
if (oConvertUtils.isNotEmpty(thirdUserId)) {
|
||||||
|
// 没有批量删除的接口
|
||||||
|
Response<JSONObject> response = JdtUserAPI.delete(thirdUserId, accessToken);
|
||||||
|
if (response.getErrcode() == 0) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendMessage(MessageDTO message) {
|
||||||
|
return this.sendMessage(message, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* @param verifyConfig
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean sendMessage(MessageDTO message, boolean verifyConfig) {
|
||||||
|
Response<String> response = this.sendMessageResponse(message, verifyConfig);
|
||||||
|
if (response != null) {
|
||||||
|
return response.isSuccess();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response<String> sendMessageResponse(MessageDTO message, boolean verifyConfig) {
|
||||||
|
if (verifyConfig && !thirdAppConfig.isDingtalkEnabled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 封装钉钉消息
|
||||||
|
String content = message.getContent();
|
||||||
|
int agentId = thirdAppConfig.getDingtalk().getAgentIdInt();
|
||||||
|
Message<TextMessage> textMessage = new Message<>(agentId, new TextMessage(content));
|
||||||
|
if (message.isToAll()) {
|
||||||
|
textMessage.setTo_all_user(true);
|
||||||
|
} else {
|
||||||
|
String[] toUsers = message.getToUser().split(",");
|
||||||
|
// 通过第三方账号表查询出第三方userId
|
||||||
|
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.listThirdUserIdByUsername(toUsers, ThirdAppConfig.DINGTALK.toLowerCase());
|
||||||
|
List<String> dtUserIds = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||||
|
textMessage.setUserid_list(dtUserIds);
|
||||||
|
}
|
||||||
|
return JdtMessageAPI.sendTextMessage(textMessage, accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean recallMessage(String msg_task_id) {
|
||||||
|
Response<JSONObject> response = this.recallMessageResponse(msg_task_id);
|
||||||
|
if (response == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return response.isSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回消息
|
||||||
|
*
|
||||||
|
* @param msg_task_id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Response<JSONObject> recallMessageResponse(String msg_task_id) {
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int agentId = thirdAppConfig.getDingtalk().getAgentIdInt();
|
||||||
|
return JdtMessageAPI.recallMessage(agentId, msg_task_id, getAccessToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送卡片消息(SysAnnouncement定制)
|
||||||
|
*
|
||||||
|
* @param announcement
|
||||||
|
* @param verifyConfig 是否验证配置(未启用的APP会拒绝发送)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Response<String> sendActionCardMessage(SysAnnouncement announcement, boolean verifyConfig) {
|
||||||
|
if (verifyConfig && !thirdAppConfig.isDingtalkEnabled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int agentId = thirdAppConfig.getDingtalk().getAgentIdInt();
|
||||||
|
String markdown = "### " + announcement.getTitile() + "\n" + oConvertUtils.getString(announcement.getMsgAbstract(),"空");
|
||||||
|
ActionCardMessage actionCard = new ActionCardMessage(markdown);
|
||||||
|
actionCard.setTitle(announcement.getTitile());
|
||||||
|
actionCard.setSingle_title("详情");
|
||||||
|
actionCard.setSingle_url(RestUtil.getBaseUrl() + "/sys/annountCement/show/" + announcement.getId());
|
||||||
|
Message<ActionCardMessage> actionCardMessage = new Message<>(agentId, actionCard);
|
||||||
|
if (CommonConstant.MSG_TYPE_ALL.equals(announcement.getMsgType())) {
|
||||||
|
actionCardMessage.setTo_all_user(true);
|
||||||
|
return JdtMessageAPI.sendActionCardMessage(actionCardMessage, accessToken);
|
||||||
|
} else {
|
||||||
|
// 将userId转为username
|
||||||
|
String[] userIds = null;
|
||||||
|
String userId = announcement.getUserIds();
|
||||||
|
if(oConvertUtils.isNotEmpty(userId)){
|
||||||
|
userIds = userId.substring(0, (userId.length() - 1)).split(",");
|
||||||
|
}else{
|
||||||
|
LambdaQueryWrapper<SysAnnouncementSend> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysAnnouncementSend::getAnntId, announcement.getId());
|
||||||
|
SysAnnouncementSend sysAnnouncementSend = sysAnnouncementSendMapper.selectOne(queryWrapper);
|
||||||
|
userIds = new String[] {sysAnnouncementSend.getUserId()};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(userIds!=null){
|
||||||
|
String[] usernameList = sysUserService.userIdToUsername(Arrays.asList(userIds)).toArray(new String[]{});
|
||||||
|
// 通过第三方账号表查询出第三方userId
|
||||||
|
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.listThirdUserIdByUsername(usernameList, ThirdAppConfig.DINGTALK.toLowerCase());
|
||||||
|
List<String> dtUserIds = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||||
|
actionCardMessage.setUserid_list(dtUserIds);
|
||||||
|
return JdtMessageAPI.sendActionCardMessage(actionCardMessage, accessToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,791 @@
|
||||||
|
package org.jeecg.modules.system.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.jeecg.qywx.api.base.JwAccessTokenAPI;
|
||||||
|
import com.jeecg.qywx.api.core.common.AccessToken;
|
||||||
|
import com.jeecg.qywx.api.department.JwDepartmentAPI;
|
||||||
|
import com.jeecg.qywx.api.department.vo.DepartMsgResponse;
|
||||||
|
import com.jeecg.qywx.api.department.vo.Department;
|
||||||
|
import com.jeecg.qywx.api.message.JwMessageAPI;
|
||||||
|
import com.jeecg.qywx.api.message.vo.Text;
|
||||||
|
import com.jeecg.qywx.api.message.vo.TextCard;
|
||||||
|
import com.jeecg.qywx.api.message.vo.TextCardEntity;
|
||||||
|
import com.jeecg.qywx.api.message.vo.TextEntity;
|
||||||
|
import com.jeecg.qywx.api.user.JwUserAPI;
|
||||||
|
import com.jeecg.qywx.api.user.vo.User;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
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.thirdapp.ThirdAppConfig;
|
||||||
|
import org.jeecg.modules.system.entity.*;
|
||||||
|
import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
|
||||||
|
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||||
|
import org.jeecg.modules.system.service.*;
|
||||||
|
import org.jeecg.modules.system.vo.thirdapp.JwDepartmentTreeVo;
|
||||||
|
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方App对接:企业微信实现类
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ThirdAppConfig thirdAppConfig;
|
||||||
|
@Autowired
|
||||||
|
private ISysDepartService sysDepartService;
|
||||||
|
@Autowired
|
||||||
|
private ISysUserService sysUserService;
|
||||||
|
@Autowired
|
||||||
|
private ISysThirdAccountService sysThirdAccountService;
|
||||||
|
@Autowired
|
||||||
|
private ISysUserDepartService sysUserDepartService;
|
||||||
|
@Autowired
|
||||||
|
private ISysPositionService sysPositionService;
|
||||||
|
@Autowired
|
||||||
|
private SysAnnouncementSendMapper sysAnnouncementSendMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccessToken() {
|
||||||
|
String CORP_ID = thirdAppConfig.getWechatEnterprise().getClientId();
|
||||||
|
String SECRET = thirdAppConfig.getWechatEnterprise().getClientSecret();
|
||||||
|
AccessToken accessToken = JwAccessTokenAPI.getAccessToken(CORP_ID, SECRET);
|
||||||
|
if (accessToken != null) {
|
||||||
|
return accessToken.getAccesstoken();
|
||||||
|
}
|
||||||
|
log.warn("获取AccessToken失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取APPToken,新版企业微信的秘钥是分开的 */
|
||||||
|
public String getAppAccessToken() {
|
||||||
|
String CORP_ID = thirdAppConfig.getWechatEnterprise().getClientId();
|
||||||
|
String SECRET = thirdAppConfig.getWechatEnterprise().getAgentAppSecret();
|
||||||
|
// 如果没有配置APP秘钥,就说明是老企业,可以通用秘钥
|
||||||
|
if (oConvertUtils.isEmpty(SECRET)) {
|
||||||
|
SECRET = thirdAppConfig.getWechatEnterprise().getClientSecret();
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessToken accessToken = JwAccessTokenAPI.getAccessToken(CORP_ID, SECRET);
|
||||||
|
if (accessToken != null) {
|
||||||
|
return accessToken.getAccesstoken();
|
||||||
|
}
|
||||||
|
log.warn("获取AccessToken失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean syncLocalDepartmentToThirdApp(String ids) {
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 获取企业微信所有的部门
|
||||||
|
List<Department> departments = JwDepartmentAPI.getAllDepartment(accessToken);
|
||||||
|
if (departments == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 删除企业微信有但本地没有的部门(以本地部门数据为主)(以为企业微信不能创建同名部门,所以只能先删除)
|
||||||
|
List<JwDepartmentTreeVo> departmentTreeList = JwDepartmentTreeVo.listToTree(departments);
|
||||||
|
this.deleteDepartRecursion(departmentTreeList, accessToken, true);
|
||||||
|
// 获取本地所有部门树结构
|
||||||
|
List<SysDepartTreeModel> sysDepartsTree = sysDepartService.queryTreeList();
|
||||||
|
// -- 企业微信不能创建新的顶级部门,所以新的顶级部门的parentId就为1
|
||||||
|
Department parent = new Department();
|
||||||
|
parent.setId("1");
|
||||||
|
// 递归同步部门
|
||||||
|
departments = JwDepartmentAPI.getAllDepartment(accessToken);
|
||||||
|
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归删除部门以及子部门,由于企业微信不允许删除带有成员和子部门的部门,所以需要递归删除下子部门,然后把部门成员移动端根部门下
|
||||||
|
private void deleteDepartRecursion(List<JwDepartmentTreeVo> children, String accessToken, boolean ifLocal) {
|
||||||
|
for (JwDepartmentTreeVo departmentTree : children) {
|
||||||
|
String depId = departmentTree.getId();
|
||||||
|
// 过滤根部门
|
||||||
|
if (!"1".equals(depId)) {
|
||||||
|
// 判断本地是否有该部门
|
||||||
|
if (ifLocal) {
|
||||||
|
LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysDepart::getQywxIdentifier, depId);
|
||||||
|
SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
|
||||||
|
// 本地有该部门,不删除
|
||||||
|
if (sysDepart != null) {
|
||||||
|
if (departmentTree.hasChildren()) {
|
||||||
|
this.deleteDepartRecursion(departmentTree.getChildren(), accessToken, true);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 判断是否有成员,有就移动到根部门
|
||||||
|
List<User> departUserList = JwUserAPI.getUsersByDepartid(depId, "1", null, accessToken);
|
||||||
|
if (departUserList != null && departUserList.size() > 0) {
|
||||||
|
for (User user : departUserList) {
|
||||||
|
User updateUser = new User();
|
||||||
|
updateUser.setUserid(user.getUserid());
|
||||||
|
updateUser.setDepartment(new Integer[]{1});
|
||||||
|
JwUserAPI.updateUser(updateUser, accessToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 有子部门优先删除子部门
|
||||||
|
if (departmentTree.hasChildren()) {
|
||||||
|
this.deleteDepartRecursion(departmentTree.getChildren(), accessToken, false);
|
||||||
|
}
|
||||||
|
// 执行删除操作
|
||||||
|
JwDepartmentAPI.deleteDepart(depId, accessToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归同步部门到第三方APP
|
||||||
|
private void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Department> departments, Department parent, String accessToken) {
|
||||||
|
if (sysDepartsTree != null && sysDepartsTree.size() != 0) {
|
||||||
|
for1:
|
||||||
|
for (SysDepartTreeModel depart : sysDepartsTree) {
|
||||||
|
for (Department department : departments) {
|
||||||
|
// id相同,代表已存在,执行修改操作
|
||||||
|
if (department.getId().equals(depart.getQywxIdentifier())) {
|
||||||
|
this.sysDepartToQwDepartment(depart, department, parent.getId());
|
||||||
|
JwDepartmentAPI.updateDepart(department, accessToken);
|
||||||
|
// 紧接着同步子级
|
||||||
|
this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken);
|
||||||
|
// 跳出外部循环
|
||||||
|
continue for1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 循环到此说明是新部门,直接调接口创建
|
||||||
|
Department newDepartment = this.sysDepartToQwDepartment(depart, parent.getId());
|
||||||
|
DepartMsgResponse response = JwDepartmentAPI.createDepartment(newDepartment, accessToken);
|
||||||
|
// 创建成功,将返回的id绑定到本地
|
||||||
|
if (response != null && response.getId() != null) {
|
||||||
|
SysDepart sysDepart = new SysDepart();
|
||||||
|
sysDepart.setId(depart.getId());
|
||||||
|
sysDepart.setQywxIdentifier(response.getId().toString());
|
||||||
|
sysDepartService.updateById(sysDepart);
|
||||||
|
Department newParent = new Department();
|
||||||
|
newParent.setId(response.getId().toString());
|
||||||
|
// 紧接着同步子级
|
||||||
|
this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken);
|
||||||
|
}
|
||||||
|
// 收集错误信息
|
||||||
|
// this.syncUserCollectErrInfo(errCode, sysUser, errInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归同步部门到本地
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SyncInfoVo syncLocalUserToThirdApp(String ids) {
|
||||||
|
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
syncInfo.addFailInfo("accessToken获取失败!");
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
// 获取企业微信所有的用户
|
||||||
|
List<User> qwUsers = JwUserAPI.getDetailUsersByDepartid("1", null, null, accessToken);
|
||||||
|
if (qwUsers == null) {
|
||||||
|
syncInfo.addFailInfo("企业微信用户列表查询失败!");
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
List<SysUser> sysUsers;
|
||||||
|
if (StringUtils.isNotBlank(ids)) {
|
||||||
|
String[] idList = ids.split(",");
|
||||||
|
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.in(SysUser::getId, (Object[]) idList);
|
||||||
|
// 获取本地指定用户
|
||||||
|
sysUsers = sysUserService.list(queryWrapper);
|
||||||
|
} else {
|
||||||
|
// 获取本地所有用户
|
||||||
|
sysUsers = sysUserService.list();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 循环判断新用户和需要更新的用户
|
||||||
|
for1:
|
||||||
|
for (SysUser sysUser : sysUsers) {
|
||||||
|
// 外部模拟登陆临时账号,不同步
|
||||||
|
if ("_reserve_user_external".equals(sysUser.getUsername())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* 判断是否同步过的逻辑:
|
||||||
|
* 1. 查询 sys_third_account(第三方账号表)是否有数据,如果有代表已同步
|
||||||
|
* 2. 本地表里没有,就先用手机号判断,不通过再用username判断。
|
||||||
|
*/
|
||||||
|
User qwUser;
|
||||||
|
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneBySysUserId(sysUser.getId(), ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||||
|
for (User qwUserTemp : qwUsers) {
|
||||||
|
if (sysThirdAccount == null || oConvertUtils.isEmpty(sysThirdAccount.getThirdUserId()) || !sysThirdAccount.getThirdUserId().equals(qwUserTemp.getUserid())) {
|
||||||
|
// sys_third_account 表匹配失败,尝试用手机号匹配
|
||||||
|
String phone = sysUser.getPhone();
|
||||||
|
if (!(oConvertUtils.isEmpty(phone) || phone.equals(qwUserTemp.getMobile()))) {
|
||||||
|
// 手机号匹配失败,再尝试用username匹配
|
||||||
|
String username = sysUser.getUsername();
|
||||||
|
if (!(oConvertUtils.isEmpty(username) || username.equals(qwUserTemp.getUserid()))) {
|
||||||
|
// username 匹配失败,直接跳到下一次循环继续
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 循环到此说明用户匹配成功,进行更新操作
|
||||||
|
qwUser = this.sysUserToQwUser(sysUser, qwUserTemp);
|
||||||
|
int errCode = JwUserAPI.updateUser(qwUser, accessToken);
|
||||||
|
// 收集错误信息
|
||||||
|
this.syncUserCollectErrInfo(errCode, sysUser, syncInfo);
|
||||||
|
this.thirdAccountSaveOrUpdate(sysThirdAccount, sysUser.getId(), qwUser.getUserid());
|
||||||
|
// 更新完成,直接跳到下一次外部循环继续
|
||||||
|
continue for1;
|
||||||
|
}
|
||||||
|
// 循环到此说明是新用户,直接调接口创建
|
||||||
|
qwUser = this.sysUserToQwUser(sysUser);
|
||||||
|
int errCode = JwUserAPI.createUser(qwUser, accessToken);
|
||||||
|
// 收集错误信息
|
||||||
|
boolean apiSuccess = this.syncUserCollectErrInfo(errCode, sysUser, syncInfo);
|
||||||
|
if (apiSuccess) {
|
||||||
|
this.thirdAccountSaveOrUpdate(sysThirdAccount, sysUser.getId(), qwUser.getUserid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SyncInfoVo syncThirdAppUserToLocal() {
|
||||||
|
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
syncInfo.addFailInfo("accessToken获取失败!");
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
// 获取企业微信所有的用户
|
||||||
|
List<User> qwUsersList = JwUserAPI.getDetailUsersByDepartid("1", null, null, accessToken);
|
||||||
|
if (qwUsersList == null) {
|
||||||
|
syncInfo.addFailInfo("企业微信用户列表查询失败!");
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
//查询本地用户
|
||||||
|
List<SysUser> sysUsersList = sysUserService.list();
|
||||||
|
// 循环判断新用户和需要更新的用户
|
||||||
|
for (User qwUser : qwUsersList) {
|
||||||
|
/*
|
||||||
|
* 判断是否同步过的逻辑:
|
||||||
|
* 1. 查询 sys_third_account(第三方账号表)是否有数据,如果有代表已同步
|
||||||
|
* 2. 本地表里没有,就先用手机号判断,不通过再用username判断。
|
||||||
|
*/
|
||||||
|
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneByThirdUserId(qwUser.getUserid(), ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||||
|
List<SysUser> collect = sysUsersList.stream().filter(user -> (qwUser.getMobile().equals(user.getPhone()) || qwUser.getUserid().equals(user.getUsername()))
|
||||||
|
).collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (collect != null && collect.size() > 0) {
|
||||||
|
SysUser sysUserTemp = collect.get(0);
|
||||||
|
// 循环到此说明用户匹配成功,进行更新操作
|
||||||
|
SysUser updateSysUser = this.qwUserToSysUser(qwUser, sysUserTemp);
|
||||||
|
try {
|
||||||
|
sysUserService.updateById(updateSysUser);
|
||||||
|
String str = String.format("用户 %s(%s) 更新成功!", updateSysUser.getRealname(), updateSysUser.getUsername());
|
||||||
|
syncInfo.addSuccessInfo(str);
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.syncUserCollectErrInfo(e, qwUser, syncInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.thirdAccountSaveOrUpdate(sysThirdAccount, updateSysUser.getId(), qwUser.getUserid());
|
||||||
|
// 更新完成,直接跳到下一次外部循环继续
|
||||||
|
}else{
|
||||||
|
// 没匹配到用户则走新增逻辑
|
||||||
|
SysUser newSysUser = this.qwUserToSysUser(qwUser);
|
||||||
|
try {
|
||||||
|
sysUserService.save(newSysUser);
|
||||||
|
String str = String.format("用户 %s(%s) 创建成功!", newSysUser.getRealname(), newSysUser.getUsername());
|
||||||
|
syncInfo.addSuccessInfo(str);
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.syncUserCollectErrInfo(e, qwUser, syncInfo);
|
||||||
|
}
|
||||||
|
this.thirdAccountSaveOrUpdate(sysThirdAccount, newSysUser.getId(), qwUser.getUserid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return syncInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存或修改第三方登录表
|
||||||
|
*
|
||||||
|
* @param sysThirdAccount 第三方账户表对象,为null就新增数据,否则就修改
|
||||||
|
* @param sysUserId 本地系统用户ID
|
||||||
|
* @param qwUserId 企业微信用户ID
|
||||||
|
*/
|
||||||
|
private void thirdAccountSaveOrUpdate(SysThirdAccount sysThirdAccount, String sysUserId, String qwUserId) {
|
||||||
|
if (sysThirdAccount == null) {
|
||||||
|
sysThirdAccount = new SysThirdAccount();
|
||||||
|
sysThirdAccount.setSysUserId(sysUserId);
|
||||||
|
sysThirdAccount.setStatus(1);
|
||||||
|
sysThirdAccount.setDelFlag(0);
|
||||||
|
sysThirdAccount.setThirdType(ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||||
|
}
|
||||||
|
sysThirdAccount.setThirdUserId(qwUserId);
|
||||||
|
sysThirdAccountService.saveOrUpdate(sysThirdAccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】收集同步过程中的错误信息
|
||||||
|
*/
|
||||||
|
private boolean syncUserCollectErrInfo(int errCode, SysUser sysUser, SyncInfoVo syncInfo) {
|
||||||
|
if (errCode != 0) {
|
||||||
|
String msg = "";
|
||||||
|
// https://open.work.weixin.qq.com/api/doc/90000/90139/90313
|
||||||
|
switch (errCode) {
|
||||||
|
case 40003:
|
||||||
|
msg = "无效的UserID";
|
||||||
|
break;
|
||||||
|
case 60129:
|
||||||
|
msg = "手机和邮箱不能都为空";
|
||||||
|
break;
|
||||||
|
case 60102:
|
||||||
|
msg = "UserID已存在";
|
||||||
|
break;
|
||||||
|
case 60103:
|
||||||
|
msg = "手机号码不合法";
|
||||||
|
break;
|
||||||
|
case 60104:
|
||||||
|
msg = "手机号码已存在";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String str = String.format("用户 %s(%s) 同步失败!错误码:%s——%s", sysUser.getUsername(), sysUser.getRealname(), errCode, msg);
|
||||||
|
syncInfo.addFailInfo(str);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
String str = String.format("用户 %s(%s) 同步成功!", sysUser.getUsername(), sysUser.getRealname());
|
||||||
|
syncInfo.addSuccessInfo(str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean syncUserCollectErrInfo(Exception e, User qwUser, SyncInfoVo syncInfo) {
|
||||||
|
String msg;
|
||||||
|
if (e instanceof DuplicateKeyException) {
|
||||||
|
msg = e.getCause().getMessage();
|
||||||
|
} else {
|
||||||
|
msg = e.getMessage();
|
||||||
|
}
|
||||||
|
String str = String.format("用户 %s(%s) 同步失败!错误信息:%s", qwUser.getUserid(), qwUser.getName(), msg);
|
||||||
|
syncInfo.addFailInfo(str);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean syncDepartCollectErrInfo(Exception e, Department department, SyncInfoVo syncInfo) {
|
||||||
|
String msg;
|
||||||
|
if (e instanceof DuplicateKeyException) {
|
||||||
|
msg = e.getCause().getMessage();
|
||||||
|
} else {
|
||||||
|
msg = e.getMessage();
|
||||||
|
}
|
||||||
|
String str = String.format("部门 %s(%s) 同步失败!错误信息:%s", department.getName(), department.getId(), msg);
|
||||||
|
syncInfo.addFailInfo(str);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】将SysUser转为企业微信的User对象(创建新用户)
|
||||||
|
*/
|
||||||
|
private User sysUserToQwUser(SysUser sysUser) {
|
||||||
|
User user = new User();
|
||||||
|
// 通过 username 来关联
|
||||||
|
user.setUserid(sysUser.getUsername());
|
||||||
|
return this.sysUserToQwUser(sysUser, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】将SysUser转为企业微信的User对象(更新旧用户)
|
||||||
|
*/
|
||||||
|
private User sysUserToQwUser(SysUser sysUser, User user) {
|
||||||
|
user.setName(sysUser.getRealname());
|
||||||
|
user.setMobile(sysUser.getPhone());
|
||||||
|
// 查询并同步用户部门关系
|
||||||
|
List<SysDepart> departList = this.getUserDepart(sysUser);
|
||||||
|
if (departList != null) {
|
||||||
|
List<Integer> departmentIdList = new ArrayList<>();
|
||||||
|
// 企业微信 1表示为上级,0表示非上级
|
||||||
|
List<Integer> isLeaderInDept = new ArrayList<>();
|
||||||
|
// 当前用户管理的部门
|
||||||
|
List<String> manageDepartIdList = new ArrayList<>();
|
||||||
|
if (oConvertUtils.isNotEmpty(sysUser.getDepartIds())) {
|
||||||
|
manageDepartIdList = Arrays.asList(sysUser.getDepartIds().split(","));
|
||||||
|
}
|
||||||
|
for (SysDepart sysDepart : departList) {
|
||||||
|
// 企业微信的部门id
|
||||||
|
if (oConvertUtils.isNotEmpty(sysDepart.getQywxIdentifier())) {
|
||||||
|
try {
|
||||||
|
departmentIdList.add(Integer.parseInt(sysDepart.getQywxIdentifier()));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 判断用户身份,是否为上级
|
||||||
|
if (CommonConstant.USER_IDENTITY_2.equals(sysUser.getUserIdentity())) {
|
||||||
|
// 判断当前部门是否为该用户管理的部门
|
||||||
|
isLeaderInDept.add(manageDepartIdList.contains(sysDepart.getId()) ? 1 : 0);
|
||||||
|
} else {
|
||||||
|
isLeaderInDept.add(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user.setDepartment(departmentIdList.toArray(new Integer[]{}));
|
||||||
|
// 个数必须和参数department的个数一致,表示在所在的部门内是否为上级。1表示为上级,0表示非上级。在审批等应用里可以用来标识上级审批人
|
||||||
|
user.setIs_leader_in_dept(isLeaderInDept.toArray(new Integer[]{}));
|
||||||
|
}
|
||||||
|
if (user.getDepartment() == null || user.getDepartment().length == 0) {
|
||||||
|
// 没有找到匹配部门,同步到根部门下
|
||||||
|
user.setDepartment(new Integer[]{1});
|
||||||
|
user.setIs_leader_in_dept(new Integer[]{0});
|
||||||
|
}
|
||||||
|
// 职务翻译
|
||||||
|
if (oConvertUtils.isNotEmpty(sysUser.getPost())) {
|
||||||
|
SysPosition position = sysPositionService.getByCode(sysUser.getPost());
|
||||||
|
if (position != null) {
|
||||||
|
user.setPosition(position.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sysUser.getSex() != null) {
|
||||||
|
user.setGender(sysUser.getSex().toString());
|
||||||
|
}
|
||||||
|
user.setEmail(sysUser.getEmail());
|
||||||
|
// 启用/禁用成员(状态),规则不同,需要转换
|
||||||
|
// 企业微信规则:1表示启用成员,0表示禁用成员
|
||||||
|
// JEECG规则:1正常,2冻结
|
||||||
|
if (sysUser.getStatus() != null) {
|
||||||
|
if (sysUser.getStatus() == 1 || sysUser.getStatus() == 2) {
|
||||||
|
user.setEnable(sysUser.getStatus() == 1 ? 1 : 0);
|
||||||
|
} else {
|
||||||
|
user.setEnable(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user.setTelephone(sysUser.getTelephone());// 座机号
|
||||||
|
// --- 企业微信没有逻辑删除的功能
|
||||||
|
// update-begin--Author:sunjianlei Date:20210520 for:本地逻辑删除的用户,在企业微信里禁用 -----
|
||||||
|
if (CommonConstant.DEL_FLAG_1.equals(sysUser.getDelFlag())) {
|
||||||
|
user.setEnable(0);
|
||||||
|
}
|
||||||
|
// update-end--Author:sunjianlei Date:20210520 for:本地逻辑删除的用户,在企业微信里冻结 -----
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户和部门的关系
|
||||||
|
*/
|
||||||
|
private List<SysDepart> getUserDepart(SysUser sysUser) {
|
||||||
|
// 根据用户部门关系表查询出用户的部门
|
||||||
|
LambdaQueryWrapper<SysUserDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysUserDepart::getUserId, sysUser.getId());
|
||||||
|
List<SysUserDepart> sysUserDepartList = sysUserDepartService.list(queryWrapper);
|
||||||
|
if (sysUserDepartList.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 根据用户部门
|
||||||
|
LambdaQueryWrapper<SysDepart> departQueryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
List<String> departIdList = sysUserDepartList.stream().map(SysUserDepart::getDepId).collect(Collectors.toList());
|
||||||
|
departQueryWrapper.in(SysDepart::getId, departIdList);
|
||||||
|
List<SysDepart> departList = sysDepartService.list(departQueryWrapper);
|
||||||
|
return departList.size() == 0 ? null : departList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】将企业微信的User对象转为SysUser(创建新用户)
|
||||||
|
*/
|
||||||
|
private SysUser qwUserToSysUser(User user) {
|
||||||
|
SysUser sysUser = new SysUser();
|
||||||
|
sysUser.setDelFlag(0);
|
||||||
|
// 通过 username 来关联
|
||||||
|
sysUser.setUsername(user.getUserid());
|
||||||
|
// 密码默认为 “123456”,随机加盐
|
||||||
|
String password = "123456", salt = oConvertUtils.randomGen(8);
|
||||||
|
String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
|
||||||
|
sysUser.setSalt(salt);
|
||||||
|
sysUser.setPassword(passwordEncode);
|
||||||
|
return this.qwUserToSysUser(user, sysUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步用户】将企业微信的User对象转为SysUser(更新旧用户)
|
||||||
|
*/
|
||||||
|
private SysUser qwUserToSysUser(User qwUser, SysUser oldSysUser) {
|
||||||
|
SysUser sysUser = new SysUser();
|
||||||
|
BeanUtils.copyProperties(oldSysUser, sysUser);
|
||||||
|
sysUser.setRealname(qwUser.getName());
|
||||||
|
sysUser.setPost(qwUser.getPosition());
|
||||||
|
try {
|
||||||
|
sysUser.setSex(Integer.parseInt(qwUser.getGender()));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
|
// 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
|
||||||
|
if (oConvertUtils.isNotEmpty(qwUser.getEmail()) && !qwUser.getEmail().equals(sysUser.getEmail())) {
|
||||||
|
sysUser.setEmail(qwUser.getEmail());
|
||||||
|
} else {
|
||||||
|
sysUser.setEmail(null);
|
||||||
|
}
|
||||||
|
// 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
|
||||||
|
if (oConvertUtils.isNotEmpty(qwUser.getMobile()) && !qwUser.getMobile().equals(sysUser.getPhone())) {
|
||||||
|
sysUser.setPhone(qwUser.getMobile());
|
||||||
|
} else {
|
||||||
|
sysUser.setPhone(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启用/禁用成员(状态),规则不同,需要转换
|
||||||
|
// 企业微信规则:1表示启用成员,0表示禁用成员
|
||||||
|
// JEECG规则:1正常,2冻结
|
||||||
|
if (qwUser.getEnable() != null) {
|
||||||
|
sysUser.setStatus(qwUser.getEnable() == 1 ? 1 : 2);
|
||||||
|
}
|
||||||
|
sysUser.setTelephone(qwUser.getTelephone());// 座机号
|
||||||
|
|
||||||
|
// --- 企业微信没有逻辑删除的功能
|
||||||
|
// sysUser.setDelFlag()
|
||||||
|
return sysUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步部门】将SysDepartTreeModel转为企业微信的Department对象(创建新部门)
|
||||||
|
*/
|
||||||
|
private Department sysDepartToQwDepartment(SysDepartTreeModel departTree, String parentId) {
|
||||||
|
Department department = new Department();
|
||||||
|
return this.sysDepartToQwDepartment(departTree, department, parentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步部门】将SysDepartTreeModel转为企业微信的Department对象
|
||||||
|
*/
|
||||||
|
private Department sysDepartToQwDepartment(SysDepartTreeModel departTree, Department department, String parentId) {
|
||||||
|
department.setName(departTree.getDepartName());
|
||||||
|
department.setParentid(parentId);
|
||||||
|
if (departTree.getDepartOrder() != null) {
|
||||||
|
department.setOrder(departTree.getDepartOrder().toString());
|
||||||
|
}
|
||||||
|
return department;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【同步部门】将企业微信的Department对象转为SysDepart
|
||||||
|
*/
|
||||||
|
private SysDepart qwDepartmentToSysDepart(Department department, SysDepart oldSysDepart) {
|
||||||
|
SysDepart sysDepart = new SysDepart();
|
||||||
|
if (oldSysDepart != null) {
|
||||||
|
BeanUtils.copyProperties(oldSysDepart, sysDepart);
|
||||||
|
}
|
||||||
|
sysDepart.setQywxIdentifier(department.getId());
|
||||||
|
sysDepart.setDepartName(department.getName());
|
||||||
|
try {
|
||||||
|
sysDepart.setDepartOrder(Integer.parseInt(department.getOrder()));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
|
return sysDepart;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int removeThirdAppUser(List<String> userIdList) {
|
||||||
|
// 判断启用状态
|
||||||
|
if (!thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
if (userIdList != null && userIdList.size() > 0) {
|
||||||
|
String accessToken = this.getAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysThirdAccount::getThirdType, ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||||
|
queryWrapper.in(SysThirdAccount::getSysUserId, userIdList);
|
||||||
|
// 根据userId,获取第三方用户的id
|
||||||
|
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.list(queryWrapper);
|
||||||
|
List<String> thirdUserIdList = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (String thirdUserId : thirdUserIdList) {
|
||||||
|
if (oConvertUtils.isNotEmpty(thirdUserId)) {
|
||||||
|
// 没有批量删除的接口
|
||||||
|
int err = JwUserAPI.deleteUser(thirdUserId, accessToken);
|
||||||
|
if (err == 0) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendMessage(MessageDTO message) {
|
||||||
|
return this.sendMessage(message, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendMessage(MessageDTO message, boolean verifyConfig) {
|
||||||
|
JSONObject response = this.sendMessageResponse(message, verifyConfig);
|
||||||
|
if (response != null) {
|
||||||
|
return response.getIntValue("errcode") == 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject sendMessageResponse(MessageDTO message, boolean verifyConfig) {
|
||||||
|
if (verifyConfig && !thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String accessToken = this.getAppAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Text text = new Text();
|
||||||
|
text.setMsgtype("text");
|
||||||
|
text.setTouser(this.getTouser(message.getToUser(), message.isToAll()));
|
||||||
|
TextEntity entity = new TextEntity();
|
||||||
|
entity.setContent(message.getContent());
|
||||||
|
text.setText(entity);
|
||||||
|
text.setAgentid(thirdAppConfig.getWechatEnterprise().getAgentIdInt());
|
||||||
|
return JwMessageAPI.sendTextMessage(text, accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送文本卡片消息(SysAnnouncement定制)
|
||||||
|
*
|
||||||
|
* @param announcement
|
||||||
|
* @param verifyConfig 是否验证配置(未启用的APP会拒绝发送)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public JSONObject sendTextCardMessage(SysAnnouncement announcement, boolean verifyConfig) {
|
||||||
|
if (verifyConfig && !thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String accessToken = this.getAppAccessToken();
|
||||||
|
if (accessToken == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
TextCard textCard = new TextCard();
|
||||||
|
textCard.setAgentid(thirdAppConfig.getWechatEnterprise().getAgentIdInt());
|
||||||
|
boolean isToAll = CommonConstant.MSG_TYPE_ALL.equals(announcement.getMsgType());
|
||||||
|
String usernameString = "";
|
||||||
|
if (!isToAll) {
|
||||||
|
// 将userId转为username
|
||||||
|
String userId = announcement.getUserIds();
|
||||||
|
String[] userIds = null;
|
||||||
|
if(oConvertUtils.isNotEmpty(userId)){
|
||||||
|
userIds = userId.substring(0, (userId.length() - 1)).split(",");
|
||||||
|
}else{
|
||||||
|
LambdaQueryWrapper<SysAnnouncementSend> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysAnnouncementSend::getAnntId, announcement.getId());
|
||||||
|
SysAnnouncementSend sysAnnouncementSend = sysAnnouncementSendMapper.selectOne(queryWrapper);
|
||||||
|
userIds = new String[] {sysAnnouncementSend.getUserId()};
|
||||||
|
}
|
||||||
|
List<String> usernameList = sysUserService.userIdToUsername(Arrays.asList(userIds));
|
||||||
|
usernameString = String.join(",", usernameList);
|
||||||
|
}
|
||||||
|
|
||||||
|
textCard.setTouser(this.getTouser(usernameString, isToAll));
|
||||||
|
TextCardEntity entity = new TextCardEntity();
|
||||||
|
entity.setTitle(announcement.getTitile());
|
||||||
|
entity.setDescription(oConvertUtils.getString(announcement.getMsgAbstract(),"空"));
|
||||||
|
entity.setUrl(RestUtil.getBaseUrl() + "/sys/annountCement/show/" + announcement.getId());
|
||||||
|
textCard.setTextcard(entity);
|
||||||
|
return JwMessageAPI.sendTextCardMessage(textCard, accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTouser(String origin, boolean toAll) {
|
||||||
|
if (toAll) {
|
||||||
|
return "@all";
|
||||||
|
} else {
|
||||||
|
String[] toUsers = origin.split(",");
|
||||||
|
// 通过第三方账号表查询出第三方userId
|
||||||
|
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.listThirdUserIdByUsername(toUsers, ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||||
|
List<String> toUserList = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||||
|
// 多个接收者用‘|’分隔
|
||||||
|
return String.join("|", toUserList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.jeecg.modules.system.service.impl.desform;
|
||||||
|
|
||||||
|
import org.jeecg.common.api.desform.ISysTranslateAPI;
|
||||||
|
import org.jeecg.common.system.vo.DictModel;
|
||||||
|
import org.jeecg.modules.system.service.ISysCategoryService;
|
||||||
|
import org.jeecg.modules.system.service.ISysDictService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单设计器翻译API接口(system实现类)
|
||||||
|
*
|
||||||
|
* @author sunjianlei
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SysTranslateAPIImpl implements ISysTranslateAPI {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ISysCategoryService sysCategoryService;
|
||||||
|
@Autowired
|
||||||
|
ISysDictService sysDictService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> categoryLoadDictItem(String ids) {
|
||||||
|
return sysCategoryService.loadDictItem(ids, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> dictLoadDictItem(String dictCode, String keys) {
|
||||||
|
String[] params = dictCode.split(",");
|
||||||
|
return sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DictModel> dictGetDictItems(String dictCode) {
|
||||||
|
List<DictModel> ls = sysDictService.getDictItems(dictCode);
|
||||||
|
if (ls == null) {
|
||||||
|
ls = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DictModel> dictLoadDict(String dictCode, String keyword, Integer pageSize) {
|
||||||
|
return sysDictService.loadDict(dictCode, keyword, pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,25 +1,25 @@
|
||||||
package org.jeecg.modules.system.util;
|
//package org.jeecg.modules.system.util;
|
||||||
|
//
|
||||||
import lombok.extern.slf4j.Slf4j;
|
//import lombok.extern.slf4j.Slf4j;
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
* 多租户 tenant_id存储器
|
// * 多租户 tenant_id存储器
|
||||||
*/
|
// */
|
||||||
@Slf4j
|
//@Slf4j
|
||||||
public class TenantContext {
|
//public class TenantContext {
|
||||||
|
//
|
||||||
private static ThreadLocal<String> currentTenant = new ThreadLocal<>();
|
// private static ThreadLocal<String> currentTenant = new ThreadLocal<>();
|
||||||
|
//
|
||||||
public static void setTenant(String tenant) {
|
// public static void setTenant(String tenant) {
|
||||||
log.debug(" setting tenant to " + tenant);
|
// log.debug(" setting tenant to " + tenant);
|
||||||
currentTenant.set(tenant);
|
// currentTenant.set(tenant);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public static String getTenant() {
|
// public static String getTenant() {
|
||||||
return currentTenant.get();
|
// return currentTenant.get();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public static void clear(){
|
// public static void clear(){
|
||||||
currentTenant.remove();
|
// currentTenant.remove();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package org.jeecg.modules.system.vo.thirdapp;
|
||||||
|
|
||||||
|
import com.jeecg.dingtalk.api.department.vo.Department;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 钉钉树结构的部门
|
||||||
|
*
|
||||||
|
* @author sunjianlei
|
||||||
|
*/
|
||||||
|
public class JdtDepartmentTreeVo extends Department {
|
||||||
|
|
||||||
|
private List<JdtDepartmentTreeVo> children;
|
||||||
|
|
||||||
|
public List<JdtDepartmentTreeVo> getChildren() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JdtDepartmentTreeVo setChildren(List<JdtDepartmentTreeVo> children) {
|
||||||
|
this.children = children;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JdtDepartmentTreeVo(Department department) {
|
||||||
|
BeanUtils.copyProperties(department, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否有子项
|
||||||
|
*/
|
||||||
|
public boolean hasChildren() {
|
||||||
|
return children != null && children.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "JwDepartmentTree{" +
|
||||||
|
"children=" + children +
|
||||||
|
"} " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 静态辅助方法,将list转为tree结构
|
||||||
|
*/
|
||||||
|
public static List<JdtDepartmentTreeVo> listToTree(List<Department> allDepartment) {
|
||||||
|
// 先找出所有的父级
|
||||||
|
List<JdtDepartmentTreeVo> treeList = getByParentId(1, allDepartment);
|
||||||
|
getChildrenRecursion(treeList, allDepartment);
|
||||||
|
return treeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<JdtDepartmentTreeVo> getByParentId(Integer parentId, List<Department> allDepartment) {
|
||||||
|
List<JdtDepartmentTreeVo> list = new ArrayList<>();
|
||||||
|
for (Department department : allDepartment) {
|
||||||
|
if (parentId.equals(department.getParent_id())) {
|
||||||
|
list.add(new JdtDepartmentTreeVo(department));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getChildrenRecursion(List<JdtDepartmentTreeVo> treeList, List<Department> allDepartment) {
|
||||||
|
for (JdtDepartmentTreeVo departmentTree : treeList) {
|
||||||
|
// 递归寻找子级
|
||||||
|
List<JdtDepartmentTreeVo> children = getByParentId(departmentTree.getDept_id(), allDepartment);
|
||||||
|
if (children.size() > 0) {
|
||||||
|
departmentTree.setChildren(children);
|
||||||
|
getChildrenRecursion(children, allDepartment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package org.jeecg.modules.system.vo.thirdapp;
|
||||||
|
|
||||||
|
import com.jeecg.qywx.api.department.vo.Department;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业微信树结构的部门
|
||||||
|
*
|
||||||
|
* @author sunjianlei
|
||||||
|
*/
|
||||||
|
public class JwDepartmentTreeVo extends Department {
|
||||||
|
|
||||||
|
private List<JwDepartmentTreeVo> children;
|
||||||
|
|
||||||
|
public List<JwDepartmentTreeVo> getChildren() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JwDepartmentTreeVo setChildren(List<JwDepartmentTreeVo> children) {
|
||||||
|
this.children = children;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JwDepartmentTreeVo(Department department) {
|
||||||
|
BeanUtils.copyProperties(department, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否有子项
|
||||||
|
*/
|
||||||
|
public boolean hasChildren() {
|
||||||
|
return children != null && children.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "JwDepartmentTree{" +
|
||||||
|
"children=" + children +
|
||||||
|
"} " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 静态辅助方法,将list转为tree结构
|
||||||
|
*/
|
||||||
|
public static List<JwDepartmentTreeVo> listToTree(List<Department> allDepartment) {
|
||||||
|
// 先找出所有的父级
|
||||||
|
List<JwDepartmentTreeVo> treeList = getByParentId("1", allDepartment);
|
||||||
|
getChildrenRecursion(treeList, allDepartment);
|
||||||
|
return treeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<JwDepartmentTreeVo> getByParentId(String parentId, List<Department> allDepartment) {
|
||||||
|
List<JwDepartmentTreeVo> list = new ArrayList<>();
|
||||||
|
for (Department department : allDepartment) {
|
||||||
|
if (parentId.equals(department.getParentid())) {
|
||||||
|
list.add(new JwDepartmentTreeVo(department));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getChildrenRecursion(List<JwDepartmentTreeVo> treeList, List<Department> allDepartment) {
|
||||||
|
for (JwDepartmentTreeVo departmentTree : treeList) {
|
||||||
|
// 递归寻找子级
|
||||||
|
List<JwDepartmentTreeVo> children = getByParentId(departmentTree.getId(), allDepartment);
|
||||||
|
if (children.size() > 0) {
|
||||||
|
departmentTree.setChildren(children);
|
||||||
|
getChildrenRecursion(children, allDepartment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.jeecg.modules.system.vo.thirdapp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步结果信息,包含成功的信息和失败的信息
|
||||||
|
*
|
||||||
|
* @author sunjianlei
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SyncInfoVo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功的信息
|
||||||
|
*/
|
||||||
|
private List<String> successInfo;
|
||||||
|
/**
|
||||||
|
* 失败的信息
|
||||||
|
*/
|
||||||
|
private List<String> failInfo;
|
||||||
|
|
||||||
|
public SyncInfoVo() {
|
||||||
|
this.successInfo = new ArrayList<>();
|
||||||
|
this.failInfo = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SyncInfoVo(List<String> successInfo, List<String> failInfo) {
|
||||||
|
this.successInfo = successInfo;
|
||||||
|
this.failInfo = failInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SyncInfoVo addSuccessInfo(String info) {
|
||||||
|
this.successInfo.add(info);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SyncInfoVo addFailInfo(String info) {
|
||||||
|
this.failInfo.add(info);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,16 +14,16 @@ server:
|
||||||
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
|
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
|
||||||
|
|
||||||
management:
|
management:
|
||||||
endpoints:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
exposure:
|
exposure:
|
||||||
include: metrics,httptrace
|
include: metrics,httptrace
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
servlet:
|
servlet:
|
||||||
multipart:
|
multipart:
|
||||||
max-file-size: 10MB
|
max-file-size: 10MB
|
||||||
max-request-size: 10MB
|
max-request-size: 10MB
|
||||||
mail:
|
mail:
|
||||||
host: smtp.163.com
|
host: smtp.163.com
|
||||||
username: jeecgos@163.com
|
username: jeecgos@163.com
|
||||||
|
@ -131,7 +131,7 @@ spring:
|
||||||
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
|
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
|
||||||
datasource:
|
datasource:
|
||||||
master:
|
master:
|
||||||
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
|
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot-os-re?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
|
||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
@ -147,7 +147,7 @@ spring:
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
lettuce:
|
lettuce:
|
||||||
pool:
|
pool:
|
||||||
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
|
max-active: 8 #最大连接数据库连接数,设 -1 为没有限制
|
||||||
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
|
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
|
||||||
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
|
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
|
||||||
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
|
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
|
||||||
|
@ -170,29 +170,27 @@ mybatis-plus:
|
||||||
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
# 返回类型为Map,显示null对应的字段
|
# 返回类型为Map,显示null对应的字段
|
||||||
call-setters-on-nulls: true
|
call-setters-on-nulls: true
|
||||||
#minidao 设置
|
#jeecg专用配置
|
||||||
minidao :
|
minidao :
|
||||||
base-package: org.jeecg.modules.jmreport.*
|
base-package: org.jeecg.modules.jmreport.*
|
||||||
#DB类型(mysql | postgresql | oracle | sqlserver)
|
#DB类型(mysql | postgresql | oracle | sqlserver| other)
|
||||||
db-type: mysql
|
db-type: mysql
|
||||||
#jeecg专用配置
|
|
||||||
jeecg :
|
jeecg :
|
||||||
# 本地:local\Minio:minio\阿里云:alioss
|
# 本地:local\Minio:minio\阿里云:alioss
|
||||||
uploadType: local
|
uploadType: local
|
||||||
path :
|
path :
|
||||||
#文件上传根目录 设置
|
#文件上传根目录 设置
|
||||||
upload: D://opt//upFiles
|
upload: /opt/upFiles
|
||||||
#webapp文件路径
|
#webapp文件路径
|
||||||
webapp: D://opt//webapp
|
webapp: /opt/webapp
|
||||||
shiro:
|
shiro:
|
||||||
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
|
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
|
||||||
#阿里云oss存储配置
|
#阿里云oss存储和大鱼短信秘钥配置
|
||||||
oss:
|
oss:
|
||||||
endpoint: oss-cn-beijing.aliyuncs.com
|
|
||||||
accessKey: ??
|
accessKey: ??
|
||||||
secretKey: ??
|
secretKey: ??
|
||||||
|
endpoint: oss-cn-beijing.aliyuncs.com
|
||||||
bucketName: ??
|
bucketName: ??
|
||||||
staticDomain: ??
|
|
||||||
# ElasticSearch 6设置
|
# ElasticSearch 6设置
|
||||||
elasticsearch:
|
elasticsearch:
|
||||||
cluster-name: jeecg-ES
|
cluster-name: jeecg-ES
|
||||||
|
@ -204,6 +202,9 @@ jeecg :
|
||||||
theme-color: "#1890ff"
|
theme-color: "#1890ff"
|
||||||
# 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
|
# 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
|
||||||
upload-type: system
|
upload-type: system
|
||||||
|
map:
|
||||||
|
# 配置百度地图的AK,申请地址:https://lbs.baidu.com/apiconsole/key?application=key#/home
|
||||||
|
baidu: ??
|
||||||
# 在线预览文件服务器地址配置
|
# 在线预览文件服务器地址配置
|
||||||
file-view-domain: 127.0.0.1:8012
|
file-view-domain: 127.0.0.1:8012
|
||||||
# minio文件上传
|
# minio文件上传
|
||||||
|
@ -218,7 +219,7 @@ jeecg :
|
||||||
#数据字典是否进行saas数据隔离,自己看自己的字典
|
#数据字典是否进行saas数据隔离,自己看自己的字典
|
||||||
saas: false
|
saas: false
|
||||||
#是否需要校验token
|
#是否需要校验token
|
||||||
is_verify_token: false
|
is_verify_token: true
|
||||||
#必须校验方法
|
#必须校验方法
|
||||||
verify_methods: remove,delete,save,add,update
|
verify_methods: remove,delete,save,add,update
|
||||||
#Wps在线文档
|
#Wps在线文档
|
||||||
|
@ -260,7 +261,7 @@ logging:
|
||||||
knife4j:
|
knife4j:
|
||||||
production: false
|
production: false
|
||||||
basic:
|
basic:
|
||||||
enable: false
|
enable: true
|
||||||
username: jeecg
|
username: jeecg
|
||||||
password: jeecg1314
|
password: jeecg1314
|
||||||
#第三方登录
|
#第三方登录
|
||||||
|
@ -275,7 +276,7 @@ justauth:
|
||||||
client-id: ??
|
client-id: ??
|
||||||
client-secret: ??
|
client-secret: ??
|
||||||
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
|
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
|
||||||
agent-id: 1000002
|
agent-id: ??
|
||||||
DINGTALK:
|
DINGTALK:
|
||||||
client-id: ??
|
client-id: ??
|
||||||
client-secret: ??
|
client-secret: ??
|
||||||
|
@ -288,3 +289,26 @@ justauth:
|
||||||
type: default
|
type: default
|
||||||
prefix: 'demo::'
|
prefix: 'demo::'
|
||||||
timeout: 1h
|
timeout: 1h
|
||||||
|
#第三方APP对接
|
||||||
|
third-app:
|
||||||
|
enabled: false
|
||||||
|
type:
|
||||||
|
#企业微信
|
||||||
|
WECHAT_ENTERPRISE:
|
||||||
|
enabled: false
|
||||||
|
#CORP_ID
|
||||||
|
client-id: ??
|
||||||
|
#SECRET
|
||||||
|
client-secret: ??
|
||||||
|
#自建应用id
|
||||||
|
agent-id: ??
|
||||||
|
#自建应用秘钥(新版企微需要配置)
|
||||||
|
# agent-app-secret: ??
|
||||||
|
#钉钉
|
||||||
|
DINGTALK:
|
||||||
|
enabled: false
|
||||||
|
# appKey
|
||||||
|
client-id: ??
|
||||||
|
# appSecret
|
||||||
|
client-secret: ??
|
||||||
|
agent-id: ??
|
|
@ -14,16 +14,16 @@ server:
|
||||||
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
|
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
|
||||||
|
|
||||||
management:
|
management:
|
||||||
endpoints:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
exposure:
|
exposure:
|
||||||
include: metrics,httptrace
|
include: metrics,httptrace
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
servlet:
|
servlet:
|
||||||
multipart:
|
multipart:
|
||||||
max-file-size: 10MB
|
max-file-size: 10MB
|
||||||
max-request-size: 10MB
|
max-request-size: 10MB
|
||||||
mail:
|
mail:
|
||||||
host: smtp.163.com
|
host: smtp.163.com
|
||||||
username: jeecgos@163.com
|
username: jeecgos@163.com
|
||||||
|
@ -147,7 +147,7 @@ spring:
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
lettuce:
|
lettuce:
|
||||||
pool:
|
pool:
|
||||||
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
|
max-active: 8 #最大连接数据库连接数,设 -1 为没有限制
|
||||||
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
|
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
|
||||||
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
|
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
|
||||||
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
|
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
|
||||||
|
@ -170,12 +170,11 @@ mybatis-plus:
|
||||||
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
# 返回类型为Map,显示null对应的字段
|
# 返回类型为Map,显示null对应的字段
|
||||||
call-setters-on-nulls: true
|
call-setters-on-nulls: true
|
||||||
#minidao 设置
|
#jeecg专用配置
|
||||||
minidao :
|
minidao :
|
||||||
base-package: org.jeecg.modules.jmreport.*
|
base-package: org.jeecg.modules.jmreport.*
|
||||||
#DB类型(mysql | postgresql | oracle | sqlserver)
|
#DB类型(mysql | postgresql | oracle | sqlserver| other)
|
||||||
db-type: mysql
|
db-type: mysql
|
||||||
#jeecg专用配置
|
|
||||||
jeecg :
|
jeecg :
|
||||||
# 本地:local\Minio:minio\阿里云:alioss
|
# 本地:local\Minio:minio\阿里云:alioss
|
||||||
uploadType: alioss
|
uploadType: alioss
|
||||||
|
@ -185,18 +184,18 @@ jeecg :
|
||||||
#webapp文件路径
|
#webapp文件路径
|
||||||
webapp: /opt/jeecg-boot/webapp
|
webapp: /opt/jeecg-boot/webapp
|
||||||
shiro:
|
shiro:
|
||||||
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
|
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/api/getUserInfo
|
||||||
#阿里云oss存储配置
|
#阿里云oss存储和大鱼短信秘钥配置
|
||||||
oss:
|
oss:
|
||||||
endpoint: oss-cn-beijing.aliyuncs.com
|
|
||||||
accessKey: ??
|
accessKey: ??
|
||||||
secretKey: ??
|
secretKey: ??
|
||||||
|
endpoint: oss-cn-beijing.aliyuncs.com
|
||||||
bucketName: ??
|
bucketName: ??
|
||||||
staticDomain: https://static.jeecg.com
|
staticDomain: https://static.jeecg.com
|
||||||
# ElasticSearch 设置
|
# ElasticSearch 设置
|
||||||
elasticsearch:
|
elasticsearch:
|
||||||
cluster-name: jeecg-ES
|
cluster-name: jeecg-ES
|
||||||
cluster-nodes: 111.225.222.176:9200
|
cluster-nodes: ??
|
||||||
check-enabled: true
|
check-enabled: true
|
||||||
# 表单设计器配置
|
# 表单设计器配置
|
||||||
desform:
|
desform:
|
||||||
|
@ -204,6 +203,9 @@ jeecg :
|
||||||
theme-color: "#1890ff"
|
theme-color: "#1890ff"
|
||||||
# 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
|
# 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
|
||||||
upload-type: system
|
upload-type: system
|
||||||
|
map:
|
||||||
|
# 配置百度地图的AK,申请地址:https://lbs.baidu.com/apiconsole/key?application=key#/home
|
||||||
|
baidu: ??
|
||||||
# 在线预览文件服务器地址配置
|
# 在线预览文件服务器地址配置
|
||||||
file-view-domain: http://fileview.jeecg.com
|
file-view-domain: http://fileview.jeecg.com
|
||||||
# minio文件上传
|
# minio文件上传
|
||||||
|
@ -211,7 +213,7 @@ jeecg :
|
||||||
minio_url: http://minio.jeecg.com
|
minio_url: http://minio.jeecg.com
|
||||||
minio_name: ??
|
minio_name: ??
|
||||||
minio_pass: ??
|
minio_pass: ??
|
||||||
bucketName: otatest
|
bucketName: ??
|
||||||
#大屏报表参数设置
|
#大屏报表参数设置
|
||||||
jmreport:
|
jmreport:
|
||||||
mode: prod
|
mode: prod
|
||||||
|
@ -275,7 +277,7 @@ justauth:
|
||||||
client-id: ??
|
client-id: ??
|
||||||
client-secret: ??
|
client-secret: ??
|
||||||
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
|
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
|
||||||
agent-id: 1000002
|
agent-id: ??
|
||||||
DINGTALK:
|
DINGTALK:
|
||||||
client-id: ??
|
client-id: ??
|
||||||
client-secret: ??
|
client-secret: ??
|
||||||
|
@ -287,4 +289,27 @@ justauth:
|
||||||
cache:
|
cache:
|
||||||
type: default
|
type: default
|
||||||
prefix: 'demo::'
|
prefix: 'demo::'
|
||||||
timeout: 1h
|
timeout: 1h
|
||||||
|
#第三方APP对接
|
||||||
|
third-app:
|
||||||
|
enabled: false
|
||||||
|
type:
|
||||||
|
#企业微信
|
||||||
|
WECHAT_ENTERPRISE:
|
||||||
|
enabled: false
|
||||||
|
#CORP_ID
|
||||||
|
client-id: ??
|
||||||
|
#SECRET
|
||||||
|
client-secret: ??
|
||||||
|
#自建应用id
|
||||||
|
agent-id: ??
|
||||||
|
#自建应用秘钥(新版企微需要配置)
|
||||||
|
# agent-app-secret: ??
|
||||||
|
#钉钉
|
||||||
|
DINGTALK:
|
||||||
|
enabled: false
|
||||||
|
# appKey
|
||||||
|
client-id: ??
|
||||||
|
# appSecret
|
||||||
|
client-secret: ??
|
||||||
|
agent-id: ??
|
|
@ -14,16 +14,16 @@ server:
|
||||||
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
|
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
|
||||||
|
|
||||||
management:
|
management:
|
||||||
endpoints:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
exposure:
|
exposure:
|
||||||
include: metrics,httptrace
|
include: metrics,httptrace
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
servlet:
|
servlet:
|
||||||
multipart:
|
multipart:
|
||||||
max-file-size: 10MB
|
max-file-size: 10MB
|
||||||
max-request-size: 10MB
|
max-request-size: 10MB
|
||||||
mail:
|
mail:
|
||||||
host: smtp.163.com
|
host: smtp.163.com
|
||||||
username: jeecgos@163.com
|
username: jeecgos@163.com
|
||||||
|
@ -147,7 +147,7 @@ spring:
|
||||||
host: 192.168.1.199
|
host: 192.168.1.199
|
||||||
lettuce:
|
lettuce:
|
||||||
pool:
|
pool:
|
||||||
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
|
max-active: 8 #最大连接数据库连接数,设 -1 为没有限制
|
||||||
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
|
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
|
||||||
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
|
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
|
||||||
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
|
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
|
||||||
|
@ -170,12 +170,11 @@ mybatis-plus:
|
||||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
# 返回类型为Map,显示null对应的字段
|
# 返回类型为Map,显示null对应的字段
|
||||||
call-setters-on-nulls: true
|
call-setters-on-nulls: true
|
||||||
#minidao 设置
|
#jeecg专用配置
|
||||||
minidao :
|
minidao :
|
||||||
base-package: org.jeecg.modules.jmreport.*
|
base-package: org.jeecg.modules.jmreport.*
|
||||||
#DB类型(mysql | postgresql | oracle | sqlserver)
|
#DB类型(mysql | postgresql | oracle | sqlserver| other)
|
||||||
db-type: mysql
|
db-type: mysql
|
||||||
#jeecg专用配置
|
|
||||||
jeecg :
|
jeecg :
|
||||||
# 本地:local\Minio:minio\阿里云:alioss
|
# 本地:local\Minio:minio\阿里云:alioss
|
||||||
uploadType: local
|
uploadType: local
|
||||||
|
@ -186,17 +185,17 @@ jeecg :
|
||||||
webapp: D://opt//webapp
|
webapp: D://opt//webapp
|
||||||
shiro:
|
shiro:
|
||||||
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
|
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
|
||||||
#阿里云oss存储配置
|
#阿里云oss存储和大鱼短信秘钥配置
|
||||||
oss:
|
oss:
|
||||||
endpoint: oss-cn-beijing.aliyuncs.com
|
|
||||||
accessKey: ??
|
accessKey: ??
|
||||||
secretKey: ??
|
secretKey: ??
|
||||||
|
endpoint: oss-cn-beijing.aliyuncs.com
|
||||||
bucketName: ??
|
bucketName: ??
|
||||||
staticDomain: https://static.jeecg.com
|
staticDomain: https://static.jeecg.com
|
||||||
# ElasticSearch 设置
|
# ElasticSearch 设置
|
||||||
elasticsearch:
|
elasticsearch:
|
||||||
cluster-name: jeecg-ES
|
cluster-name: jeecg-ES
|
||||||
cluster-nodes: http://fileview.jeecg.com
|
cluster-nodes: ??
|
||||||
check-enabled: false
|
check-enabled: false
|
||||||
# 表单设计器配置
|
# 表单设计器配置
|
||||||
desform:
|
desform:
|
||||||
|
@ -204,6 +203,9 @@ jeecg :
|
||||||
theme-color: "#1890ff"
|
theme-color: "#1890ff"
|
||||||
# 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
|
# 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
|
||||||
upload-type: system
|
upload-type: system
|
||||||
|
map:
|
||||||
|
# 配置百度地图的AK,申请地址:https://lbs.baidu.com/apiconsole/key?application=key#/home
|
||||||
|
baidu: ??
|
||||||
# 在线预览文件服务器地址配置
|
# 在线预览文件服务器地址配置
|
||||||
file-view-domain: http://127.0.0.1:8012
|
file-view-domain: http://127.0.0.1:8012
|
||||||
# minio文件上传
|
# minio文件上传
|
||||||
|
@ -211,7 +213,7 @@ jeecg :
|
||||||
minio_url: http://minio.jeecg.com
|
minio_url: http://minio.jeecg.com
|
||||||
minio_name: ??
|
minio_name: ??
|
||||||
minio_pass: ??
|
minio_pass: ??
|
||||||
bucketName: otatest
|
bucketName: ??
|
||||||
#大屏报表参数设置
|
#大屏报表参数设置
|
||||||
jmreport:
|
jmreport:
|
||||||
mode: prod
|
mode: prod
|
||||||
|
@ -260,7 +262,7 @@ cas:
|
||||||
knife4j:
|
knife4j:
|
||||||
production: false
|
production: false
|
||||||
basic:
|
basic:
|
||||||
enable: false
|
enable: true
|
||||||
username: jeecg
|
username: jeecg
|
||||||
password: jeecg1314
|
password: jeecg1314
|
||||||
#第三方登录
|
#第三方登录
|
||||||
|
@ -275,7 +277,7 @@ justauth:
|
||||||
client-id: ??
|
client-id: ??
|
||||||
client-secret: ??
|
client-secret: ??
|
||||||
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
|
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
|
||||||
agent-id: 1000002
|
agent-id: ??
|
||||||
DINGTALK:
|
DINGTALK:
|
||||||
client-id: ??
|
client-id: ??
|
||||||
client-secret: ??
|
client-secret: ??
|
||||||
|
@ -288,3 +290,26 @@ justauth:
|
||||||
type: default
|
type: default
|
||||||
prefix: 'demo::'
|
prefix: 'demo::'
|
||||||
timeout: 1h
|
timeout: 1h
|
||||||
|
#第三方APP对接
|
||||||
|
third-app:
|
||||||
|
enabled: false
|
||||||
|
type:
|
||||||
|
#企业微信
|
||||||
|
WECHAT_ENTERPRISE:
|
||||||
|
enabled: false
|
||||||
|
#CORP_ID
|
||||||
|
client-id: ??
|
||||||
|
#SECRET
|
||||||
|
client-secret: ??
|
||||||
|
#自建应用id
|
||||||
|
agent-id: ??
|
||||||
|
#自建应用秘钥(新版企微需要配置)
|
||||||
|
# agent-app-secret: ??
|
||||||
|
#钉钉
|
||||||
|
DINGTALK:
|
||||||
|
enabled: false
|
||||||
|
# appKey
|
||||||
|
client-id: ??
|
||||||
|
# appSecret
|
||||||
|
client-secret: ??
|
||||||
|
agent-id: ??
|
|
@ -9,6 +9,6 @@ ${AnsiColor.BRIGHT_BLUE}
|
||||||
|
|
||||||
|
|
||||||
${AnsiColor.BRIGHT_GREEN}
|
${AnsiColor.BRIGHT_GREEN}
|
||||||
Jeecg Boot Version: 2.4.3
|
Jeecg Boot Version: 2.4.5
|
||||||
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
|
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
|
||||||
${AnsiColor.BLACK}
|
${AnsiColor.BLACK}
|
||||||
|
|
|
@ -45,6 +45,8 @@ public class ${entityName} implements Serializable {
|
||||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
||||||
</#if>
|
</#if>
|
||||||
|
<#elseif po.classType=='sel_tree'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
|
||||||
</#if>
|
</#if>
|
||||||
/**${po.filedComment}*/
|
/**${po.filedComment}*/
|
||||||
<#if po.fieldName == primaryKeyField>
|
<#if po.fieldName == primaryKeyField>
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<#elseif po.classType=='pca'>
|
<#elseif po.classType=='pca'>
|
||||||
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
|
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
|
||||||
<#elseif po.classType=='popup'>
|
<#elseif po.classType=='popup'>
|
||||||
<#if query_field_no gt 1> </#if><j-popup placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" code="${po.dictTable}" org-fields="${po.dictField}" dest-fields="${po.dictText}" :field="getPopupField('${po.dictText}')"/>
|
<#if query_field_no gt 1> </#if><j-popup placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" code="${po.dictTable}" org-fields="${po.dictField}" dest-fields="${po.dictText}" :field="getPopupField('${po.dictText}')" :multi="${po.extendParams.popupMulti?c}"/>
|
||||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
<#if po.dictTable?default("")?trim?length gt 1>
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
@ -289,7 +289,7 @@
|
||||||
<#elseif po.classType=='switch'>
|
<#elseif po.classType=='switch'>
|
||||||
dataIndex: '${po.fieldName}',
|
dataIndex: '${po.fieldName}',
|
||||||
customRender: (text) => (text ? filterMultiDictText(this.dictOptions['${po.fieldName}'], text) : ''),
|
customRender: (text) => (text ? filterMultiDictText(this.dictOptions['${po.fieldName}'], text) : ''),
|
||||||
<#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||||
dataIndex: '${po.fieldName}_dictText'
|
dataIndex: '${po.fieldName}_dictText'
|
||||||
<#elseif po.classType=='cat_tree'>
|
<#elseif po.classType=='cat_tree'>
|
||||||
<#if list_need_category>
|
<#if list_need_category>
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
org-fields="${po.dictField}"
|
org-fields="${po.dictField}"
|
||||||
dest-fields="${Format.underlineToHump(po.dictText)}"
|
dest-fields="${Format.underlineToHump(po.dictText)}"
|
||||||
code="${po.dictTable}"
|
code="${po.dictTable}"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
@input="popupCallback"
|
@input="popupCallback"
|
||||||
<#if po.readonly=='Y'>disabled</#if>/>
|
<#if po.readonly=='Y'>disabled</#if>/>
|
||||||
<#elseif po.classType =='sel_depart'>
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
|
|
@ -39,6 +39,8 @@ public class ${entityName} implements Serializable {
|
||||||
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'>
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'>
|
||||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
||||||
|
<#elseif po.classType=='sel_tree'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
/**${po.filedComment}*/
|
/**${po.filedComment}*/
|
||||||
|
|
|
@ -40,6 +40,8 @@ public class ${subTab.entityName} implements Serializable {
|
||||||
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'>
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'>
|
||||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
||||||
|
<#elseif po.classType=='sel_tree'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
/**${po.filedComment}*/
|
/**${po.filedComment}*/
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
<#elseif po.classType=='pca'>
|
<#elseif po.classType=='pca'>
|
||||||
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
|
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
|
||||||
<#elseif po.classType=='popup'>
|
<#elseif po.classType=='popup'>
|
||||||
<#if query_field_no gt 1> </#if><j-popup placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" code="${po.dictTable}" org-fields="${po.dictField}" dest-fields="${po.dictText}" :field="getPopupField('${po.dictText}')"/>
|
<#if query_field_no gt 1> </#if><j-popup placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" code="${po.dictTable}" org-fields="${po.dictField}" dest-fields="${po.dictText}" :field="getPopupField('${po.dictText}')" :multi="${po.extendParams.popupMulti?c}"/>
|
||||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
<#if po.dictTable?default("")?trim?length gt 1>
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
@ -277,7 +277,7 @@
|
||||||
<#elseif po.classType=='image'>
|
<#elseif po.classType=='image'>
|
||||||
dataIndex: '${po.fieldName}',
|
dataIndex: '${po.fieldName}',
|
||||||
scopedSlots: {customRender: 'imgSlot'}
|
scopedSlots: {customRender: 'imgSlot'}
|
||||||
<#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||||
dataIndex: '${po.fieldName}_dictText'
|
dataIndex: '${po.fieldName}_dictText'
|
||||||
<#elseif po.classType=='cat_tree'>
|
<#elseif po.classType=='cat_tree'>
|
||||||
<#if list_need_category>
|
<#if list_need_category>
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
org-fields="${po.dictField}"
|
org-fields="${po.dictField}"
|
||||||
dest-fields="${Format.underlineToHump(po.dictText)}"
|
dest-fields="${Format.underlineToHump(po.dictText)}"
|
||||||
code="${po.dictTable}"
|
code="${po.dictTable}"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
@input="popupCallback"
|
@input="popupCallback"
|
||||||
<#if po.readonly=='Y'>disabled</#if>/>
|
<#if po.readonly=='Y'>disabled</#if>/>
|
||||||
<#elseif po.classType =='sel_depart'>
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
org-fields="${po.dictField}"
|
org-fields="${po.dictField}"
|
||||||
dest-fields="${Format.underlineToHump(po.dictText)}"
|
dest-fields="${Format.underlineToHump(po.dictText)}"
|
||||||
code="${po.dictTable}"
|
code="${po.dictTable}"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
@input="popupCallback"/>
|
@input="popupCallback"/>
|
||||||
<#elseif po.classType =='sel_depart'>
|
<#elseif po.classType =='sel_depart'>
|
||||||
<j-select-depart v-model="model.${po.fieldName}" multi/>
|
<j-select-depart v-model="model.${po.fieldName}" multi/>
|
||||||
|
|
|
@ -40,6 +40,8 @@ public class ${entityName} implements Serializable {
|
||||||
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'>
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'>
|
||||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
||||||
|
<#elseif po.classType=='sel_tree'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
/**${po.filedComment}*/
|
/**${po.filedComment}*/
|
||||||
|
|
|
@ -35,6 +35,8 @@ public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, $
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add${entityName}(${entityName} ${entityName?uncap_first}) {
|
public void add${entityName}(${entityName} ${entityName?uncap_first}) {
|
||||||
|
//新增时设置hasChild为0
|
||||||
|
${entityName?uncap_first}.set${hasChildrenField?cap_first}(I${entityName}Service.NOCHILD);
|
||||||
if(oConvertUtils.isEmpty(${entityName?uncap_first}.get${pidFieldName?cap_first}())){
|
if(oConvertUtils.isEmpty(${entityName?uncap_first}.get${pidFieldName?cap_first}())){
|
||||||
${entityName?uncap_first}.set${pidFieldName?cap_first}(I${entityName}Service.ROOT_PID_VALUE);
|
${entityName?uncap_first}.set${pidFieldName?cap_first}(I${entityName}Service.ROOT_PID_VALUE);
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
<#elseif po.classType=='pca'>
|
<#elseif po.classType=='pca'>
|
||||||
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
|
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
|
||||||
<#elseif po.classType=='popup'>
|
<#elseif po.classType=='popup'>
|
||||||
<#if query_field_no gt 1> </#if><j-popup placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" code="${po.dictTable}" org-fields="${po.dictField}" dest-fields="${po.dictText}" :field="getPopupField('${po.dictText}')"/>
|
<#if query_field_no gt 1> </#if><j-popup placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" code="${po.dictTable}" org-fields="${po.dictField}" dest-fields="${po.dictText}" :field="getPopupField('${po.dictText}')" :multi="${po.extendParams.popupMulti?c}"/>
|
||||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
<#if po.dictTable?default("")?trim?length gt 1>
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
@ -265,7 +265,7 @@
|
||||||
<#elseif po.classType=='image'>
|
<#elseif po.classType=='image'>
|
||||||
dataIndex: '${po.fieldName}',
|
dataIndex: '${po.fieldName}',
|
||||||
scopedSlots: {customRender: 'imgSlot'}
|
scopedSlots: {customRender: 'imgSlot'}
|
||||||
<#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||||
dataIndex: '${po.fieldName}_dictText'
|
dataIndex: '${po.fieldName}_dictText'
|
||||||
<#elseif po.classType=='switch'>
|
<#elseif po.classType=='switch'>
|
||||||
dataIndex: '${po.fieldName}',
|
dataIndex: '${po.fieldName}',
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
org-fields="${po.dictField}"
|
org-fields="${po.dictField}"
|
||||||
dest-fields="${Format.underlineToHump(po.dictText)}"
|
dest-fields="${Format.underlineToHump(po.dictText)}"
|
||||||
code="${po.dictTable}"
|
code="${po.dictTable}"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
@input="popupCallback"
|
@input="popupCallback"
|
||||||
<#if po.readonly=='Y'>disabled</#if>/>
|
<#if po.readonly=='Y'>disabled</#if>/>
|
||||||
<#elseif po.classType =='sel_depart'>
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
|
|
@ -39,6 +39,8 @@ public class ${entityName} implements Serializable {
|
||||||
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'>
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'>
|
||||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||||
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
|
||||||
|
<#elseif po.classType=='sel_tree'>
|
||||||
|
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
/**${po.filedComment}*/
|
/**${po.filedComment}*/
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<#elseif po.classType=='pca'>
|
<#elseif po.classType=='pca'>
|
||||||
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
|
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
|
||||||
<#elseif po.classType=='popup'>
|
<#elseif po.classType=='popup'>
|
||||||
<#if query_field_no gt 1> </#if><j-popup placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" code="${po.dictTable}" org-fields="${po.dictField}" dest-fields="${po.dictText}" :field="getPopupField('${po.dictText}')"/>
|
<#if query_field_no gt 1> </#if><j-popup placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" code="${po.dictTable}" org-fields="${po.dictField}" dest-fields="${po.dictText}" :field="getPopupField('${po.dictText}')" :multi="${po.extendParams.popupMulti?c}"/>
|
||||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||||
<#if po.dictTable?default("")?trim?length gt 1>
|
<#if po.dictTable?default("")?trim?length gt 1>
|
||||||
|
@ -263,7 +263,7 @@
|
||||||
<#elseif po.classType=='image'>
|
<#elseif po.classType=='image'>
|
||||||
dataIndex: '${po.fieldName}',
|
dataIndex: '${po.fieldName}',
|
||||||
scopedSlots: {customRender: 'imgSlot'}
|
scopedSlots: {customRender: 'imgSlot'}
|
||||||
<#elseif po.classType=='sel_search' || po.classType=='list_multi' || po.classType=='list' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart'>
|
<#elseif po.classType=='sel_tree' || po.classType=='sel_search' || po.classType=='list_multi' || po.classType=='list' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart'>
|
||||||
dataIndex: '${po.fieldName}_dictText',
|
dataIndex: '${po.fieldName}_dictText',
|
||||||
<#elseif po.classType=='switch'>
|
<#elseif po.classType=='switch'>
|
||||||
dataIndex: '${po.fieldName}',
|
dataIndex: '${po.fieldName}',
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
org-fields="${po.dictField}"
|
org-fields="${po.dictField}"
|
||||||
dest-fields="${Format.underlineToHump(po.dictText)}"
|
dest-fields="${Format.underlineToHump(po.dictText)}"
|
||||||
code="${po.dictTable}"
|
code="${po.dictTable}"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
@input="popupCallback"
|
@input="popupCallback"
|
||||||
<#if po.readonly=='Y'>disabled</#if>/>
|
<#if po.readonly=='Y'>disabled</#if>/>
|
||||||
<#elseif po.classType =='sel_depart'>
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
org-fields="${po.dictField}"
|
org-fields="${po.dictField}"
|
||||||
dest-fields="${Format.underlineToHump(po.dictText)}"
|
dest-fields="${Format.underlineToHump(po.dictText)}"
|
||||||
code="${po.dictTable}"
|
code="${po.dictTable}"
|
||||||
|
:multi="${po.extendParams.popupMulti?c}"
|
||||||
@input="popupCallback"
|
@input="popupCallback"
|
||||||
<#if po.readonly=='Y'>disabled</#if>/>
|
<#if po.readonly=='Y'>disabled</#if>/>
|
||||||
<#elseif po.classType =='sel_depart'>
|
<#elseif po.classType =='sel_depart'>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue