Commit 68407729 by zhangdaiscott

JeecgBoot低代码平台 2.4.5 版本发布,钉钉与企业微信集成版本

parent 1bc7ee33
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
-- 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';
-- online 新增部门授权 扩展字段
-- 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>
<artifactId>jeecg-boot-base-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.3</version>
<version>2.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-base-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.3</version>
<version>2.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-base</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.3</version>
<version>2.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-base</artifactId>
<version>2.4.3</version>
<version>2.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -114,7 +114,7 @@
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>hibernate-re</artifactId>
<version>2.4.3-RC</version>
<version>2.4.5-RC</version>
</dependency>
<!--mysql-->
......
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);
}
......@@ -24,6 +24,11 @@ public class MessageDTO implements Serializable {
protected String toUser;
/**
* 发送给所有人
*/
protected boolean toAll;
/**
* 消息主题
*/
protected String title;
......
package org.jeecg.common.api.vo;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.jeecg.common.constant.CommonConstant;
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);
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) {
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.constant.CommonConstant;
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.util.IPUtils;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.base.service.BaseCommonService;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
......
......@@ -17,6 +17,7 @@ import org.jeecg.common.constant.CommonConstant;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
......@@ -38,6 +39,8 @@ public class DictAspect {
@Autowired
private CommonAPI commonAPI;
@Autowired
public RedisTemplate redisTemplate;
// 定义切点Pointcut
@Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))")
......@@ -144,12 +147,33 @@ public class DictAspect {
if (k.trim().length() == 0) {
continue; //跳过循环
}
//update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
if (!StringUtils.isEmpty(table)){
log.debug("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim());
log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
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 {
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 (!"".equals(textValue.toString())) {
textValue.append(",");
......
......@@ -305,4 +305,21 @@ public interface CommonConstant {
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用
*/
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_POSTGRESQL = "POSTGRESQL";
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
public static final String DB_TYPE_MARIADB = "MARIADB";
// 数据库类型,对应 database_type 字典
public static final String DB_TYPE_MYSQL_NUM = "1";
public static final String DB_TYPE_ORACLE_NUM = "2";
public static final String DB_TYPE_SQLSERVER_NUM = "3";
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"
*/
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)) {
order = parameterMap.get(ORDER_TYPE)[0];
}
log.debug("排序规则>>列:"+column+",排序方式:"+order);
log.info("排序规则>>列:" + column + ",排序方式:" + order);
if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
//字典字段,去掉字典翻译文本后缀
if(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
}
//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) {
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
String columnStr = oConvertUtils.camelToUnderline(column);
String[] columnArray = columnStr.split(",");
queryWrapper.orderByAsc(columnArray);
} else {
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
*/
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(",");
for (String str : special_str) {
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.interfaces.DecodedJWT;
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.jeecg.common.constant.CommonConstant;
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.oConvertUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
/**
* @Author Scott
* @Date 2018-07-12 14:23
......
......@@ -14,6 +14,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.sql.DataSource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
......@@ -74,7 +75,8 @@ public class CommonUtils {
fileName = fileName.substring(pos + 1);
}
//替换上传文件名字的特殊字符
fileName = fileName.replace("=","").replace(",","").replace("&","").replace("#", "");
fileName = fileName.replace("=","").replace(",","").replace("&","")
.replace("#", "").replace("“", "").replace("”", "");
//替换上传文件名字中的空格
fileName=fileName.replaceAll("\\s","");
return fileName;
......@@ -106,6 +108,44 @@ public class CommonUtils {
}
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);
} catch (SQLException e) {
//e.printStackTrace();
log.warn(e.getMessage());
log.warn(e.getMessage(),e);
return "";
}
}
......@@ -157,8 +197,11 @@ public class CommonUtils {
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
}else if(dbType.indexOf("postgresql")>=0) {
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
}else if(dbType.indexOf("mariadb")>=0) {
DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
}else {
throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
log.error("数据库类型:[" + dbType + "]不识别!");
//throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
......
......@@ -75,7 +75,11 @@ public class MinioUtil {
orgName=file.getName();
}
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上传一个本地文件到存储桶中。
if(objectName.startsWith("/")){
......
......@@ -13,6 +13,7 @@ import java.util.Map;
public class SqlUtils {
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_ORACLE = "oracle";
public static final String DATABSE_TYPE_SQLSERVER = "sqlserver";
......@@ -47,7 +48,7 @@ public class SqlUtils {
*/
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) {
......
......@@ -111,7 +111,9 @@ public class OssBootUtil {
orgName=file.getName();
}
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("/")) {
fileDir = fileDir.concat("/");
}
......
......@@ -23,7 +23,7 @@ import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
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.Collections;
......@@ -33,7 +33,7 @@ import java.util.List;
* @Author scott
*/
@Configuration
@EnableSwagger2
@EnableSwagger2WebMvc
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Config implements WebMvcConfigurer {
......
......@@ -19,7 +19,7 @@ public class OssConfiguration {
private String accessKeySecret;
@Value("${jeecg.oss.bucketName}")
private String bucketName;
@Value("${jeecg.oss.staticDomain}")
@Value("${jeecg.oss.staticDomain:}")
private String staticDomain;
......
package org.jeecg.config.shiro;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
......@@ -110,6 +111,11 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/webjars/**", "anon");
filterChainDefinitionMap.put("/v2/**", "anon");
// update-begin--Author:sunjianlei Date:20210510 for:排除消息通告查看详情页面(用于第三方APP)
filterChainDefinitionMap.put("/sys/annountCement/show/**", "anon");
// update-end--Author:sunjianlei Date:20210510 for:排除消息通告查看详情页面(用于第三方APP)
//积木报表排除
filterChainDefinitionMap.put("/jmreport/**", "anon");
filterChainDefinitionMap.put("/**/*.js.map", "anon");
......@@ -127,7 +133,7 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
filterChainDefinitionMap.put("/eoaSocket/**","anon");//我的聊天
//性能监控 TODO 存在安全漏洞泄露TOEKN(durid连接池也有)
filterChainDefinitionMap.put("/actuator/**", "anon");
......@@ -241,8 +247,17 @@ public class ShiroConfig {
RedisClusterManager redisManager = new RedisClusterManager();
Set<HostAndPort> portSet = new HashSet<>();
lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));
JedisCluster jedisCluster = new JedisCluster(portSet);
redisManager.setJedisCluster(jedisCluster);
//update-begin--Author:scott Date:20210531 for:修改集群模式下未设置redis密码的bug issues/I3QNIC
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;
}
return manager;
......
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;
}
}
}
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;
}
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>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-base</artifactId>
<version>2.4.3</version>
<version>2.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<description>公共模块</description>
......
......@@ -81,4 +81,14 @@ public interface CacheConstant {
* online表单页配置信息缓存key
*/
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
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
log.info(" --- redis config init --- ");
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =jacksonSerializer();
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = jacksonSerializer();
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
// key序列化
redisTemplate.setKeySerializer(stringSerializer);
// value序列化
......@@ -98,10 +99,13 @@ public class RedisConfig extends CachingConfigurerSupport {
*/
@Bean
public CacheManager cacheManager(LettuceConnectionFactory factory) {
// 配置序列化(缓存默认有效期 6小时)
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = jacksonSerializer();
// 配置序列化(解决乱码的问题),并且配置缓存默认有效期 6小时
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6));
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
//.disableCachingNullValues();
// 以锁写入的方式创建RedisCacheWriter对象
//update-begin-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符*
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));
/* 自定义配置test:demo 的超时时间为 5分钟*/
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.PLUGIN_MALL_RANKING, 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>
<artifactId>jeecg-boot-parent</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.3</version>
<version>2.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-parent</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.3</version>
<version>2.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -10,6 +10,6 @@ WORKDIR /jeecg-boot
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
\ No newline at end of file
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-2.4.5.jar
\ No newline at end of file
......@@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-parent</artifactId>
<version>2.4.3</version>
<version>2.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -35,15 +35,20 @@
<artifactId>jeecg-system-local-api</artifactId>
</dependency>
<dependency>
<groupId>org.jeecgframework</groupId>
<artifactId>jeewx-api</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-module-demo</artifactId>
<version>${jeecgboot.version}</version>
</dependency>
<!-- 积木报表 -->
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>spring-boot-starter-jimureport</artifactId>
<version>1.3.1-beta4</version>
<version>1.3.3-beta</version>
<exclusions>
<exclusion>
<groupId>org.jeecgframework</groupId>
......
package org.jeecg.modules.quartz.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.ImportExcelUtil;
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.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
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.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @Description: 定时任务在线管理
......@@ -89,10 +78,6 @@ public class QuartzJobController {
//@RequiresRoles("admin")
@RequestMapping(value = "/add", method = RequestMethod.POST)
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);
return Result.ok("创建定时任务成功");
}
......@@ -155,15 +140,14 @@ public class QuartzJobController {
/**
* 暂停定时任务
*
* @param jobClassName
* @param id
* @return
*/
//@RequiresRoles("admin")
@GetMapping(value = "/pause")
@ApiOperation(value = "暂停定时任务")
public Result<Object> pauseJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
QuartzJob job = null;
job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
QuartzJob job = quartzJobService.getById(id);
if (job == null) {
return Result.error("定时任务不存在!");
}
......@@ -174,14 +158,14 @@ public class QuartzJobController {
/**
* 启动定时任务
*
* @param jobClassName
* @param id
* @return
*/
//@RequiresRoles("admin")
@GetMapping(value = "/resume")
@ApiOperation(value = "恢复定时任务")
public Result<Object> resumeJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
QuartzJob job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
QuartzJob job = quartzJobService.getById(id);
if (job == null) {
return Result.error("定时任务不存在!");
}
......
......@@ -26,7 +26,7 @@ public class SampleParamJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info(String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
log.info(" Job Execution key:"+jobExecutionContext.getJobDetail().getKey());
log.info( String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
}
}
package org.jeecg.modules.quartz.service.impl;
import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
......@@ -13,9 +12,8 @@ import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
/**
* @Description: 定时任务在线管理
......@@ -46,13 +44,16 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
*/
@Override
public boolean saveAndScheduleJob(QuartzJob quartzJob) {
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
// 定时器添加
this.schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
}
// DB设置修改
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
public boolean resumeJob(QuartzJob quartzJob) {
schedulerDelete(quartzJob.getJobClassName().trim());
schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
schedulerDelete(quartzJob.getId());
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
return this.updateById(quartzJob);
}
......@@ -73,10 +74,10 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
@Override
public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
schedulerDelete(quartzJob.getJobClassName().trim());
schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
schedulerDelete(quartzJob.getId());
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
}else{
scheduler.pauseJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));
scheduler.pauseJob(JobKey.jobKey(quartzJob.getId()));
}
return this.updateById(quartzJob);
}
......@@ -86,7 +87,7 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
*/
@Override
public boolean deleteAndStopJob(QuartzJob job) {
schedulerDelete(job.getJobClassName().trim());
schedulerDelete(job.getId());
boolean ok = this.removeById(job.getId());
return ok;
}
......@@ -98,7 +99,9 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
String identity = jobName + ymd;
//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
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
.withIdentity(identity, JOB_TEST_GROUP)
......@@ -114,31 +117,31 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
@Override
public void pause(QuartzJob quartzJob){
schedulerDelete(quartzJob.getJobClassName().trim());
schedulerDelete(quartzJob.getId());
quartzJob.setStatus(CommonConstant.STATUS_DISABLE);
this.updateById(quartzJob);
}
/**
* 添加定时任务
*
*
* @param jobClassName
* @param cronExpression
* @param parameter
*/
private void schedulerAdd(String jobClassName, String cronExpression, String parameter) {
private void schedulerAdd(String id, String jobClassName, String cronExpression, String parameter) {
try {
// 启动调度器
scheduler.start();
// 构建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);
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build();
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(id).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
} 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 {
scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
scheduler.deleteJob(JobKey.jobKey(jobClassName));
scheduler.pauseTrigger(TriggerKey.triggerKey(id));
scheduler.unscheduleJob(TriggerKey.triggerKey(id));
scheduler.deleteJob(JobKey.jobKey(id));
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new JeecgBootException("删除定时任务失败");
......
......@@ -133,7 +133,7 @@ public class CommonController {
String orgName = mf.getOriginalFilename();// 获取文件名
orgName = CommonUtils.getFileName(orgName);
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{
fileName = orgName+ "_" + System.currentTimeMillis();
}
......
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 com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeecg.dingtalk.api.core.response.Response;
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.query.QueryGenerator;
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.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.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 com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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 lombok.extern.slf4j.Slf4j;
import static org.jeecg.common.constant.CommonConstant.ANNOUNCEMENT_SEND_STATUS_1;
/**
* @Title: Controller
......@@ -67,6 +67,15 @@ public class SysAnnouncementController {
private ISysAnnouncementSendService sysAnnouncementSendService;
@Resource
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());
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);
if(ok) {
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;
}
/**
* 通告查看详情页面(用于第三方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 delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
* @return
*/
@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<>();
// 非空判断
if (StringUtils.isBlank(ids)) {
......@@ -420,13 +421,8 @@ public class SysCategoryController {
result.setMessage("ids 不能为空");
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);
// 取出name并返回
List<String> textList = list.stream().map(SysCategory::getName).collect(Collectors.toList());
List<String> textList = sysCategoryService.loadDictItem(ids, delNotExist);
result.setSuccess(true);
result.setResult(textList);
return result;
......
package org.jeecg.modules.system.controller;
import java.io.IOException;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
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.authz.annotation.RequiresRoles;
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.SysDepartTreeModel;
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.ISysUserService;
import org.jeecg.modules.system.util.FindsDepartsChildrenUtil;
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.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
/**
* <p>
......@@ -133,6 +127,33 @@ public class SysDepartController {
}
/**
* 获取某个部门的所有父级部门的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());
}
}
/**
* 添加新数据 添加用户新建的部门对象数据,并保存到数据库
*
* @param sysDepart
......
......@@ -31,7 +31,6 @@ 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.entity.result.ExcelImportResult;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.BeanUtils;
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) {
log.info(" dictCode : "+ dictCode);
Result<List<DictModel>> result = new Result<List<DictModel>>();
List<DictModel> ls = null;
try {
if(dictCode.indexOf(",")!=-1) {
//关联表字典(举例:sys_user,realname,id)
String[] params = dictCode.split(",");
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);
List<DictModel> ls = sysDictService.getDictItems(dictCode);
if (ls == null) {
result.error500("字典Code格式不正确!");
return result;
}
result.setSuccess(true);
result.setResult(ls);
log.debug(result.toString());
result.setSuccess(true);
result.setResult(ls);
log.debug(result.toString());
} catch (Exception e) {
log.error(e.getMessage(),e);
log.error(e.getMessage(), e);
result.error500("操作失败");
return result;
}
return result;
}
......@@ -198,8 +173,9 @@ public class SysDictController {
}
/**
* 【JSearchSelectTag下拉搜索组件专用接口】
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
* @param dictCode
* @param dictCode 字典code格式:table,text,code
* @return
*/
@RequestMapping(value = "/loadDict/{dictCode}", method = RequestMethod.GET)
......@@ -209,39 +185,75 @@ public class SysDictController {
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
log.info(" 加载字典表数据,加载关键字: "+ keyword);
Result<List<DictModel>> result = new Result<List<DictModel>>();
List<DictModel> ls = null;
try {
if(dictCode.indexOf(",")!=-1) {
String[] params = dictCode.split(",");
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 {
List<DictModel> ls = sysDictService.loadDict(dictCode, keyword, pageSize);
if (ls == null) {
result.error500("字典Code格式不正确!");
return result;
}
result.setSuccess(true);
result.setResult(ls);
log.info(result.toString());
return result;
} catch (Exception e) {
log.error(e.getMessage(),e);
result.error500("操作失败");
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;
}
/**
*
* 根据字典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)
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<>();
try {
if(dictCode.indexOf(",")!=-1) {
......@@ -250,7 +262,7 @@ public class SysDictController {
result.error500("字典Code格式不正确!");
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.setResult(texts);
......@@ -407,12 +419,14 @@ public class SysDictController {
//清空字典缓存
Set keys = redisTemplate.keys(CacheConstant.SYS_DICT_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 keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
Set keys5 = redisTemplate.keys( "jmreport:cache:dict*");
Set keys6 = redisTemplate.keys( "jmreport:cache:dictTable*");
redisTemplate.delete(keys);
redisTemplate.delete(keys2);
redisTemplate.delete(keys21);
redisTemplate.delete(keys3);
redisTemplate.delete(keys4);
redisTemplate.delete(keys5);
......
......@@ -145,8 +145,8 @@ public class SysUserController {
user.setPassword(passwordEncode);
user.setStatus(1);
user.setDelFlag(CommonConstant.DEL_FLAG_0);
sysUserService.addUserWithRole(user, selectedRoles);
sysUserService.addUserWithDepart(user, selectedDeparts);
// 保存用户走一个service 保证事务
sysUserService.saveUser(user, selectedRoles, selectedDeparts);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
......@@ -172,9 +172,8 @@ public class SysUserController {
user.setPassword(sysUser.getPassword());
String roles = jsonObject.getString("selectedroles");
String departs = jsonObject.getString("selecteddeparts");
sysUserService.editUserWithRole(user, roles);
sysUserService.editUserWithDepart(user, departs);
sysUserService.updateNullPhoneEmail();
// 修改用户走一个service 保证事务
sysUserService.editUser(user, roles, departs);
result.success("修改成功!");
}
} catch (Exception e) {
......@@ -279,6 +278,7 @@ public class SysUserController {
result.setResult(true);
try {
//通过传入信息查询新的用户信息
sysUser.setPassword(null);
SysUser user = sysUserService.getOne(new QueryWrapper<SysUser>(sysUser));
if (user != null) {
result.setSuccess(false);
......@@ -298,6 +298,7 @@ public class SysUserController {
/**
* 修改密码
*/
//@RequiresRoles({"admin"})
@RequestMapping(value = "/changePassword", method = RequestMethod.PUT)
public Result<?> changePassword(@RequestBody SysUser sysUser) {
SysUser u = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysUser.getUsername()));
......@@ -389,6 +390,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
*
* @param request
......@@ -521,13 +539,17 @@ public class SysUserController {
/**
* 首页用户重置密码
*/
//@RequiresRoles({"admin"})
@RequestMapping(value = "/updatePassword", method = RequestMethod.PUT)
public Result<?> changPassword(@RequestBody JSONObject json) {
//@RequiresRoles({"admin"})
@RequestMapping(value = "/updatePassword", method = RequestMethod.PUT)
public Result<?> updatePassword(@RequestBody JSONObject json) {
String username = json.getString("username");
String oldpassword = json.getString("oldpassword");
String password = json.getString("password");
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));
if(user==null) {
return Result.error("用户不存在!");
......@@ -1338,4 +1360,6 @@ public class SysUserController {
sysUserService.updateById(user);
return Result.ok("手机号设置成功!");
}
}
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");
}
}
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.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
/**
* @Description: 系统通告表
* @Author: jeecg-boot
......@@ -144,4 +143,8 @@ public class SysAnnouncement implements Serializable {
* 摘要
*/
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 lombok.Data;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.modules.system.model.SysDepartTreeModel;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
......@@ -73,6 +71,8 @@ public class SysDepart implements Serializable {
/**删除状态(0,正常,1已删除)*/
@Dict(dicCode = "del_flag")
private String delFlag;
/**对接企业微信的ID*/
private String qywxIdentifier;
/**创建人*/
private String createBy;
/**创建日期*/
......
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.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
/**
......@@ -60,4 +55,8 @@ public class SysThirdAccount {
@Excel(name = "真实姓名", width = 15)
@ApiModelProperty(value = "真实姓名")
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.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.ResultType;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.jeecg.common.system.vo.DictModel;
......@@ -132,4 +131,26 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
*/
@Deprecated
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);
}
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.jeecg.modules.system.entity.SysThirdAccount;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
/**
* @Description: 第三方登录账号表
* @Author: jeecg-boot
* @Date: 2020-11-17
* @Date: 2020-11-17
* @Version: V1.0
*/
public interface SysThirdAccountMapper extends BaseMapper<SysThirdAccount> {
/**
* 通过 sysUsername 集合批量查询
*
* @param sysUsernameArr username集合
* @param thirdType 第三方类型
* @return
*/
List<SysThirdAccount> selectThirdIdsByUsername(@Param("sysUsernameArr") String[] sysUsernameArr, @Param("thirdType") String thirdType);
}
package org.jeecg.modules.system.mapper;
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.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
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>
</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>
......@@ -24,7 +24,7 @@
<!-- 首页访问统计 -->
<select id="findVisitCount" resultType="java.util.HashMap">
<if test="dbType == 'MYSQL'">
<if test="dbType == 'MYSQL' || dbType == 'MARIADB'">
select count(*) as visit
,count(distinct(ip)) as ip
,DATE_FORMAT(create_time, '%Y-%m-%d') as tian
......@@ -34,7 +34,7 @@
group by tian,type
order by tian asc
</if>
<if test="dbType == 'ORACLE'">
<if test="dbType == 'ORACLE' || dbType == 'DM'">
select count(*) as visit
,count(distinct(ip)) as ip
,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">
<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>
\ No newline at end of file
......@@ -6,4 +6,29 @@
FROM sys_user_depart
WHERE user_id = #{userId, jdbcType=VARCHAR}
</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>
\ No newline at end of file
......@@ -65,6 +65,8 @@ public class SysDepartTreeModel implements Serializable{
private String delFlag;
private String qywxIdentifier;
private String createBy;
private Date createTime;
......@@ -100,6 +102,7 @@ public class SysDepartTreeModel implements Serializable{
this.memo = sysDepart.getMemo();
this.status = sysDepart.getStatus();
this.delFlag = sysDepart.getDelFlag();
this.qywxIdentifier = sysDepart.getQywxIdentifier();
this.createBy = sysDepart.getCreateBy();
this.createTime = sysDepart.getCreateTime();
this.updateBy = sysDepart.getUpdateBy();
......@@ -287,6 +290,14 @@ public class SysDepartTreeModel implements Serializable{
this.delFlag = delFlag;
}
public String getQywxIdentifier() {
return qywxIdentifier;
}
public void setQywxIdentifier(String qywxIdentifier) {
this.qywxIdentifier = qywxIdentifier;
}
public String getCreateBy() {
return createBy;
}
......@@ -349,6 +360,7 @@ public class SysDepartTreeModel implements Serializable{
Objects.equals(memo, model.memo) &&
Objects.equals(status, model.status) &&
Objects.equals(delFlag, model.delFlag) &&
Objects.equals(qywxIdentifier, model.qywxIdentifier) &&
Objects.equals(createBy, model.createBy) &&
Objects.equals(createTime, model.createTime) &&
Objects.equals(updateBy, model.updateBy) &&
......@@ -364,7 +376,7 @@ public class SysDepartTreeModel implements Serializable{
return Objects.hash(id, parentId, departName, departNameEn, departNameAbbr,
departOrder, description, orgCategory, orgType, orgCode, mobile, fax, address,
memo, status, delFlag, createBy, createTime, updateBy, updateTime,
memo, status, delFlag, qywxIdentifier, createBy, createTime, updateBy, updateTime,
children);
}
......
package org.jeecg.modules.system.service;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.system.entity.SysCategory;
import org.jeecg.modules.system.model.TreeSelectModel;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* @Description: 分类字典
......@@ -58,5 +57,22 @@ public interface ISysCategoryService extends IService<SysCategory> {
* @param 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);
}
package org.jeecg.modules.system.service;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.model.DepartIdModel;
......@@ -112,6 +113,20 @@ public interface ISysDepartService extends IService<SysDepart>{
* @return
*/
List<SysDepartTreeModel> queryTreeListByPid(String parentId);
/**
* 获取某个部门的所有父级部门的ID
*
* @param departId 根据departId查
*/
JSONObject queryAllParentIdByDepartId(String departId);
/**
* 获取某个部门的所有父级部门的ID
*
* @param orgCode 根据orgCode查
*/
JSONObject queryAllParentIdByOrgCode(String orgCode);
/**
* 获取公司信息
* @return
......
package org.jeecg.modules.system.service;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.DictQuery;
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.model.TreeSelectModel;
import java.util.List;
import java.util.Map;
/**
* <p>
* 字典表 服务类
......@@ -37,6 +37,8 @@ public interface ISysDictService extends IService<SysDict> {
@Deprecated
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);
/**
* 查询所有部门 作为字典信息 id -->value,departName -->text
* @return
*/
public List<DictModel> queryAllDepartBackDictModel();
/**
* 查询所有用户 作为字典信息 username -->value,realname -->text
* @return
*/
public List<DictModel> queryAllUserBackDictModel();
/**
* 通过关键字查询字典表
* @param table
......@@ -82,7 +84,18 @@ public interface ISysDictService extends IService<SysDict> {
* @param keyword
* @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
......@@ -125,4 +138,21 @@ public interface ISysDictService extends IService<SysDict> {
@Deprecated
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> {
/**
* 通过code查询
*/
SysPosition getByCode(String code);
}
package org.jeecg.modules.system.service;
import org.jeecg.modules.system.entity.SysThirdAccount;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysThirdAccount;
import org.jeecg.modules.system.entity.SysUser;
import java.util.List;
/**
* @Description: 第三方登录账号表
* @Author: jeecg-boot
......@@ -15,5 +17,19 @@ public interface ISysThirdAccountService extends IService<SysThirdAccount> {
void updateThirdUserId(SysUser sysUser,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 com.baomidou.mybatisplus.core.metadata.IPage;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.model.DepartIdModel;
......@@ -37,5 +38,16 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
/**
* 根据部门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);
}
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.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.SysUserCacheInfo;
import org.jeecg.modules.system.entity.SysUser;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* <p>
* 用户表 服务类
......@@ -233,4 +232,24 @@ public interface ISysUserService extends IService<SysUser> {
* @return
*/
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);
}
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);
}
package org.jeecg.modules.system.service.impl;
import java.util.HashMap;
import java.util.ArrayList;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
......@@ -95,6 +92,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
@Autowired
private ISysPermissionDataRuleService sysPermissionDataRuleService;
@Autowired
private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
@Autowired
private ThirdAppDingtalkServiceImpl dingtalkService;
@Override
@Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
public LoginUser getUserByName(String username) {
......@@ -201,6 +203,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
info.setSysUserCode(user.getUsername());
info.setSysUserName(user.getRealname());
info.setSysOrgCode(user.getOrgCode());
}else{
return null;
}
//多部门支持in查询
List<SysDepart> list = departMapper.queryUserDeparts(user.getId());
......@@ -267,7 +271,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
}
@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) {
return sysDictService.queryDictItemsByCode(code);
}
......@@ -294,6 +298,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
message.getTitle(),
message.getContent(),
message.getCategory());
try {
// 同步发送第三方APP消息
wechatEnterpriseService.sendMessage(message, true);
dingtalkService.sendMessage(message, true);
} catch (Exception e) {
log.error("同步发送第三方APP消息失败!", e);
}
}
@Override
......@@ -305,6 +316,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
message.getCategory(),
message.getBusType(),
message.getBusId());
try {
// 同步发送第三方APP消息
wechatEnterpriseService.sendMessage(message, true);
dingtalkService.sendMessage(message, true);
} catch (Exception e) {
log.error("同步发送第三方APP消息失败!", e);
}
}
@Override
......@@ -368,6 +386,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
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());
}
}
try {
// 同步企业微信、钉钉的消息通知
dingtalkService.sendActionCardMessage(announcement, true);
wechatEnterpriseService.sendTextCardMessage(announcement, true);
} catch (Exception e) {
log.error("同步发送第三方APP消息失败!", e);
}
}
@Override
......@@ -492,8 +525,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
}else if(dbType.indexOf("postgresql")>=0) {
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
}else if(dbType.indexOf("mariadb")>=0) {
DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
}else {
throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
log.error("数据库类型:[" + dbType + "]不识别!");
//throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
......@@ -848,7 +884,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
/**
* 36根据多个用户账号(逗号分隔),查询返回多个用户信息
* @param orgCodes
* @param usernames
* @return
*/
@Override
......@@ -867,7 +903,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
/**
* 37根据多个部门编码(逗号分隔),查询返回多个部门信息
* @param usernames
* @param orgCodes
* @return
*/
@Override
......
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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.constant.FillRuleConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.common.util.YouBianCodeUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysCategory;
import org.jeecg.modules.system.mapper.SysCategoryMapper;
import org.jeecg.modules.system.model.TreeSelectModel;
import org.jeecg.modules.system.service.ISysCategoryService;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Description: 分类字典
* @Author: jeecg-boot
......@@ -204,4 +204,32 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa
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;
}
}
package org.jeecg.modules.system.service.impl;
import java.util.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
......@@ -21,10 +24,7 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.StringUtil;
import java.util.*;
/**
* <p>
......@@ -468,7 +468,8 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
SysDepart depart = list.get(i);
SysDepartTreeModel treeModel = new SysDepartTreeModel(depart);
//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());
if(count>0){
treeModel.setIsLeaf(false);
......@@ -479,6 +480,59 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
}
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
public SysDepart queryCompByOrgCode(String orgCode) {
int length = YouBianCodeUtil.zhanweiLength;
......
......@@ -9,6 +9,7 @@ import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.DictQuery;
import org.jeecg.common.util.SqlInjectionUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysDict;
import org.jeecg.modules.system.entity.SysDictItem;
......@@ -50,7 +51,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
* @return
*/
@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) {
log.debug("无缓存dictCache的时候调用这里!");
return sysDictMapper.queryDictItemsByCode(code);
......@@ -86,7 +87,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
*/
@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) {
log.debug("无缓存dictText的时候调用这里!");
return sysDictMapper.queryDictTextByKey(code, key);
......@@ -123,12 +124,17 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
* @return
*/
@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) {
log.debug("无缓存dictTable的时候调用这里!");
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
* dictTableCache采用redis缓存有效期10分钟
......@@ -136,28 +142,33 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
* @param text
* @param code
* @param keys (逗号分隔)
* @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
* @return
*/
@Override
//update-begin--Author:lvdandan Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存
//@Cacheable(value = CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE)
//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)){
return null;
}
String[] keyArray = keys.split(",");
List<DictModel> dicts = sysDictMapper.queryTableDictByKeys(table, text, code, keyArray);
List<String> texts = new ArrayList<>(dicts.size());
// update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
// 查询出来的顺序可能是乱的,需要排个序
for (String key : keyArray) {
for (DictModel dict : dicts) {
if (key.equals(dict.getValue())) {
texts.add(dict.getText());
break;
}
List<DictModel> res = dicts.stream().filter(i -> key.equals(i.getValue())).collect(Collectors.toList());
if (res.size() > 0) {
texts.add(res.get(0).getText());
} else if (!delNotExist) {
texts.add(key);
}
}
// update-end--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
return texts;
}
......@@ -205,12 +216,49 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
}
@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);
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();
}
/**
* 获取条件语句
* @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
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);
......@@ -238,4 +286,61 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
Page<DictModel> pageList = baseMapper.queryDictTablePageList(page, query);
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;
}
}
}
package org.jeecg.modules.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.system.entity.SysPosition;
import org.jeecg.modules.system.mapper.SysPositionMapper;
......@@ -15,4 +16,11 @@ import org.springframework.stereotype.Service;
@Service
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);
}
}
package org.jeecg.modules.system.service.impl;
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.util.DateUtils;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.UUIDGenerator;
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.SysUserRoleMapper;
import org.jeecg.modules.system.service.ISysThirdAccountService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Date;
import java.util.List;
/**
......@@ -55,7 +55,8 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
thirdQuery.eq(SysThirdAccount::getThirdType,account.getThirdType());
SysThirdAccount sysThirdAccounts = sysThirdAccountMapper.selectOne(thirdQuery);
if(sysThirdAccounts!=null){
sysThirdAccountMapper.deleteById(sysThirdAccounts.getId());
sysThirdAccount.setThirdUserId(sysThirdAccounts.getThirdUserId());
sysThirdAccountMapper.deleteById(sysThirdAccounts.getId());
}
//更新用户账户表sys_user_id
sysThirdAccountMapper.update(sysThirdAccount,query);
......@@ -67,6 +68,13 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
query.eq(SysThirdAccount::getThirdUserUuid,thirdUserUuid);
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();
user.setActivitiSync(CommonConstant.ACT_SYNC_0);
......@@ -103,4 +111,26 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
sysUserRoleMapper.insert(userRole);
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);
}
}
package org.jeecg.modules.system.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Collectors;
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.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
......@@ -100,34 +104,58 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
*/
@Override
public List<SysUser> queryUserByDepCode(String depCode,String realname) {
LambdaQueryWrapper<SysDepart> queryByDepCode = new LambdaQueryWrapper<SysDepart>();
queryByDepCode.likeRight(SysDepart::getOrgCode,depCode);
List<SysDepart> sysDepartList = sysDepartService.list(queryByDepCode);
List<String> depIds = sysDepartList.stream().map(SysDepart::getId).collect(Collectors.toList());
//update-begin-author:taoyan date:20210422 for: 根据部门选择用户接口代码优化
if(oConvertUtils.isNotEmpty(realname)){
realname = realname.trim();
}
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: 根据部门选择用户接口代码优化
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());
}
@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);
}
List<SysUser> userList = (List<SysUser>) sysUserService.list(queryUser);
//update-begin-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
for (SysUser sysUser : userList) {
sysUser.setSalt("");
sysUser.setPassword("");
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);
});
}
//update-end-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
return userList;
pageList.setRecords(new ArrayList<SysUser>(map.values()));
}
return new ArrayList<SysUser>();
return pageList;
}
}
......@@ -10,12 +10,12 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
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.SysUserCacheInfo;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.mapper.*;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
......@@ -62,6 +62,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
private SysDepartRoleMapper sysDepartRoleMapper;
@Resource
private BaseCommonService baseCommonService;
@Autowired
private SysThirdAccountMapper sysThirdAccountMapper;
@Autowired
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
@Autowired
ThirdAppDingtalkServiceImpl dingtalkService;
@Override
@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));
//3. 删除用户角色关系
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;
}
......@@ -439,4 +455,88 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
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());
}
}
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);
}
}
package org.jeecg.modules.system.util;
import lombok.extern.slf4j.Slf4j;
/**
* 多租户 tenant_id存储器
*/
@Slf4j
public class TenantContext {
private static ThreadLocal<String> currentTenant = new ThreadLocal<>();
public static void setTenant(String tenant) {
log.debug(" setting tenant to " + tenant);
currentTenant.set(tenant);
}
public static String getTenant() {
return currentTenant.get();
}
public static void clear(){
currentTenant.remove();
}
}
//package org.jeecg.modules.system.util;
//
//import lombok.extern.slf4j.Slf4j;
//
///**
// * 多租户 tenant_id存储器
// */
//@Slf4j
//public class TenantContext {
//
// private static ThreadLocal<String> currentTenant = new ThreadLocal<>();
//
// public static void setTenant(String tenant) {
// log.debug(" setting tenant to " + tenant);
// currentTenant.set(tenant);
// }
//
// public static String getTenant() {
// return currentTenant.get();
// }
//
// public static void clear(){
// currentTenant.remove();
// }
//}
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);
}
}
}
}
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);
}
}
}
}
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/*
management:
endpoints:
web:
exposure:
include: metrics,httptrace
endpoints:
web:
exposure:
include: metrics,httptrace
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
multipart:
max-file-size: 10MB
max-request-size: 10MB
mail:
host: smtp.163.com
username: jeecgos@163.com
......@@ -131,7 +131,7 @@ spring:
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
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
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
......@@ -147,7 +147,7 @@ spring:
host: 127.0.0.1
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
max-active: 8 #最大连接数据库连接数,设 -1 为没有限制
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
......@@ -170,29 +170,27 @@ mybatis-plus:
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 返回类型为Map,显示null对应的字段
call-setters-on-nulls: true
#minidao 设
#jeecg专用配
minidao :
base-package: org.jeecg.modules.jmreport.*
#DB类型(mysql | postgresql | oracle | sqlserver)
#DB类型(mysql | postgresql | oracle | sqlserver| other
db-type: mysql
#jeecg专用配置
jeecg :
# 本地:local\Minio:minio\阿里云:alioss
uploadType: local
path :
#文件上传根目录 设置
upload: D://opt//upFiles
upload: /opt/upFiles
#webapp文件路径
webapp: D://opt//webapp
webapp: /opt/webapp
shiro:
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
#阿里云oss存储配置
#阿里云oss存储和大鱼短信秘钥配置
oss:
endpoint: oss-cn-beijing.aliyuncs.com
accessKey: ??
secretKey: ??
endpoint: oss-cn-beijing.aliyuncs.com
bucketName: ??
staticDomain: ??
# ElasticSearch 6设置
elasticsearch:
cluster-name: jeecg-ES
......@@ -204,6 +202,9 @@ jeecg :
theme-color: "#1890ff"
# 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
upload-type: system
map:
# 配置百度地图的AK,申请地址:https://lbs.baidu.com/apiconsole/key?application=key#/home
baidu: ??
# 在线预览文件服务器地址配置
file-view-domain: 127.0.0.1:8012
# minio文件上传
......@@ -218,7 +219,7 @@ jeecg :
#数据字典是否进行saas数据隔离,自己看自己的字典
saas: false
#是否需要校验token
is_verify_token: false
is_verify_token: true
#必须校验方法
verify_methods: remove,delete,save,add,update
#Wps在线文档
......@@ -260,7 +261,7 @@ logging:
knife4j:
production: false
basic:
enable: false
enable: true
username: jeecg
password: jeecg1314
#第三方登录
......@@ -275,7 +276,7 @@ justauth:
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
agent-id: 1000002
agent-id: ??
DINGTALK:
client-id: ??
client-secret: ??
......@@ -288,3 +289,26 @@ justauth:
type: default
prefix: 'demo::'
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: ??
\ No newline at end of file
......@@ -14,16 +14,16 @@ server:
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
management:
endpoints:
web:
exposure:
include: metrics,httptrace
endpoints:
web:
exposure:
include: metrics,httptrace
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
multipart:
max-file-size: 10MB
max-request-size: 10MB
mail:
host: smtp.163.com
username: jeecgos@163.com
......@@ -147,7 +147,7 @@ spring:
host: 127.0.0.1
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
max-active: 8 #最大连接数据库连接数,设 -1 为没有限制
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
......@@ -170,12 +170,11 @@ mybatis-plus:
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 返回类型为Map,显示null对应的字段
call-setters-on-nulls: true
#minidao 设
#jeecg专用配
minidao :
base-package: org.jeecg.modules.jmreport.*
#DB类型(mysql | postgresql | oracle | sqlserver)
#DB类型(mysql | postgresql | oracle | sqlserver| other
db-type: mysql
#jeecg专用配置
jeecg :
# 本地:local\Minio:minio\阿里云:alioss
uploadType: alioss
......@@ -185,18 +184,18 @@ jeecg :
#webapp文件路径
webapp: /opt/jeecg-boot/webapp
shiro:
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
#阿里云oss存储配置
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/api/getUserInfo
#阿里云oss存储和大鱼短信秘钥配置
oss:
endpoint: oss-cn-beijing.aliyuncs.com
accessKey: ??
secretKey: ??
endpoint: oss-cn-beijing.aliyuncs.com
bucketName: ??
staticDomain: https://static.jeecg.com
# ElasticSearch 设置
elasticsearch:
cluster-name: jeecg-ES
cluster-nodes: 111.225.222.176:9200
cluster-nodes: ??
check-enabled: true
# 表单设计器配置
desform:
......@@ -204,6 +203,9 @@ jeecg :
theme-color: "#1890ff"
# 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
upload-type: system
map:
# 配置百度地图的AK,申请地址:https://lbs.baidu.com/apiconsole/key?application=key#/home
baidu: ??
# 在线预览文件服务器地址配置
file-view-domain: http://fileview.jeecg.com
# minio文件上传
......@@ -211,7 +213,7 @@ jeecg :
minio_url: http://minio.jeecg.com
minio_name: ??
minio_pass: ??
bucketName: otatest
bucketName: ??
#大屏报表参数设置
jmreport:
mode: prod
......@@ -275,7 +277,7 @@ justauth:
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
agent-id: 1000002
agent-id: ??
DINGTALK:
client-id: ??
client-secret: ??
......@@ -287,4 +289,27 @@ justauth:
cache:
type: default
prefix: 'demo::'
timeout: 1h
\ No newline at end of file
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: ??
\ No newline at end of file
......@@ -14,16 +14,16 @@ server:
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
management:
endpoints:
web:
exposure:
include: metrics,httptrace
endpoints:
web:
exposure:
include: metrics,httptrace
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
multipart:
max-file-size: 10MB
max-request-size: 10MB
mail:
host: smtp.163.com
username: jeecgos@163.com
......@@ -147,7 +147,7 @@ spring:
host: 192.168.1.199
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
max-active: 8 #最大连接数据库连接数,设 -1 为没有限制
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
......@@ -170,12 +170,11 @@ mybatis-plus:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 返回类型为Map,显示null对应的字段
call-setters-on-nulls: true
#minidao 设
#jeecg专用配
minidao :
base-package: org.jeecg.modules.jmreport.*
#DB类型(mysql | postgresql | oracle | sqlserver)
#DB类型(mysql | postgresql | oracle | sqlserver| other
db-type: mysql
#jeecg专用配置
jeecg :
# 本地:local\Minio:minio\阿里云:alioss
uploadType: local
......@@ -186,17 +185,17 @@ jeecg :
webapp: D://opt//webapp
shiro:
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
#阿里云oss存储配置
#阿里云oss存储和大鱼短信秘钥配置
oss:
endpoint: oss-cn-beijing.aliyuncs.com
accessKey: ??
secretKey: ??
endpoint: oss-cn-beijing.aliyuncs.com
bucketName: ??
staticDomain: https://static.jeecg.com
# ElasticSearch 设置
elasticsearch:
cluster-name: jeecg-ES
cluster-nodes: http://fileview.jeecg.com
cluster-nodes: ??
check-enabled: false
# 表单设计器配置
desform:
......@@ -204,6 +203,9 @@ jeecg :
theme-color: "#1890ff"
# 文件、图片上传方式,可选项:qiniu(七牛云)、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
# minio文件上传
......@@ -211,7 +213,7 @@ jeecg :
minio_url: http://minio.jeecg.com
minio_name: ??
minio_pass: ??
bucketName: otatest
bucketName: ??
#大屏报表参数设置
jmreport:
mode: prod
......@@ -260,7 +262,7 @@ cas:
knife4j:
production: false
basic:
enable: false
enable: true
username: jeecg
password: jeecg1314
#第三方登录
......@@ -275,7 +277,7 @@ justauth:
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
agent-id: 1000002
agent-id: ??
DINGTALK:
client-id: ??
client-secret: ??
......@@ -288,3 +290,26 @@ justauth:
type: default
prefix: 'demo::'
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: ??
\ No newline at end of file
......@@ -9,6 +9,6 @@ ${AnsiColor.BRIGHT_BLUE}
${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}
${AnsiColor.BLACK}
......@@ -45,6 +45,8 @@ public class ${entityName} implements Serializable {
<#elseif po.dictField?default("")?trim?length gt 1>
<#assign list_field_dictCode=', dicCode = "${po.dictField}"'>
</#if>
<#elseif po.classType=='sel_tree'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
</#if>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
......
......@@ -50,7 +50,7 @@
<#elseif po.classType=='pca'>
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
<#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'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
<#if po.dictTable?default("")?trim?length gt 1>
......@@ -289,7 +289,7 @@
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
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'
<#elseif po.classType=='cat_tree'>
<#if list_need_category>
......
......@@ -44,6 +44,7 @@
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
:multi="${po.extendParams.popupMulti?c}"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#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}"'>
<#elseif po.dictField?default("")?trim?length gt 1>
<#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>
/**${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}"'>
<#elseif po.dictField?default("")?trim?length gt 1>
<#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>
/**${po.filedComment}*/
......
......@@ -47,7 +47,7 @@
<#elseif po.classType=='pca'>
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
<#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'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
<#if po.dictTable?default("")?trim?length gt 1>
......@@ -277,7 +277,7 @@
<#elseif po.classType=='image'>
dataIndex: '${po.fieldName}',
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'
<#elseif po.classType=='cat_tree'>
<#if list_need_category>
......
......@@ -49,6 +49,7 @@
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
:multi="${po.extendParams.popupMulti?c}"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
......
......@@ -46,6 +46,7 @@
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
:multi="${po.extendParams.popupMulti?c}"
@input="popupCallback"/>
<#elseif po.classType =='sel_depart'>
<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}"'>
<#elseif po.dictField?default("")?trim?length gt 1>
<#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>
/**${po.filedComment}*/
......
......@@ -35,6 +35,8 @@ public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, $
@Override
public void add${entityName}(${entityName} ${entityName?uncap_first}) {
//新增时设置hasChild0
${entityName?uncap_first}.set${hasChildrenField?cap_first}(I${entityName}Service.NOCHILD);
if(oConvertUtils.isEmpty(${entityName?uncap_first}.get${pidFieldName?cap_first}())){
${entityName?uncap_first}.set${pidFieldName?cap_first}(I${entityName}Service.ROOT_PID_VALUE);
}else{
......
......@@ -59,7 +59,7 @@
<#elseif po.classType=='pca'>
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
<#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'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
<#if po.dictTable?default("")?trim?length gt 1>
......@@ -265,7 +265,7 @@
<#elseif po.classType=='image'>
dataIndex: '${po.fieldName}',
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'
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
......
......@@ -52,6 +52,7 @@
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
:multi="${po.extendParams.popupMulti?c}"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#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}"'>
<#elseif po.dictField?default("")?trim?length gt 1>
<#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>
/**${po.filedComment}*/
......
......@@ -42,7 +42,7 @@
<#elseif po.classType=='pca'>
<#if query_field_no gt 1> </#if><j-area-linkage type="cascader" v-model="queryParam.${po.fieldName}" placeholder="请选择省市区"/>
<#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'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
<#if po.dictTable?default("")?trim?length gt 1>
......@@ -263,7 +263,7 @@
<#elseif po.classType=='image'>
dataIndex: '${po.fieldName}',
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',
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
......
......@@ -40,6 +40,7 @@
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
:multi="${po.extendParams.popupMulti?c}"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
......
......@@ -42,6 +42,7 @@
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
:multi="${po.extendParams.popupMulti?c}"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment