Commit 743ba7d90238779df3b0b2769e088b9ba558d30c

Authored by zhangdaiscott
1 parent d5e19d16

重构system模块代码规范,JeecgBoot 3.2.0 版本发布

Showing 80 changed files with 2257 additions and 409 deletions
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/init/SystemInitListener.java
... ... @@ -28,7 +28,8 @@ public class SystemInitListener implements ApplicationListener<ApplicationReadyE
28 28 public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
29 29  
30 30 log.info(" 服务已启动,初始化路由配置 ###################");
31   - if (applicationReadyEvent.getApplicationContext().getDisplayName().indexOf("AnnotationConfigServletWebServerApplicationContext") > -1) {
  31 + String context = "AnnotationConfigServletWebServerApplicationContext";
  32 + if (applicationReadyEvent.getApplicationContext().getDisplayName().indexOf(context) > -1) {
32 33 sysGatewayRouteService.addRoute2Redis(CacheConstant.GATEWAY_ROUTES);
33 34 }
34 35  
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java 0 → 100644
  1 +package org.jeecg.modules.api.controller;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import lombok.extern.slf4j.Slf4j;
  5 +import org.jeecg.common.api.dto.OnlineAuthDTO;
  6 +import org.jeecg.common.api.dto.message.*;
  7 +import org.jeecg.common.system.vo.*;
  8 +import org.jeecg.modules.system.service.ISysUserService;
  9 +import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.web.bind.annotation.*;
  12 +
  13 +import java.util.List;
  14 +import java.util.Map;
  15 +import java.util.Set;
  16 +
  17 +
  18 +/**
  19 + * 服务化 system模块 对外接口请求类
  20 + * @author: jeecg-boot
  21 + */
  22 +@Slf4j
  23 +@RestController
  24 +@RequestMapping("/sys/api")
  25 +public class SystemApiController {
  26 +
  27 + @Autowired
  28 + private SysBaseApiImpl sysBaseApi;
  29 + @Autowired
  30 + private ISysUserService sysUserService;
  31 +
  32 +
  33 + /**
  34 + * 发送系统消息
  35 + * @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息
  36 + */
  37 + @PostMapping("/sendSysAnnouncement")
  38 + public void sendSysAnnouncement(@RequestBody MessageDTO message){
  39 + sysBaseApi.sendSysAnnouncement(message);
  40 + }
  41 +
  42 + /**
  43 + * 发送消息 附带业务参数
  44 + * @param message 使用构造器赋值参数
  45 + */
  46 + @PostMapping("/sendBusAnnouncement")
  47 + public void sendBusAnnouncement(@RequestBody BusMessageDTO message){
  48 + sysBaseApi.sendBusAnnouncement(message);
  49 + }
  50 +
  51 + /**
  52 + * 通过模板发送消息
  53 + * @param message 使用构造器赋值参数
  54 + */
  55 + @PostMapping("/sendTemplateAnnouncement")
  56 + public void sendTemplateAnnouncement(@RequestBody TemplateMessageDTO message){
  57 + sysBaseApi.sendTemplateAnnouncement(message);
  58 + }
  59 +
  60 + /**
  61 + * 通过模板发送消息 附带业务参数
  62 + * @param message 使用构造器赋值参数
  63 + */
  64 + @PostMapping("/sendBusTemplateAnnouncement")
  65 + public void sendBusTemplateAnnouncement(@RequestBody BusTemplateMessageDTO message){
  66 + sysBaseApi.sendBusTemplateAnnouncement(message);
  67 + }
  68 +
  69 + /**
  70 + * 通过消息中心模板,生成推送内容
  71 + * @param templateDTO 使用构造器赋值参数
  72 + * @return
  73 + */
  74 + @PostMapping("/parseTemplateByCode")
  75 + public String parseTemplateByCode(@RequestBody TemplateDTO templateDTO){
  76 + return sysBaseApi.parseTemplateByCode(templateDTO);
  77 + }
  78 +
  79 + /**
  80 + * 根据业务类型busType及业务busId修改消息已读
  81 + */
  82 + @GetMapping("/updateSysAnnounReadFlag")
  83 + public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId")String busId){
  84 + sysBaseApi.updateSysAnnounReadFlag(busType, busId);
  85 + }
  86 +
  87 + /**
  88 + * 根据用户账号查询用户信息
  89 + * @param username
  90 + * @return
  91 + */
  92 + @GetMapping("/getUserByName")
  93 + public LoginUser getUserByName(@RequestParam("username") String username){
  94 + return sysBaseApi.getUserByName(username);
  95 + }
  96 +
  97 + /**
  98 + * 根据用户id查询用户信息
  99 + * @param id
  100 + * @return
  101 + */
  102 + @GetMapping("/getUserById")
  103 + LoginUser getUserById(@RequestParam("id") String id){
  104 + return sysBaseApi.getUserById(id);
  105 + }
  106 +
  107 + /**
  108 + * 通过用户账号查询角色集合
  109 + * @param username
  110 + * @return
  111 + */
  112 + @GetMapping("/getRolesByUsername")
  113 + List<String> getRolesByUsername(@RequestParam("username") String username){
  114 + return sysBaseApi.getRolesByUsername(username);
  115 + }
  116 +
  117 + /**
  118 + * 通过用户账号查询部门集合
  119 + * @param username
  120 + * @return 部门 id
  121 + */
  122 + @GetMapping("/getDepartIdsByUsername")
  123 + List<String> getDepartIdsByUsername(@RequestParam("username") String username){
  124 + return sysBaseApi.getDepartIdsByUsername(username);
  125 + }
  126 +
  127 + /**
  128 + * 通过用户账号查询部门 name
  129 + * @param username
  130 + * @return 部门 name
  131 + */
  132 + @GetMapping("/getDepartNamesByUsername")
  133 + List<String> getDepartNamesByUsername(@RequestParam("username") String username){
  134 + return sysBaseApi.getDepartNamesByUsername(username);
  135 + }
  136 +
  137 +
  138 + /**
  139 + * 获取数据字典
  140 + * @param code
  141 + * @return
  142 + */
  143 + @GetMapping("/queryDictItemsByCode")
  144 + List<DictModel> queryDictItemsByCode(@RequestParam("code") String code){
  145 + return sysBaseApi.queryDictItemsByCode(code);
  146 + }
  147 +
  148 + /**
  149 + * 获取有效的数据字典
  150 + * @param code
  151 + * @return
  152 + */
  153 + @GetMapping("/queryEnableDictItemsByCode")
  154 + List<DictModel> queryEnableDictItemsByCode(@RequestParam("code") String code){
  155 + return sysBaseApi.queryEnableDictItemsByCode(code);
  156 + }
  157 +
  158 +
  159 + /** 查询所有的父级字典,按照create_time排序 */
  160 + @GetMapping("/queryAllDict")
  161 + List<DictModel> queryAllDict(){
  162 +// try{
  163 +// //睡10秒,gateway网关5秒超时,会触发熔断降级操作
  164 +// Thread.sleep(10000);
  165 +// }catch (Exception e){
  166 +// e.printStackTrace();
  167 +// }
  168 +
  169 + log.info("--我是jeecg-system服务节点,微服务接口queryAllDict被调用--");
  170 + return sysBaseApi.queryAllDict();
  171 + }
  172 +
  173 + /**
  174 + * 查询所有分类字典
  175 + * @return
  176 + */
  177 + @GetMapping("/queryAllSysCategory")
  178 + List<SysCategoryModel> queryAllSysCategory(){
  179 + return sysBaseApi.queryAllSysCategory();
  180 + }
  181 +
  182 +
  183 + /**
  184 + * 查询所有部门 作为字典信息 id -->value,departName -->text
  185 + * @return
  186 + */
  187 + @GetMapping("/queryAllDepartBackDictModel")
  188 + List<DictModel> queryAllDepartBackDictModel(){
  189 + return sysBaseApi.queryAllDepartBackDictModel();
  190 + }
  191 +
  192 + /**
  193 + * 获取所有角色 带参
  194 + * roleIds 默认选中角色
  195 + * @return
  196 + */
  197 + @GetMapping("/queryAllRole")
  198 + public List<ComboModel> queryAllRole(@RequestParam(name = "roleIds",required = false)String[] roleIds){
  199 + if(roleIds==null || roleIds.length==0){
  200 + return sysBaseApi.queryAllRole();
  201 + }else{
  202 + return sysBaseApi.queryAllRole(roleIds);
  203 + }
  204 + }
  205 +
  206 + /**
  207 + * 通过用户账号查询角色Id集合
  208 + * @param username
  209 + * @return
  210 + */
  211 + @GetMapping("/getRoleIdsByUsername")
  212 + public List<String> getRoleIdsByUsername(@RequestParam("username")String username){
  213 + return sysBaseApi.getRoleIdsByUsername(username);
  214 + }
  215 +
  216 + /**
  217 + * 通过部门编号查询部门id
  218 + * @param orgCode
  219 + * @return
  220 + */
  221 + @GetMapping("/getDepartIdsByOrgCode")
  222 + public String getDepartIdsByOrgCode(@RequestParam("orgCode")String orgCode){
  223 + return sysBaseApi.getDepartIdsByOrgCode(orgCode);
  224 + }
  225 +
  226 + /**
  227 + * 查询所有部门
  228 + * @return
  229 + */
  230 + @GetMapping("/getAllSysDepart")
  231 + public List<SysDepartModel> getAllSysDepart(){
  232 + return sysBaseApi.getAllSysDepart();
  233 + }
  234 +
  235 + /**
  236 + * 根据 id 查询数据库中存储的 DynamicDataSourceModel
  237 + *
  238 + * @param dbSourceId
  239 + * @return
  240 + */
  241 + @GetMapping("/getDynamicDbSourceById")
  242 + DynamicDataSourceModel getDynamicDbSourceById(@RequestParam("dbSourceId")String dbSourceId){
  243 + return sysBaseApi.getDynamicDbSourceById(dbSourceId);
  244 + }
  245 +
  246 +
  247 +
  248 + /**
  249 + * 根据部门Id获取部门负责人
  250 + * @param deptId
  251 + * @return
  252 + */
  253 + @GetMapping("/getDeptHeadByDepId")
  254 + public List<String> getDeptHeadByDepId(@RequestParam("deptId") String deptId){
  255 + return sysBaseApi.getDeptHeadByDepId(deptId);
  256 + }
  257 +
  258 + /**
  259 + * 查找父级部门
  260 + * @param departId
  261 + * @return
  262 + */
  263 + @GetMapping("/getParentDepartId")
  264 + public DictModel getParentDepartId(@RequestParam("departId")String departId){
  265 + return sysBaseApi.getParentDepartId(departId);
  266 + }
  267 +
  268 + /**
  269 + * 根据 code 查询数据库中存储的 DynamicDataSourceModel
  270 + *
  271 + * @param dbSourceCode
  272 + * @return
  273 + */
  274 + @GetMapping("/getDynamicDbSourceByCode")
  275 + public DynamicDataSourceModel getDynamicDbSourceByCode(@RequestParam("dbSourceCode") String dbSourceCode){
  276 + return sysBaseApi.getDynamicDbSourceByCode(dbSourceCode);
  277 + }
  278 +
  279 + /**
  280 + * 给指定用户发消息
  281 + * @param userIds
  282 + * @param cmd
  283 + */
  284 + @GetMapping("/sendWebSocketMsg")
  285 + public void sendWebSocketMsg(String[] userIds, String cmd){
  286 + sysBaseApi.sendWebSocketMsg(userIds, cmd);
  287 + }
  288 +
  289 +
  290 + /**
  291 + * 根据id获取所有参与用户
  292 + * userIds
  293 + * @return
  294 + */
  295 + @GetMapping("/queryAllUserByIds")
  296 + public List<LoginUser> queryAllUserByIds(@RequestParam("userIds") String[] userIds){
  297 + return sysBaseApi.queryAllUserByIds(userIds);
  298 + }
  299 +
  300 + /**
  301 + * 查询所有用户 返回ComboModel
  302 + * @return
  303 + */
  304 + @GetMapping("/queryAllUserBackCombo")
  305 + public List<ComboModel> queryAllUserBackCombo(){
  306 + return sysBaseApi.queryAllUserBackCombo();
  307 + }
  308 +
  309 + /**
  310 + * 分页查询用户 返回JSONObject
  311 + * @return
  312 + */
  313 + @GetMapping("/queryAllUser")
  314 + public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) int pageSize){
  315 + return sysBaseApi.queryAllUser(userIds, pageNo, pageSize);
  316 + }
  317 +
  318 +
  319 +
  320 + /**
  321 + * 将会议签到信息推动到预览
  322 + * userIds
  323 + * @return
  324 + * @param userId
  325 + */
  326 + @GetMapping("/meetingSignWebsocket")
  327 + public void meetingSignWebsocket(@RequestParam("userId")String userId){
  328 + sysBaseApi.meetingSignWebsocket(userId);
  329 + }
  330 +
  331 + /**
  332 + * 根据name获取所有参与用户
  333 + * userNames
  334 + * @return
  335 + */
  336 + @GetMapping("/queryUserByNames")
  337 + public List<LoginUser> queryUserByNames(@RequestParam("userNames")String[] userNames){
  338 + return sysBaseApi.queryUserByNames(userNames);
  339 + }
  340 +
  341 + /**
  342 + * 获取用户的角色集合
  343 + * @param username
  344 + * @return
  345 + */
  346 + @GetMapping("/getUserRoleSet")
  347 + public Set<String> getUserRoleSet(@RequestParam("username")String username){
  348 + return sysBaseApi.getUserRoleSet(username);
  349 + }
  350 +
  351 + /**
  352 + * 获取用户的权限集合
  353 + * @param username
  354 + * @return
  355 + */
  356 + @GetMapping("/getUserPermissionSet")
  357 + public Set<String> getUserPermissionSet(@RequestParam("username") String username){
  358 + return sysBaseApi.getUserPermissionSet(username);
  359 + }
  360 +
  361 + //-----
  362 +
  363 + /**
  364 + * 判断是否有online访问的权限
  365 + * @param onlineAuthDTO
  366 + * @return
  367 + */
  368 + @PostMapping("/hasOnlineAuth")
  369 + public boolean hasOnlineAuth(@RequestBody OnlineAuthDTO onlineAuthDTO){
  370 + return sysBaseApi.hasOnlineAuth(onlineAuthDTO);
  371 + }
  372 +
  373 + /**
  374 + * 查询用户角色信息
  375 + * @param username
  376 + * @return
  377 + */
  378 + @GetMapping("/queryUserRoles")
  379 + public Set<String> queryUserRoles(@RequestParam("username") String username){
  380 + return sysUserService.getUserRolesSet(username);
  381 + }
  382 +
  383 +
  384 + /**
  385 + * 查询用户权限信息
  386 + * @param username
  387 + * @return
  388 + */
  389 + @GetMapping("/queryUserAuths")
  390 + public Set<String> queryUserAuths(@RequestParam("username") String username){
  391 + return sysUserService.getUserPermissionsSet(username);
  392 + }
  393 +
  394 + /**
  395 + * 通过部门id获取部门全部信息
  396 + */
  397 + @GetMapping("/selectAllById")
  398 + public SysDepartModel selectAllById(@RequestParam("id") String id){
  399 + return sysBaseApi.selectAllById(id);
  400 + }
  401 +
  402 + /**
  403 + * 根据用户id查询用户所属公司下所有用户ids
  404 + * @param userId
  405 + * @return
  406 + */
  407 + @GetMapping("/queryDeptUsersByUserId")
  408 + public List<String> queryDeptUsersByUserId(@RequestParam("userId") String userId){
  409 + return sysBaseApi.queryDeptUsersByUserId(userId);
  410 + }
  411 +
  412 +
  413 + /**
  414 + * 查询数据权限
  415 + * @return
  416 + */
  417 + @GetMapping("/queryPermissionDataRule")
  418 + public List<SysPermissionDataRuleModel> queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath")String requestPath, @RequestParam("username") String username){
  419 + return sysBaseApi.queryPermissionDataRule(component, requestPath, username);
  420 + }
  421 +
  422 + /**
  423 + * 查询用户信息
  424 + * @param username
  425 + * @return
  426 + */
  427 + @GetMapping("/getCacheUser")
  428 + public SysUserCacheInfo getCacheUser(@RequestParam("username") String username){
  429 + return sysBaseApi.getCacheUser(username);
  430 + }
  431 +
  432 + /**
  433 + * 普通字典的翻译
  434 + * @param code
  435 + * @param key
  436 + * @return
  437 + */
  438 + @GetMapping("/translateDict")
  439 + public String translateDict(@RequestParam("code") String code, @RequestParam("key") String key){
  440 + return sysBaseApi.translateDict(code, key);
  441 + }
  442 +
  443 +
  444 + /**
  445 + * 36根据多个用户账号(逗号分隔),查询返回多个用户信息
  446 + * @param usernames
  447 + * @return
  448 + */
  449 + @RequestMapping("/queryUsersByUsernames")
  450 + List<JSONObject> queryUsersByUsernames(@RequestParam("usernames") String usernames){
  451 + return this.sysBaseApi.queryUsersByUsernames(usernames);
  452 + }
  453 +
  454 + /**
  455 + * 37根据多个用户id(逗号分隔),查询返回多个用户信息
  456 + * @param ids
  457 + * @return
  458 + */
  459 + @RequestMapping("/queryUsersByIds")
  460 + List<JSONObject> queryUsersByIds(@RequestParam("ids") String ids){
  461 + return this.sysBaseApi.queryUsersByIds(ids);
  462 + }
  463 +
  464 + /**
  465 + * 38根据多个部门编码(逗号分隔),查询返回多个部门信息
  466 + * @param orgCodes
  467 + * @return
  468 + */
  469 + @GetMapping("/queryDepartsByOrgcodes")
  470 + List<JSONObject> queryDepartsByOrgcodes(@RequestParam("orgCodes") String orgCodes){
  471 + return this.sysBaseApi.queryDepartsByOrgcodes(orgCodes);
  472 + }
  473 +
  474 + /**
  475 + * 39根据多个部门ID(逗号分隔),查询返回多个部门信息
  476 + * @param ids
  477 + * @return
  478 + */
  479 + @GetMapping("/queryDepartsByIds")
  480 + List<JSONObject> queryDepartsByIds(@RequestParam("ids") String ids){
  481 + return this.sysBaseApi.queryDepartsByIds(ids);
  482 + }
  483 +
  484 + /**
  485 + * 40发送邮件消息
  486 + * @param email
  487 + * @param title
  488 + * @param content
  489 + */
  490 + @GetMapping("/sendEmailMsg")
  491 + public void sendEmailMsg(@RequestParam("email")String email,@RequestParam("title")String title,@RequestParam("content")String content){
  492 + this.sysBaseApi.sendEmailMsg(email,title,content);
  493 + };
  494 + /**
  495 + * 41 获取公司下级部门和公司下所有用户信息
  496 + * @param orgCode
  497 + */
  498 + @GetMapping("/getDeptUserByOrgCode")
  499 + List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode){
  500 + return this.sysBaseApi.getDeptUserByOrgCode(orgCode);
  501 + }
  502 +
  503 + /**
  504 + * 查询分类字典翻译
  505 + *
  506 + * @param ids 分类字典表id
  507 + * @return
  508 + */
  509 + @GetMapping("/loadCategoryDictItem")
  510 + public List<String> loadCategoryDictItem(@RequestParam("ids") String ids) {
  511 + return sysBaseApi.loadCategoryDictItem(ids);
  512 + }
  513 +
  514 + /**
  515 + * 根据字典code加载字典text
  516 + *
  517 + * @param dictCode 顺序:tableName,text,code
  518 + * @param keys 要查询的key
  519 + * @return
  520 + */
  521 + @GetMapping("/loadDictItem")
  522 + public List<String> loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys) {
  523 + return sysBaseApi.loadDictItem(dictCode, keys);
  524 + }
  525 +
  526 + /**
  527 + * 根据字典code查询字典项
  528 + *
  529 + * @param dictCode 顺序:tableName,text,code
  530 + * @param dictCode 要查询的key
  531 + * @return
  532 + */
  533 + @GetMapping("/getDictItems")
  534 + public List<DictModel> getDictItems(@RequestParam("dictCode") String dictCode) {
  535 + return sysBaseApi.getDictItems(dictCode);
  536 + }
  537 +
  538 + /**
  539 + * 根据多个字典code查询多个字典项
  540 + *
  541 + * @param dictCodeList
  542 + * @return key = dictCode ; value=对应的字典项
  543 + */
  544 + @RequestMapping("/getManyDictItems")
  545 + public Map<String, List<DictModel>> getManyDictItems(@RequestParam("dictCodeList") List<String> dictCodeList) {
  546 + return sysBaseApi.getManyDictItems(dictCodeList);
  547 + }
  548 +
  549 + /**
  550 + * 【下拉搜索】
  551 + * 大数据量的字典表 走异步加载,即前端输入内容过滤数据
  552 + *
  553 + * @param dictCode 字典code格式:table,text,code
  554 + * @param keyword 过滤关键字
  555 + * @return
  556 + */
  557 + @GetMapping("/loadDictItemByKeyword")
  558 + public List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize) {
  559 + return sysBaseApi.loadDictItemByKeyword(dictCode, keyword, pageSize);
  560 + }
  561 +
  562 + /**
  563 + * 48 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割
  564 + * @param dictCodes
  565 + * @param keys
  566 + * @return
  567 + */
  568 + @GetMapping("/translateManyDict")
  569 + public Map<String, List<DictModel>> translateManyDict(@RequestParam("dictCodes") String dictCodes, @RequestParam("keys") String keys){
  570 + return this.sysBaseApi.translateManyDict(dictCodes, keys);
  571 + }
  572 +
  573 +
  574 + /**
  575 + * 获取表数据字典 【接口签名验证】
  576 + * @param table
  577 + * @param text
  578 + * @param code
  579 + * @return
  580 + */
  581 + @GetMapping("/queryTableDictItemsByCode")
  582 + List<DictModel> queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code){
  583 + return sysBaseApi.queryTableDictItemsByCode(table, text, code);
  584 + }
  585 +
  586 + /**
  587 + * 查询表字典 支持过滤数据 【接口签名验证】
  588 + * @param table
  589 + * @param text
  590 + * @param code
  591 + * @param filterSql
  592 + * @return
  593 + */
  594 + @GetMapping("/queryFilterTableDictInfo")
  595 + List<DictModel> queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql){
  596 + return sysBaseApi.queryFilterTableDictInfo(table, text, code, filterSql);
  597 + }
  598 +
  599 + /**
  600 + * 【接口签名验证】
  601 + * 查询指定table的 text code 获取字典,包含text和value
  602 + * @param table
  603 + * @param text
  604 + * @param code
  605 + * @param keyArray
  606 + * @return
  607 + */
  608 + @Deprecated
  609 + @GetMapping("/queryTableDictByKeys")
  610 + public List<String> queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray){
  611 + return sysBaseApi.queryTableDictByKeys(table, text, code, keyArray);
  612 + }
  613 +
  614 +
  615 + /**
  616 + * 字典表的 翻译【接口签名验证】
  617 + * @param table
  618 + * @param text
  619 + * @param code
  620 + * @param key
  621 + * @return
  622 + */
  623 + @GetMapping("/translateDictFromTable")
  624 + public String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key){
  625 + return sysBaseApi.translateDictFromTable(table, text, code, key);
  626 + }
  627 +
  628 +
  629 + /**
  630 + * 【接口签名验证】
  631 + * 49 字典表的 翻译,可批量
  632 + *
  633 + * @param table
  634 + * @param text
  635 + * @param code
  636 + * @param keys 多个用逗号分割
  637 + * @return
  638 + */
  639 + @GetMapping("/translateDictFromTableByKeys")
  640 + public List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys) {
  641 + return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys);
  642 + }
  643 +
  644 + /**
  645 + * 发送模板信息
  646 + * @param message
  647 + */
  648 + @PostMapping("/sendTemplateMessage")
  649 + public void sendTemplateMessage(@RequestBody MessageDTO message){
  650 + sysBaseApi.sendTemplateMessage(message);
  651 + }
  652 +
  653 + /**
  654 + * 获取消息模板内容
  655 + * @param code
  656 + * @return
  657 + */
  658 + @GetMapping("/getTemplateContent")
  659 + public String getTemplateContent(@RequestParam("code") String code){
  660 + return this.sysBaseApi.getTemplateContent(code);
  661 + }
  662 +
  663 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java
... ... @@ -5,21 +5,17 @@ import java.util.List;
5 5 import javax.servlet.http.HttpServletRequest;
6 6 import javax.servlet.http.HttpServletResponse;
7 7  
8   -import cn.hutool.crypto.SecureUtil;
9 8 import org.apache.commons.lang.StringUtils;
10 9 import org.jeecg.common.api.vo.Result;
11   -import org.jeecg.common.constant.CacheConstant;
12 10 import org.jeecg.common.constant.CommonConstant;
13 11 import org.jeecg.common.system.util.JwtUtil;
14   -import org.jeecg.common.system.vo.LoginUser;
15 12 import org.jeecg.common.util.RedisUtil;
16   -import org.jeecg.modules.cas.util.CASServiceUtil;
  13 +import org.jeecg.modules.cas.util.CasServiceUtil;
17 14 import org.jeecg.modules.cas.util.XmlUtils;
18 15 import org.jeecg.modules.system.entity.SysDepart;
19 16 import org.jeecg.modules.system.entity.SysUser;
20 17 import org.jeecg.modules.system.service.ISysDepartService;
21 18 import org.jeecg.modules.system.service.ISysUserService;
22   -import org.springframework.beans.BeanUtils;
23 19 import org.springframework.beans.factory.annotation.Autowired;
24 20 import org.springframework.beans.factory.annotation.Value;
25 21 import org.springframework.http.HttpEntity;
... ... @@ -65,7 +61,7 @@ public class CasClientController {
65 61 log.info("Rest api login.");
66 62 try {
67 63 String validateUrl = prefixUrl+"/p3/serviceValidate";
68   - String res = CASServiceUtil.getSTValidate(validateUrl, ticket, service);
  64 + String res = CasServiceUtil.getStValidate(validateUrl, ticket, service);
69 65 log.info("res."+res);
70 66 final String error = XmlUtils.getTextForElement(res, "authenticationFailure");
71 67 if(StringUtils.isNotEmpty(error)) {
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/util/CasServiceUtil.java 0 → 100644
  1 +package org.jeecg.modules.cas.util;
  2 +
  3 +import java.io.BufferedReader;
  4 +import java.io.IOException;
  5 +import java.io.InputStreamReader;
  6 +import java.security.cert.X509Certificate;
  7 +
  8 +import javax.net.ssl.SSLContext;
  9 +import javax.net.ssl.TrustManager;
  10 +import javax.net.ssl.X509TrustManager;
  11 +
  12 +import org.apache.http.HttpResponse;
  13 +import org.apache.http.client.methods.HttpGet;
  14 +import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
  15 +import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  16 +import org.apache.http.impl.client.CloseableHttpClient;
  17 +import org.apache.http.impl.client.HttpClients;
  18 +
  19 +/**
  20 + * @Description: CasServiceUtil
  21 + * @author: jeecg-boot
  22 + */
  23 +public class CasServiceUtil {
  24 +
  25 + public static void main(String[] args) {
  26 + String serviceUrl = "https://cas.8f8.com.cn:8443/cas/p3/serviceValidate";
  27 + String service = "http://localhost:3003/user/login";
  28 + String ticket = "ST-5-1g-9cNES6KXNRwq-GuRET103sm0-DESKTOP-VKLS8B3";
  29 + String res = getStValidate(serviceUrl,ticket, service);
  30 +
  31 + System.out.println("---------res-----"+res);
  32 + }
  33 +
  34 +
  35 + /**
  36 + * 验证ST
  37 + */
  38 + public static String getStValidate(String url, String st, String service){
  39 + try {
  40 + url = url+"?service="+service+"&ticket="+st;
  41 + CloseableHttpClient httpclient = createHttpClientWithNoSsl();
  42 + HttpGet httpget = new HttpGet(url);
  43 + HttpResponse response = httpclient.execute(httpget);
  44 + String res = readResponse(response);
  45 + return res == null ? null : (res == "" ? null : res);
  46 + } catch (Exception e) {
  47 + e.printStackTrace();
  48 + }
  49 + return "";
  50 + }
  51 +
  52 +
  53 + /**
  54 + * 读取 response body 内容为字符串
  55 + *
  56 + * @param response
  57 + * @return
  58 + * @throws IOException
  59 + */
  60 + private static String readResponse(HttpResponse response) throws IOException {
  61 + BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
  62 + String result = new String();
  63 + String line;
  64 + while ((line = in.readLine()) != null) {
  65 + result += line;
  66 + }
  67 + return result;
  68 + }
  69 +
  70 +
  71 + /**
  72 + * 创建模拟客户端(针对 https 客户端禁用 SSL 验证)
  73 + *
  74 + * @param cookieStore 缓存的 Cookies 信息
  75 + * @return
  76 + * @throws Exception
  77 + */
  78 + private static CloseableHttpClient createHttpClientWithNoSsl() throws Exception {
  79 + // Create a trust manager that does not validate certificate chains
  80 + TrustManager[] trustAllCerts = new TrustManager[]{
  81 + new X509TrustManager() {
  82 + @Override
  83 + public X509Certificate[] getAcceptedIssuers() {
  84 + return null;
  85 + }
  86 +
  87 + @Override
  88 + public void checkClientTrusted(X509Certificate[] certs, String authType) {
  89 + // don't check
  90 + }
  91 +
  92 + @Override
  93 + public void checkServerTrusted(X509Certificate[] certs, String authType) {
  94 + // don't check
  95 + }
  96 + }
  97 + };
  98 +
  99 + SSLContext ctx = SSLContext.getInstance("TLS");
  100 + ctx.init(null, trustAllCerts, null);
  101 + LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(ctx);
  102 + return HttpClients.custom()
  103 + .setSSLSocketFactory(sslSocketFactory)
  104 + .build();
  105 + }
  106 +
  107 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/util/XmlUtils.java
... ... @@ -14,6 +14,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
14 14 import javax.xml.parsers.ParserConfigurationException;
15 15 import javax.xml.parsers.SAXParser;
16 16 import javax.xml.parsers.SAXParserFactory;
  17 +import org.jeecg.common.constant.CommonConstant;
17 18 import org.w3c.dom.Document;
18 19 import org.xml.sax.Attributes;
19 20 import org.xml.sax.InputSource;
... ... @@ -31,6 +32,11 @@ import lombok.extern.slf4j.Slf4j;
31 32 public final class XmlUtils {
32 33  
33 34 /**
  35 + * attributes
  36 + */
  37 + private static final String ATTRIBUTES = "attributes";
  38 +
  39 + /**
34 40 * Creates a new namespace-aware DOM document object by parsing the given XML.
35 41 *
36 42 * @param xml XML content.
... ... @@ -218,9 +224,9 @@ public final class XmlUtils {
218 224 }
219 225  
220 226 @Override
221   - public void startElement(final String namespaceURI, final String localName, final String qName,
222   - final Attributes attributes) throws SAXException {
223   - if ("attributes".equals(localName)) {
  227 + public void startElement(final String nameSpaceUri, final String localName, final String qName,
  228 + final Attributes attributes) throws SAXException {
  229 + if (ATTRIBUTES.equals(localName)) {
224 230 this.foundAttributes = true;
225 231 } else if (this.foundAttributes) {
226 232 this.value = new StringBuilder();
... ... @@ -236,9 +242,9 @@ public final class XmlUtils {
236 242 }
237 243  
238 244 @Override
239   - public void endElement(final String namespaceURI, final String localName, final String qName)
  245 + public void endElement(final String nameSpaceUri, final String localName, final String qName)
240 246 throws SAXException {
241   - if ("attributes".equals(localName)) {
  247 + if (ATTRIBUTES.equals(localName)) {
242 248 this.foundAttributes = false;
243 249 this.currentAttribute = null;
244 250 } else if (this.foundAttributes) {
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/controller/SysMessageTemplateController.java
... ... @@ -6,9 +6,12 @@ import java.util.Map;
6 6 import javax.servlet.http.HttpServletRequest;
7 7 import javax.servlet.http.HttpServletResponse;
8 8  
  9 +import org.jeecg.common.api.dto.message.MessageDTO;
9 10 import org.jeecg.common.api.vo.Result;
  11 +import org.jeecg.common.system.api.ISysBaseAPI;
10 12 import org.jeecg.common.system.base.controller.JeecgController;
11 13 import org.jeecg.common.system.query.QueryGenerator;
  14 +import org.jeecg.common.util.oConvertUtils;
12 15 import org.jeecg.modules.message.entity.MsgParams;
13 16 import org.jeecg.modules.message.entity.SysMessageTemplate;
14 17 import org.jeecg.modules.message.service.ISysMessageTemplateService;
... ... @@ -46,6 +49,9 @@ public class SysMessageTemplateController extends JeecgController&lt;SysMessageTemp
46 49 @Autowired
47 50 private PushMsgUtil pushMsgUtil;
48 51  
  52 + @Autowired
  53 + private ISysBaseAPI sysBaseApi;
  54 +
49 55 /**
50 56 * 分页列表查询
51 57 *
... ... @@ -152,19 +158,23 @@ public class SysMessageTemplateController extends JeecgController&lt;SysMessageTemp
152 158 @PostMapping(value = "/sendMsg")
153 159 public Result<SysMessageTemplate> sendMessage(@RequestBody MsgParams msgParams) {
154 160 Result<SysMessageTemplate> result = new Result<SysMessageTemplate>();
155   - Map<String, String> map = null;
156 161 try {
157   - map = (Map<String, String>) JSON.parse(msgParams.getTestData());
  162 + MessageDTO md = new MessageDTO();
  163 + md.setToAll(false);
  164 + md.setTitle("消息发送测试");
  165 + md.setTemplateCode(msgParams.getTemplateCode());
  166 + md.setToUser(msgParams.getReceiver());
  167 + md.setType(msgParams.getMsgType());
  168 + String testData = msgParams.getTestData();
  169 + if(oConvertUtils.isNotEmpty(testData)){
  170 + Map<String, Object> data = JSON.parseObject(testData, Map.class);
  171 + md.setData(data);
  172 + }
  173 + sysBaseApi.sendTemplateMessage(md);
  174 + return result.success("消息发送成功!");
158 175 } catch (Exception e) {
159   - result.error500("解析Json出错!");
160   - return result;
161   - }
162   - boolean is_sendSuccess = pushMsgUtil.sendMessage(msgParams.getMsgType(), msgParams.getTemplateCode(), map, msgParams.getReceiver());
163   - if (is_sendSuccess) {
164   - result.success("发送消息任务添加成功!");
165   - } else {
166   - result.error500("发送消息任务添加失败!");
  176 + log.error("发送消息出错", e.getMessage());
  177 + return result.error500("发送消息出错!");
167 178 }
168   - return result;
169 179 }
170 180 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessage.java
... ... @@ -50,9 +50,11 @@ public class SysMessage extends JeecgEntity {
50 50 /**消息标题*/
51 51 @Excel(name = "消息标题", width = 15)
52 52 private java.lang.String esTitle;
53   - /**推送方式:1短信 2邮件 3微信*/
54   - @Excel(name = "推送方式:1短信 2邮件 3微信", width = 15)
55   - @Dict(dicCode = "msgType")
  53 + /**
  54 + * 推送方式:参考枚举类MessageTypeEnum
  55 + */
  56 + @Excel(name = "推送方式", width = 15)
  57 + @Dict(dicCode = "messageType")
56 58 private java.lang.String esType;
57 59 /**备注*/
58 60 @Excel(name = "备注", width = 15)
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessageTemplate.java
... ... @@ -35,4 +35,9 @@ public class SysMessageTemplate extends JeecgEntity{
35 35 /**模板类型*/
36 36 @Excel(name = "模板类型", width = 15)
37 37 private java.lang.String templateType;
  38 +
  39 + /**已经应用/未应用 1是0否*/
  40 + @Excel(name = "应用状态", width = 15)
  41 + private String useStatus;
  42 +
38 43 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/ISendMsgHandle.java
1 1 package org.jeecg.modules.message.handle;
2 2  
  3 +import org.jeecg.common.api.dto.message.MessageDTO;
  4 +
3 5 /**
4 6 * @Description: 发送信息接口
5 7 * @author: jeecg-boot
... ... @@ -8,9 +10,17 @@ public interface ISendMsgHandle {
8 10  
9 11 /**
10 12 * 发送信息
11   - * @param es_receiver 发送人
12   - * @param es_title 标题
13   - * @param es_content 内容
  13 + * @param esReceiver 发送人
  14 + * @param esTitle 标题
  15 + * @param esContent 内容
  16 + */
  17 + void sendMsg(String esReceiver, String esTitle, String esContent);
  18 +
  19 + /**
  20 + * 发送信息
  21 + * @param messageDTO
14 22 */
15   - void SendMsg(String es_receiver, String es_title, String es_content);
  23 + default void sendMessage(MessageDTO messageDTO){
  24 +
  25 + }
16 26 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/DdSendMsgHandle.java 0 → 100644
  1 +package org.jeecg.modules.message.handle.impl;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.jeecg.common.api.dto.message.MessageDTO;
  5 +import org.jeecg.modules.message.handle.ISendMsgHandle;
  6 +import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +/**
  11 + * @Description: 发钉钉消息模板
  12 + * @author: jeecg-boot
  13 + */
  14 +@Slf4j
  15 +@Component("ddSendMsgHandle")
  16 +public class DdSendMsgHandle implements ISendMsgHandle {
  17 +
  18 + @Autowired
  19 + private ThirdAppDingtalkServiceImpl dingtalkService;
  20 +
  21 + @Override
  22 + public void sendMsg(String esReceiver, String esTitle, String esContent) {
  23 + log.info("发微信消息模板");
  24 + MessageDTO messageDTO = new MessageDTO();
  25 + messageDTO.setToUser(esReceiver);
  26 + messageDTO.setTitle(esTitle);
  27 + messageDTO.setContent(esContent);
  28 + messageDTO.setToAll(false);
  29 + sendMessage(messageDTO);
  30 + }
  31 +
  32 + @Override
  33 + public void sendMessage(MessageDTO messageDTO) {
  34 + dingtalkService.sendMessage(messageDTO, true);
  35 + }
  36 +
  37 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/EmailSendMsgHandle.java
1 1 package org.jeecg.modules.message.handle.impl;
2 2  
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import lombok.extern.slf4j.Slf4j;
  5 +import org.jeecg.common.api.dto.message.MessageDTO;
  6 +import org.jeecg.common.constant.CommonConstant;
  7 +import org.jeecg.common.system.util.JwtUtil;
  8 +import org.jeecg.common.util.RedisUtil;
3 9 import org.jeecg.common.util.SpringContextUtils;
4 10 import org.jeecg.common.util.oConvertUtils;
5 11 import org.jeecg.config.StaticConfig;
6 12 import org.jeecg.modules.message.handle.ISendMsgHandle;
7   -import org.springframework.mail.SimpleMailMessage;
  13 +import org.jeecg.modules.system.entity.SysUser;
  14 +import org.jeecg.modules.system.mapper.SysUserMapper;
  15 +import org.springframework.beans.factory.annotation.Autowired;
8 16 import org.springframework.mail.javamail.JavaMailSender;
9 17 import org.springframework.mail.javamail.MimeMessageHelper;
  18 +import org.springframework.stereotype.Component;
10 19  
11 20 import javax.mail.MessagingException;
12 21 import javax.mail.internet.MimeMessage;
  22 +import java.io.UnsupportedEncodingException;
  23 +import java.net.URLEncoder;
  24 +import java.util.List;
13 25  
14 26 /**
15 27 * @Description: 邮箱发送信息
16 28 * @author: jeecg-boot
17 29 */
  30 +@Slf4j
  31 +@Component("emailSendMsgHandle")
18 32 public class EmailSendMsgHandle implements ISendMsgHandle {
19 33 static String emailFrom;
20 34  
... ... @@ -22,8 +36,16 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
22 36 EmailSendMsgHandle.emailFrom = emailFrom;
23 37 }
24 38  
  39 + @Autowired
  40 + SysUserMapper sysUserMapper;
  41 +
  42 + @Autowired
  43 + private RedisUtil redisUtil;
  44 +
  45 +
  46 +
25 47 @Override
26   - public void SendMsg(String es_receiver, String es_title, String es_content) {
  48 + public void sendMsg(String esReceiver, String esTitle, String esContent) {
27 49 JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender");
28 50 MimeMessage message = mailSender.createMimeMessage();
29 51 MimeMessageHelper helper = null;
... ... @@ -37,13 +59,53 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
37 59 helper = new MimeMessageHelper(message, true);
38 60 // 设置发送方邮箱地址
39 61 helper.setFrom(emailFrom);
40   - helper.setTo(es_receiver);
41   - helper.setSubject(es_title);
42   - helper.setText(es_content, true);
  62 + helper.setTo(esReceiver);
  63 + helper.setSubject(esTitle);
  64 + helper.setText(esContent, true);
43 65 mailSender.send(message);
44 66 } catch (MessagingException e) {
45 67 e.printStackTrace();
46 68 }
47 69  
48 70 }
  71 +
  72 + @Override
  73 + public void sendMessage(MessageDTO messageDTO) {
  74 + String[] arr = messageDTO.getToUser().split(",");
  75 + LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<SysUser>().in(SysUser::getUsername, arr);
  76 + List<SysUser> list = sysUserMapper.selectList(query);
  77 + String content = messageDTO.getContent();
  78 + String title = messageDTO.getTitle();
  79 + for(SysUser user: list){
  80 + String email = user.getEmail();
  81 + if(email==null || "".equals(email)){
  82 + continue;
  83 + }
  84 +
  85 + if(content.indexOf(CommonConstant.LOGIN_TOKEN)>0){
  86 + String token = getToken(user);
  87 + try {
  88 + content = content.replace(CommonConstant.LOGIN_TOKEN, URLEncoder.encode(token, "UTF-8"));
  89 + } catch (UnsupportedEncodingException e) {
  90 + log.error("邮件消息token编码失败", e.getMessage());
  91 + }
  92 + }
  93 + log.info("邮件内容:"+ content);
  94 + sendMsg(email, title, content);
  95 + }
  96 + }
  97 +
  98 + /**
  99 + * 获取token
  100 + * @param user
  101 + * @return
  102 + */
  103 + private String getToken(SysUser user) {
  104 + // 生成token
  105 + String token = JwtUtil.sign(user.getUsername(), user.getPassword());
  106 + redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
  107 + // 设置超时时间 1个小时
  108 + redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 1 / 1000);
  109 + return token;
  110 + }
49 111 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/QywxSendMsgHandle.java 0 → 100644
  1 +package org.jeecg.modules.message.handle.impl;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.jeecg.common.api.dto.message.MessageDTO;
  5 +import org.jeecg.modules.message.handle.ISendMsgHandle;
  6 +import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +/**
  11 + * @Description: 发企业微信消息模板
  12 + * @author: jeecg-boot
  13 + */
  14 +@Slf4j
  15 +@Component("qywxSendMsgHandle")
  16 +public class QywxSendMsgHandle implements ISendMsgHandle {
  17 +
  18 + @Autowired
  19 + private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
  20 +
  21 + @Override
  22 + public void sendMsg(String esReceiver, String esTitle, String esContent) {
  23 + log.info("发微信消息模板");
  24 + MessageDTO messageDTO = new MessageDTO();
  25 + messageDTO.setToUser(esReceiver);
  26 + messageDTO.setTitle(esTitle);
  27 + messageDTO.setContent(esContent);
  28 + messageDTO.setToAll(false);
  29 + sendMessage(messageDTO);
  30 + }
  31 +
  32 + @Override
  33 + public void sendMessage(MessageDTO messageDTO) {
  34 + wechatEnterpriseService.sendMessage(messageDTO, true);
  35 + }
  36 +
  37 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SmsSendMsgHandle.java
... ... @@ -11,7 +11,7 @@ import org.jeecg.modules.message.handle.ISendMsgHandle;
11 11 public class SmsSendMsgHandle implements ISendMsgHandle {
12 12  
13 13 @Override
14   - public void SendMsg(String es_receiver, String es_title, String es_content) {
  14 + public void sendMsg(String esReceiver, String esTitle, String esContent) {
15 15 // TODO Auto-generated method stub
16 16 log.info("发短信");
17 17 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SystemSendMsgHandle.java
1 1 package org.jeecg.modules.message.handle.impl;
2 2  
  3 +import com.alibaba.fastjson.JSONObject;
3 4 import org.jeecg.common.api.dto.message.MessageDTO;
  5 +import org.jeecg.common.constant.CommonConstant;
  6 +import org.jeecg.common.constant.WebsocketConst;
4 7 import org.jeecg.common.exception.JeecgBootException;
5 8 import org.jeecg.common.system.api.ISysBaseAPI;
6 9 import org.jeecg.common.util.SpringContextUtils;
7 10 import org.jeecg.common.util.oConvertUtils;
8 11 import org.jeecg.modules.message.handle.ISendMsgHandle;
  12 +import org.jeecg.modules.message.websocket.WebSocket;
  13 +import org.jeecg.modules.system.entity.SysAnnouncement;
  14 +import org.jeecg.modules.system.entity.SysAnnouncementSend;
  15 +import org.jeecg.modules.system.entity.SysUser;
  16 +import org.jeecg.modules.system.mapper.SysAnnouncementMapper;
  17 +import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
  18 +import org.jeecg.modules.system.mapper.SysUserMapper;
  19 +import org.springframework.stereotype.Component;
  20 +
  21 +import javax.annotation.Resource;
  22 +import java.util.Date;
  23 +import java.util.Map;
9 24  
10 25 /**
11 26 * @Description: 发送系统消息
12 27 * @Author: wangshuai
13 28 * @Date: 2022年3月22日 18:48:20
14 29 */
  30 +@Component("systemSendMsgHandle")
15 31 public class SystemSendMsgHandle implements ISendMsgHandle {
16 32  
17 33 public static final String FROM_USER="system";
18 34  
  35 + @Resource
  36 + private SysAnnouncementMapper sysAnnouncementMapper;
  37 +
  38 + @Resource
  39 + private SysUserMapper userMapper;
  40 +
  41 + @Resource
  42 + private SysAnnouncementSendMapper sysAnnouncementSendMapper;
  43 +
  44 + @Resource
  45 + private WebSocket webSocket;
  46 +
  47 + /**
  48 + * 该方法会发送3种消息:系统消息、企业微信 钉钉
  49 + * @param esReceiver 发送人
  50 + * @param esTitle 标题
  51 + * @param esContent 内容
  52 + */
19 53 @Override
20   - public void SendMsg(String es_receiver, String es_title, String es_content) {
21   - if(oConvertUtils.isEmpty(es_receiver)){
  54 + public void sendMsg(String esReceiver, String esTitle, String esContent) {
  55 + if(oConvertUtils.isEmpty(esReceiver)){
22 56 throw new JeecgBootException("被发送人不能为空");
23 57 }
24   - ISysBaseAPI sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class);
25   - MessageDTO messageDTO = new MessageDTO(FROM_USER,es_receiver,es_title,es_content);
26   - sysBaseAPI.sendSysAnnouncement(messageDTO);
  58 + ISysBaseAPI sysBaseApi = SpringContextUtils.getBean(ISysBaseAPI.class);
  59 + MessageDTO messageDTO = new MessageDTO(FROM_USER,esReceiver,esTitle,esContent);
  60 + sysBaseApi.sendSysAnnouncement(messageDTO);
  61 + }
  62 +
  63 + /**
  64 + * 仅发送系统消息
  65 + * @param messageDTO
  66 + */
  67 + @Override
  68 + public void sendMessage(MessageDTO messageDTO) {
  69 + //原方法不支持 sysBaseApi.sendSysAnnouncement(messageDTO); 有企业微信消息逻辑,
  70 + String title = messageDTO.getTitle();
  71 + String content = messageDTO.getContent();
  72 + String fromUser = messageDTO.getFromUser();
  73 + Map<String,Object> data = messageDTO.getData();
  74 + String[] arr = messageDTO.getToUser().split(",");
  75 + for(String username: arr){
  76 + doSend(title, content, fromUser, username, data);
  77 + }
  78 + }
  79 +
  80 + private void doSend(String title, String msgContent, String fromUser, String toUser, Map<String, Object> data){
  81 + SysAnnouncement announcement = new SysAnnouncement();
  82 + if(data!=null){
  83 + //摘要信息
  84 + Object msgAbstract = data.get(CommonConstant.NOTICE_MSG_SUMMARY);
  85 + if(msgAbstract!=null){
  86 + announcement.setMsgAbstract(msgAbstract.toString());
  87 + }
  88 + // 任务节点ID
  89 + Object taskId = data.get(CommonConstant.NOTICE_MSG_BUS_ID);
  90 + if(taskId!=null){
  91 + announcement.setBusId(taskId.toString());
  92 + }
  93 + }
  94 + announcement.setTitile(title);
  95 + announcement.setMsgContent(msgContent);
  96 + announcement.setSender(fromUser);
  97 + announcement.setPriority(CommonConstant.PRIORITY_M);
  98 + announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
  99 + announcement.setSendStatus(CommonConstant.HAS_SEND);
  100 + announcement.setSendTime(new Date());
  101 + //系统消息
  102 + announcement.setMsgCategory("2");
  103 + announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
  104 + sysAnnouncementMapper.insert(announcement);
  105 + // 2.插入用户通告阅读标记表记录
  106 + String userId = toUser;
  107 + String[] userIds = userId.split(",");
  108 + String anntId = announcement.getId();
  109 + for(int i=0;i<userIds.length;i++) {
  110 + if(oConvertUtils.isNotEmpty(userIds[i])) {
  111 + SysUser sysUser = userMapper.getUserByName(userIds[i]);
  112 + if(sysUser==null) {
  113 + continue;
  114 + }
  115 + SysAnnouncementSend announcementSend = new SysAnnouncementSend();
  116 + announcementSend.setAnntId(anntId);
  117 + announcementSend.setUserId(sysUser.getId());
  118 + announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
  119 + sysAnnouncementSendMapper.insert(announcementSend);
  120 + JSONObject obj = new JSONObject();
  121 + obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
  122 + obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
  123 + obj.put(WebsocketConst.MSG_ID, announcement.getId());
  124 + obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
  125 + webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
  126 + }
  127 + }
27 128 }
28 129 }
29 130 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/WxSendMsgHandle.java
... ... @@ -11,7 +11,7 @@ import org.jeecg.modules.message.handle.ISendMsgHandle;
11 11 public class WxSendMsgHandle implements ISendMsgHandle {
12 12  
13 13 @Override
14   - public void SendMsg(String es_receiver, String es_title, String es_content) {
  14 + public void sendMsg(String esReceiver, String esTitle, String esContent) {
15 15 // TODO Auto-generated method stub
16 16 log.info("发微信消息模板");
17 17 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/job/SendMsgJob.java
1 1 package org.jeecg.modules.message.job;
2 2  
3   -import java.util.List;
4   -
  3 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  4 +import lombok.extern.slf4j.Slf4j;
  5 +import org.jeecg.common.api.dto.message.MessageDTO;
  6 +import org.jeecg.common.system.api.ISysBaseAPI;
5 7 import org.jeecg.common.util.DateUtils;
6 8 import org.jeecg.modules.message.entity.SysMessage;
7   -import org.jeecg.modules.message.handle.ISendMsgHandle;
8 9 import org.jeecg.modules.message.handle.enums.SendMsgStatusEnum;
9   -import org.jeecg.modules.message.handle.enums.SendMsgTypeEnum;
10 10 import org.jeecg.modules.message.service.ISysMessageService;
11 11 import org.quartz.Job;
12 12 import org.quartz.JobExecutionContext;
13 13 import org.quartz.JobExecutionException;
14 14 import org.springframework.beans.factory.annotation.Autowired;
15 15  
16   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
17   -
18   -import lombok.extern.slf4j.Slf4j;
  16 +import java.util.List;
19 17  
20 18 /**
21 19 * 发送消息任务
... ... @@ -28,6 +26,9 @@ public class SendMsgJob implements Job {
28 26 @Autowired
29 27 private ISysMessageService sysMessageService;
30 28  
  29 + @Autowired
  30 + private ISysBaseAPI sysBaseAPI;
  31 +
31 32 @Override
32 33 public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
33 34  
... ... @@ -41,32 +42,19 @@ public class SendMsgJob implements Job {
41 42 System.out.println(sysMessages);
42 43 // 2.根据不同的类型走不通的发送实现类
43 44 for (SysMessage sysMessage : sysMessages) {
44   - ISendMsgHandle sendMsgHandle = null;
45   - try {
46   - if (sysMessage.getEsType().equals(SendMsgTypeEnum.EMAIL.getType())) {
47   - sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.EMAIL.getImplClass()).newInstance();
48   - } else if (sysMessage.getEsType().equals(SendMsgTypeEnum.SMS.getType())) {
49   - sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.SMS.getImplClass()).newInstance();
50   - } else if (sysMessage.getEsType().equals(SendMsgTypeEnum.WX.getType())) {
51   - sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.WX.getImplClass()).newInstance();
52   - } else if(sysMessage.getEsType().equals(SendMsgTypeEnum.SYSTEM_MESSAGE.getType())){
53   - //update-begin---author:wangshuai ---date:20220323 for:[issues/I4X698]根据模板发送系统消息,发送失败------------
54   - sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.SYSTEM_MESSAGE.getImplClass()).newInstance();
55   - //update-end---author:wangshuai ---date:20220323 for:[issues/I4X698]根据模板发送系统消息,发送失败------------
56   - }
57   - } catch (Exception e) {
58   - log.error(e.getMessage(),e);
59   - }
  45 + //update-begin-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改
60 46 Integer sendNum = sysMessage.getEsSendNum();
61 47 try {
62   - //update-begin---author:wangshuai ---date:20220323 for:[issues/I4X698]模板管理发送消息出现NullPointerException 錯誤------------
63   - if(null != sendMsgHandle){
64   - sendMsgHandle.SendMsg(sysMessage.getEsReceiver(), sysMessage.getEsTitle(),
65   - sysMessage.getEsContent().toString());
66   - //发送消息成功
67   - sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
68   - }
69   - //update-end---author:wangshuai ---date:20220323 for:[issues/I4X698]模板管理发送消息出现NullPointerException 錯誤------------
  48 + MessageDTO md = new MessageDTO();
  49 + md.setTitle(sysMessage.getEsTitle());
  50 + md.setContent(sysMessage.getEsContent());
  51 + md.setToUser(sysMessage.getEsReceiver());
  52 + md.setType(sysMessage.getEsType());
  53 + md.setToAll(false);
  54 + sysBaseAPI.sendTemplateMessage(md);
  55 + //发送消息成功
  56 + sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
  57 + //update-end-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改
70 58 } catch (Exception e) {
71 59 e.printStackTrace();
72 60 // 发送消息出现异常
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/monitor/service/impl/RedisServiceImpl.java
... ... @@ -12,6 +12,7 @@ import cn.hutool.core.date.DateUtil;
12 12 import com.alibaba.fastjson.JSONArray;
13 13 import com.alibaba.fastjson.JSONObject;
14 14 import com.google.common.collect.Maps;
  15 +import org.jeecg.common.constant.CommonConstant;
15 16 import org.jeecg.common.util.oConvertUtils;
16 17 import org.jeecg.modules.monitor.domain.RedisInfo;
17 18 import org.jeecg.modules.monitor.exception.RedisConnectException;
... ... @@ -34,6 +35,11 @@ public class RedisServiceImpl implements RedisService {
34 35 @Resource
35 36 private RedisConnectionFactory redisConnectionFactory;
36 37  
  38 + /**
  39 + * redis信息
  40 + */
  41 + private static final String REDIS_MESSAGE = "3";
  42 +
37 43 /**
38 44 * Redis详细信息
39 45 */
... ... @@ -88,7 +94,7 @@ public class RedisServiceImpl implements RedisService {
88 94 public Map<String, JSONArray> getMapForReport(String type) throws RedisConnectException {
89 95 Map<String,JSONArray> mapJson=new HashMap(5);
90 96 JSONArray json = new JSONArray();
91   - if("3".equals(type)){
  97 + if(REDIS_MESSAGE.equals(type)){
92 98 List<RedisInfo> redisInfo = getRedisInfo();
93 99 for(RedisInfo info:redisInfo){
94 100 Map<String, Object> map= Maps.newHashMap();
... ... @@ -101,7 +107,8 @@ public class RedisServiceImpl implements RedisService {
101 107 mapJson.put("data",json);
102 108 return mapJson;
103 109 }
104   - for(int i = 0; i < 5; i++){
  110 + int length = 5;
  111 + for(int i = 0; i < length; i++){
105 112 JSONObject jo = new JSONObject();
106 113 Map<String, Object> map;
107 114 if("1".equals(type)){
... ... @@ -109,11 +116,11 @@ public class RedisServiceImpl implements RedisService {
109 116 jo.put("value",map.get("dbSize"));
110 117 }else{
111 118 map = getMemoryInfo();
112   - Integer used_memory = Integer.valueOf(map.get("used_memory").toString());
113   - jo.put("value",used_memory/1000);
  119 + Integer usedMemory = Integer.valueOf(map.get("used_memory").toString());
  120 + jo.put("value",usedMemory/1000);
114 121 }
115   - String create_time = DateUtil.formatTime(DateUtil.date((Long) map.get("create_time")-(4-i)*1000));
116   - jo.put("name",create_time);
  122 + String createTime = DateUtil.formatTime(DateUtil.date((Long) map.get("create_time")-(4-i)*1000));
  123 + jo.put("name",createTime);
117 124 json.add(jo);
118 125 }
119 126 mapJson.put("data",json);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/ngalain/service/impl/NgAlainServiceImpl.java
... ... @@ -2,6 +2,8 @@ package org.jeecg.modules.ngalain.service.impl;
2 2  
3 3 import com.alibaba.fastjson.JSONArray;
4 4 import com.alibaba.fastjson.JSONObject;
  5 +import org.jeecg.common.constant.CommonConstant;
  6 +import org.jeecg.common.constant.SymbolConstant;
5 7 import org.jeecg.common.util.oConvertUtils;
6 8 import org.jeecg.modules.ngalain.service.NgAlainService;
7 9 import org.jeecg.modules.system.entity.SysPermission;
... ... @@ -123,12 +125,13 @@ public class NgAlainServiceImpl implements NgAlainService {
123 125 private JSONObject getPermissionJsonObject(SysPermission permission) {
124 126 JSONObject json = new JSONObject();
125 127 //类型(0:一级菜单 1:子菜单 2:按钮)
126   - if(permission.getMenuType()==2) {
  128 + if(CommonConstant.MENU_TYPE_2.equals(permission.getMenuType())) {
127 129 json.put("action", permission.getPerms());
128 130 json.put("describe", permission.getName());
129   - }else if(permission.getMenuType()==0||permission.getMenuType()==1) {
  131 + }else if(CommonConstant.MENU_TYPE_0.equals(permission.getMenuType()) || CommonConstant.MENU_TYPE_1.equals(permission.getMenuType())) {
130 132 json.put("id", permission.getId());
131   - if(permission.getUrl()!=null&&(permission.getUrl().startsWith("http://")||permission.getUrl().startsWith("https://"))) {
  133 + boolean flag = permission.getUrl()!=null&&(permission.getUrl().startsWith(CommonConstant.HTTP_PROTOCOL)||permission.getUrl().startsWith(CommonConstant.HTTPS_PROTOCOL));
  134 + if(flag) {
132 135 String url= new String(Base64.getUrlEncoder().encode(permission.getUrl().getBytes()));
133 136 json.put("path", "/sys/link/" +url.replaceAll("=",""));
134 137 }else {
... ... @@ -156,7 +159,7 @@ public class NgAlainServiceImpl implements NgAlainService {
156 159 }else {
157 160 meta.put("icon", oConvertUtils.getString(permission.getIcon(), ""));
158 161 }
159   - if(permission.getUrl()!=null&&(permission.getUrl().startsWith("http://")||permission.getUrl().startsWith("https://"))) {
  162 + if(flag) {
160 163 meta.put("url", permission.getUrl());
161 164 }
162 165 json.put("meta", meta);
... ... @@ -172,7 +175,7 @@ public class NgAlainServiceImpl implements NgAlainService {
172 175 */
173 176 private String urlToRouteName(String url) {
174 177 if(oConvertUtils.isNotEmpty(url)) {
175   - if(url.startsWith("/")) {
  178 + if(url.startsWith(SymbolConstant.SINGLE_SLASH)) {
176 179 url = url.substring(1);
177 180 }
178 181 url = url.replace("/", "-");
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/controller/OssFileController.java 0 → 100644
  1 +package org.jeecg.modules.oss.controller;
  2 +
  3 +import javax.servlet.http.HttpServletRequest;
  4 +
  5 +import org.apache.shiro.authz.annotation.RequiresRoles;
  6 +import org.jeecg.common.api.vo.Result;
  7 +import org.jeecg.common.system.query.QueryGenerator;
  8 +import org.jeecg.modules.oss.entity.OssFile;
  9 +import org.jeecg.modules.oss.service.IOssFileService;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.stereotype.Controller;
  12 +import org.springframework.web.bind.annotation.*;
  13 +import org.springframework.web.multipart.MultipartFile;
  14 +
  15 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  16 +import com.baomidou.mybatisplus.core.metadata.IPage;
  17 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  18 +
  19 +import lombok.extern.slf4j.Slf4j;
  20 +
  21 +/**
  22 + * 云存储示例 DEMO
  23 + * @author: jeecg-boot
  24 + */
  25 +@Slf4j
  26 +@Controller
  27 +@RequestMapping("/sys/oss/file")
  28 +public class OssFileController {
  29 +
  30 + @Autowired
  31 + private IOssFileService ossFileService;
  32 +
  33 + @ResponseBody
  34 + @GetMapping("/list")
  35 + public Result<IPage<OssFile>> queryPageList(OssFile file,
  36 + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
  37 + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
  38 + Result<IPage<OssFile>> result = new Result<>();
  39 + QueryWrapper<OssFile> queryWrapper = QueryGenerator.initQueryWrapper(file, req.getParameterMap());
  40 + Page<OssFile> page = new Page<>(pageNo, pageSize);
  41 + IPage<OssFile> pageList = ossFileService.page(page, queryWrapper);
  42 + result.setSuccess(true);
  43 + result.setResult(pageList);
  44 + return result;
  45 + }
  46 +
  47 + @ResponseBody
  48 + @PostMapping("/upload")
  49 + //@RequiresRoles("admin")
  50 + public Result upload(@RequestParam("file") MultipartFile multipartFile) {
  51 + Result result = new Result();
  52 + try {
  53 + ossFileService.upload(multipartFile);
  54 + result.success("上传成功!");
  55 + }
  56 + catch (Exception ex) {
  57 + log.info(ex.getMessage(), ex);
  58 + result.error500("上传失败");
  59 + }
  60 + return result;
  61 + }
  62 +
  63 + @ResponseBody
  64 + @DeleteMapping("/delete")
  65 + public Result delete(@RequestParam(name = "id") String id) {
  66 + Result result = new Result();
  67 + OssFile file = ossFileService.getById(id);
  68 + if (file == null) {
  69 + result.error500("未找到对应实体");
  70 + }else {
  71 + boolean ok = ossFileService.delete(file);
  72 + result.success("删除成功!");
  73 + }
  74 + return result;
  75 + }
  76 +
  77 + /**
  78 + * 通过id查询.
  79 + */
  80 + @ResponseBody
  81 + @GetMapping("/queryById")
  82 + public Result<OssFile> queryById(@RequestParam(name = "id") String id) {
  83 + Result<OssFile> result = new Result<>();
  84 + OssFile file = ossFileService.getById(id);
  85 + if (file == null) {
  86 + result.error500("未找到对应实体");
  87 + }
  88 + else {
  89 + result.setResult(file);
  90 + result.setSuccess(true);
  91 + }
  92 + return result;
  93 + }
  94 +
  95 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/entity/OssFile.java 0 → 100644
  1 +package org.jeecg.modules.oss.entity;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.experimental.Accessors;
  7 +import org.jeecg.common.system.base.entity.JeecgEntity;
  8 +import org.jeecgframework.poi.excel.annotation.Excel;
  9 +
  10 +/**
  11 + * @Description: oss云存储实体类
  12 + * @author: jeecg-boot
  13 + */
  14 +@Data
  15 +@TableName("oss_file")
  16 +@EqualsAndHashCode(callSuper = false)
  17 +@Accessors(chain = true)
  18 +public class OssFile extends JeecgEntity {
  19 +
  20 + private static final long serialVersionUID = 1L;
  21 +
  22 + @Excel(name = "文件名称")
  23 + private String fileName;
  24 +
  25 + @Excel(name = "文件地址")
  26 + private String url;
  27 +
  28 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/mapper/OssFileMapper.java 0 → 100644
  1 +package org.jeecg.modules.oss.mapper;
  2 +
  3 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import org.jeecg.modules.oss.entity.OssFile;
  5 +
  6 +/**
  7 + * @Description: oss云存储Mapper
  8 + * @author: jeecg-boot
  9 + */
  10 +public interface OssFileMapper extends BaseMapper<OssFile> {
  11 +
  12 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/service/IOssFileService.java 0 → 100644
  1 +package org.jeecg.modules.oss.service;
  2 +
  3 +import java.io.IOException;
  4 +
  5 +import com.baomidou.mybatisplus.extension.service.IService;
  6 +import org.jeecg.modules.oss.entity.OssFile;
  7 +import org.springframework.web.multipart.MultipartFile;
  8 +
  9 +/**
  10 + * @Description: OOS云存储service接口
  11 + * @author: jeecg-boot
  12 + */
  13 +public interface IOssFileService extends IService<OssFile> {
  14 +
  15 + /**
  16 + * oss文件上传
  17 + * @param multipartFile
  18 + * @throws IOException
  19 + */
  20 + void upload(MultipartFile multipartFile) throws IOException;
  21 +
  22 + /**
  23 + * oss文件删除
  24 + * @param ossFile OSSFile对象
  25 + * @return
  26 + */
  27 + boolean delete(OssFile ossFile);
  28 +
  29 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/service/impl/OssFileServiceImpl.java 0 → 100644
  1 +package org.jeecg.modules.oss.service.impl;
  2 +
  3 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  4 +import org.jeecg.common.util.CommonUtils;
  5 +import org.jeecg.common.util.oss.OssBootUtil;
  6 +import org.jeecg.modules.oss.entity.OssFile;
  7 +import org.jeecg.modules.oss.mapper.OssFileMapper;
  8 +import org.jeecg.modules.oss.service.IOssFileService;
  9 +import org.springframework.stereotype.Service;
  10 +import org.springframework.web.multipart.MultipartFile;
  11 +
  12 +import java.io.IOException;
  13 +
  14 +/**
  15 + * @Description: OSS云存储实现类
  16 + * @author: jeecg-boot
  17 + */
  18 +@Service("ossFileService")
  19 +public class OssFileServiceImpl extends ServiceImpl<OssFileMapper, OssFile> implements IOssFileService {
  20 +
  21 + @Override
  22 + public void upload(MultipartFile multipartFile) throws IOException {
  23 + String fileName = multipartFile.getOriginalFilename();
  24 + fileName = CommonUtils.getFileName(fileName);
  25 + OssFile ossFile = new OssFile();
  26 + ossFile.setFileName(fileName);
  27 + String url = OssBootUtil.upload(multipartFile,"upload/test");
  28 + //update-begin--Author:scott Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败-------------------
  29 + // 返回阿里云原生域名前缀URL
  30 + ossFile.setUrl(OssBootUtil.getOriginalUrl(url));
  31 + //update-end--Author:scott Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败-------------------
  32 + this.save(ossFile);
  33 + }
  34 +
  35 + @Override
  36 + public boolean delete(OssFile ossFile) {
  37 + try {
  38 + this.removeById(ossFile.getId());
  39 + OssBootUtil.deleteUrl(ossFile.getUrl());
  40 + }
  41 + catch (Exception ex) {
  42 + log.error(ex.getMessage(),ex);
  43 + return false;
  44 + }
  45 + return true;
  46 + }
  47 +
  48 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java
... ... @@ -10,6 +10,7 @@ import org.apache.shiro.SecurityUtils;
10 10 import org.apache.shiro.authz.annotation.RequiresRoles;
11 11 import org.jeecg.common.api.vo.Result;
12 12 import org.jeecg.common.constant.CommonConstant;
  13 +import org.jeecg.common.constant.SymbolConstant;
13 14 import org.jeecg.common.system.query.QueryGenerator;
14 15 import org.jeecg.common.system.vo.LoginUser;
15 16 import org.jeecg.common.util.ImportExcelUtil;
... ... @@ -132,7 +133,7 @@ public class QuartzJobController {
132 133 if (ids == null || "".equals(ids.trim())) {
133 134 return Result.error("参数不识别!");
134 135 }
135   - for (String id : Arrays.asList(ids.split(","))) {
  136 + for (String id : Arrays.asList(ids.split(SymbolConstant.COMMA))) {
136 137 QuartzJob job = quartzJobService.getById(id);
137 138 quartzJobService.deleteAndStopJob(job);
138 139 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/CommonController.java
... ... @@ -5,8 +5,8 @@ import com.alibaba.fastjson.JSONObject;
5 5 import lombok.extern.slf4j.Slf4j;
6 6 import org.jeecg.common.api.vo.Result;
7 7 import org.jeecg.common.constant.CommonConstant;
  8 +import org.jeecg.common.constant.SymbolConstant;
8 9 import org.jeecg.common.exception.JeecgBootException;
9   -import org.jeecg.common.system.api.ISysBaseAPI;
10 10 import org.jeecg.common.util.CommonUtils;
11 11 import org.jeecg.common.util.RestUtil;
12 12 import org.jeecg.common.util.TokenUtils;
... ... @@ -72,8 +72,10 @@ public class CommonController {
72 72 String bizPath = request.getParameter("biz");
73 73  
74 74 //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
75   - if (oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"))) {
76   - throw new JeecgBootException("上传目录bizPath,格式非法!");
  75 + if (oConvertUtils.isNotEmpty(bizPath)) {
  76 + if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){
  77 + throw new JeecgBootException("上传目录bizPath,格式非法!");
  78 + }
77 79 }
78 80  
79 81 MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
... ... @@ -138,7 +140,7 @@ public class CommonController {
138 140 // 获取文件名
139 141 String orgName = mf.getOriginalFilename();
140 142 orgName = CommonUtils.getFileName(orgName);
141   - if(orgName.indexOf(".")!=-1){
  143 + if(orgName.indexOf(SymbolConstant.SPOT)!=-1){
142 144 fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
143 145 }else{
144 146 fileName = orgName+ "_" + System.currentTimeMillis();
... ... @@ -152,8 +154,8 @@ public class CommonController {
152 154 }else{
153 155 dbpath = fileName;
154 156 }
155   - if (dbpath.contains("\\")) {
156   - dbpath = dbpath.replace("\\", "/");
  157 + if (dbpath.contains(SymbolConstant.DOUBLE_BACKSLASH)) {
  158 + dbpath = dbpath.replace(SymbolConstant.DOUBLE_BACKSLASH, SymbolConstant.SINGLE_SLASH);
157 159 }
158 160 return dbpath;
159 161 } catch (IOException e) {
... ... @@ -210,7 +212,7 @@ public class CommonController {
210 212 public void view(HttpServletRequest request, HttpServletResponse response) {
211 213 // ISO-8859-1 ==> UTF-8 进行编码转换
212 214 String imgPath = extractPathFromPattern(request);
213   - if(oConvertUtils.isEmpty(imgPath) || imgPath=="null"){
  215 + if(oConvertUtils.isEmpty(imgPath) || CommonConstant.STRING_NULL.equals(imgPath)){
214 216 return;
215 217 }
216 218 // 其余处理略
... ... @@ -218,7 +220,7 @@ public class CommonController {
218 220 OutputStream outputStream = null;
219 221 try {
220 222 imgPath = imgPath.replace("..", "").replace("../","");
221   - if (imgPath.endsWith(",")) {
  223 + if (imgPath.endsWith(SymbolConstant.COMMA)) {
222 224 imgPath = imgPath.substring(0, imgPath.length() - 1);
223 225 }
224 226 String filePath = uploadpath + File.separator + imgPath;
... ... @@ -349,7 +351,7 @@ public class CommonController {
349 351 * @return
350 352 */
351 353 @RequestMapping("/transitRESTful")
352   - public Result transitRESTful(@RequestParam("url") String url, HttpServletRequest request) {
  354 + public Result transitRestful(@RequestParam("url") String url, HttpServletRequest request) {
353 355 try {
354 356 ServletServerHttpRequest httpRequest = new ServletServerHttpRequest(request);
355 357 // 中转请求method、body
... ... @@ -368,8 +370,8 @@ public class CommonController {
368 370 HttpHeaders headers = new HttpHeaders();
369 371 headers.set("X-Access-Token", token);
370 372 // 发送请求
371   - String httpURL = URLDecoder.decode(url, "UTF-8");
372   - ResponseEntity<String> response = RestUtil.request(httpURL, method, headers , variables, params, String.class);
  373 + String httpUrl = URLDecoder.decode(url, "UTF-8");
  374 + ResponseEntity<String> response = RestUtil.request(httpUrl, method, headers , variables, params, String.class);
373 375 // 封装返回结果
374 376 Result<Object> result = new Result<>();
375 377 int statusCode = response.getStatusCodeValue();
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java
... ... @@ -12,12 +12,14 @@ import org.apache.shiro.SecurityUtils;
12 12 import org.jeecg.common.api.vo.Result;
13 13 import org.jeecg.common.constant.CacheConstant;
14 14 import org.jeecg.common.constant.CommonConstant;
  15 +import org.jeecg.common.constant.SymbolConstant;
15 16 import org.jeecg.common.system.util.JwtUtil;
16 17 import org.jeecg.common.system.vo.LoginUser;
17 18 import org.jeecg.common.util.*;
18 19 import org.jeecg.common.util.encryption.EncryptedString;
19 20 import org.jeecg.modules.base.service.BaseCommonService;
20 21 import org.jeecg.modules.system.entity.SysDepart;
  22 +import org.jeecg.modules.system.entity.SysRoleIndex;
21 23 import org.jeecg.modules.system.entity.SysTenant;
22 24 import org.jeecg.modules.system.entity.SysUser;
23 25 import org.jeecg.modules.system.model.SysLoginModel;
... ... @@ -26,6 +28,7 @@ import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
26 28 import org.jeecg.modules.system.util.RandImageUtil;
27 29 import org.springframework.beans.BeanUtils;
28 30 import org.springframework.beans.factory.annotation.Autowired;
  31 +import org.springframework.http.HttpStatus;
29 32 import org.springframework.web.bind.annotation.*;
30 33  
31 34 import javax.annotation.Resource;
... ... @@ -59,6 +62,8 @@ public class LoginController {
59 62 @Resource
60 63 private BaseCommonService baseCommonService;
61 64  
  65 + private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
  66 +
62 67 @ApiOperation("登录接口")
63 68 @RequestMapping(value = "/login", method = RequestMethod.POST)
64 69 public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){
... ... @@ -83,6 +88,8 @@ public class LoginController {
83 88 if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) {
84 89 log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);
85 90 result.error500("验证码错误");
  91 + // 改成特殊的code 便于前端判断
  92 + result.setCode(HttpStatus.PRECONDITION_FAILED.value());
86 93 return result;
87 94 }
88 95 //update-end-author:taoyan date:20190828 for:校验验证码
... ... @@ -97,7 +104,7 @@ public class LoginController {
97 104 if(!result.isSuccess()) {
98 105 return result;
99 106 }
100   -
  107 +
101 108 //2. 校验用户名或密码是否正确
102 109 String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
103 110 String syspassword = sysUser.getPassword();
... ... @@ -130,6 +137,21 @@ public class LoginController {
130 137 // 根据用户名查询用户信息
131 138 SysUser sysUser = sysUserService.getUserByName(username);
132 139 JSONObject obj=new JSONObject();
  140 +
  141 + //update-begin---author:scott ---date:2022-06-20 for:vue3前端,支持自定义首页-----------
  142 + String version = request.getHeader(CommonConstant.VERSION);
  143 + //update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
  144 + SysRoleIndex roleIndex = sysUserService.getDynamicIndexByUserRole(username, version);
  145 + if (oConvertUtils.isNotEmpty(version) && roleIndex != null && oConvertUtils.isNotEmpty(roleIndex.getUrl())) {
  146 + String homePath = roleIndex.getUrl();
  147 + if (!homePath.startsWith(SymbolConstant.SINGLE_SLASH)) {
  148 + homePath = SymbolConstant.SINGLE_SLASH + homePath;
  149 + }
  150 + sysUser.setHomePath(homePath);
  151 + }
  152 + //update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
  153 + //update-end---author:scott ---date::2022-06-20 for:vue3前端,支持自定义首页--------------
  154 +
133 155 obj.put("userInfo",sysUser);
134 156 obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
135 157 result.setResult(obj);
... ... @@ -294,7 +316,8 @@ public class LoginController {
294 316 result = sysUserService.checkUserIsEffective(sysUser);
295 317 if(!result.isSuccess()) {
296 318 String message = result.getMessage();
297   - if("该用户不存在,请注册".equals(message)){
  319 + String userNotExist="该用户不存在,请注册";
  320 + if(userNotExist.equals(message)){
298 321 result.error500("该用户不存在或未绑定手机号");
299 322 }
300 323 return result;
... ... @@ -400,7 +423,7 @@ public class LoginController {
400 423 String tenantIds = sysUser.getRelTenantIds();
401 424 if (oConvertUtils.isNotEmpty(tenantIds)) {
402 425 List<Integer> tenantIdList = new ArrayList<>();
403   - for(String id: tenantIds.split(",")){
  426 + for(String id: tenantIds.split(SymbolConstant.COMMA)){
404 427 tenantIdList.add(Integer.valueOf(id));
405 428 }
406 429 // 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。
... ... @@ -451,7 +474,6 @@ public class LoginController {
451 474 Result<String> res = new Result<String>();
452 475 try {
453 476 //生成验证码
454   - final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
455 477 String code = RandomUtil.randomString(BASE_CHECK_CODES,4);
456 478  
457 479 //存到redis中
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java
... ... @@ -27,7 +27,7 @@ import org.jeecg.modules.system.service.ISysAnnouncementService;
27 27 import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
28 28 import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
29 29 import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
30   -import org.jeecg.modules.system.util.XSSUtils;
  30 +import org.jeecg.modules.system.util.XssUtils;
31 31 import org.jeecgframework.poi.excel.ExcelImportUtil;
32 32 import org.jeecgframework.poi.excel.def.NormalExcelConstants;
33 33 import org.jeecgframework.poi.excel.entity.ExportParams;
... ... @@ -125,7 +125,7 @@ public class SysAnnouncementController {
125 125 Result<SysAnnouncement> result = new Result<SysAnnouncement>();
126 126 try {
127 127 // update-begin-author:liusq date:20210804 for:标题处理xss攻击的问题
128   - String title = XSSUtils.striptXSS(sysAnnouncement.getTitile());
  128 + String title = XssUtils.scriptXss(sysAnnouncement.getTitile());
129 129 sysAnnouncement.setTitile(title);
130 130 // update-end-author:liusq date:20210804 for:标题处理xss攻击的问题
131 131 sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
... ... @@ -153,7 +153,7 @@ public class SysAnnouncementController {
153 153 result.error500("未找到对应实体");
154 154 }else {
155 155 // update-begin-author:liusq date:20210804 for:标题处理xss攻击的问题
156   - String title = XSSUtils.striptXSS(sysAnnouncement.getTitile());
  156 + String title = XssUtils.scriptXss(sysAnnouncement.getTitile());
157 157 sysAnnouncement.setTitile(title);
158 158 // update-end-author:liusq date:20210804 for:标题处理xss攻击的问题
159 159 boolean ok = sysAnnouncementService.upDateAnnouncement(sysAnnouncement);
... ... @@ -488,15 +488,15 @@ public class SysAnnouncementController {
488 488 public ModelAndView showContent(ModelAndView modelAndView, @PathVariable("id") String id, HttpServletRequest request) {
489 489 SysAnnouncement announcement = sysAnnouncementService.getById(id);
490 490 if (announcement != null) {
491   - boolean tokenOK = false;
  491 + boolean tokenOk = false;
492 492 try {
493 493 // 验证Token有效性
494   - tokenOK = TokenUtils.verifyToken(request, sysBaseApi, redisUtil);
  494 + tokenOk = TokenUtils.verifyToken(request, sysBaseApi, redisUtil);
495 495 } catch (Exception ignored) {
496 496 }
497 497 // 判断是否传递了Token,并且Token有效,如果传了就不做查看限制,直接返回
498 498 // 如果Token无效,就做查看限制:只能查看已发布的
499   - if (tokenOK || ANNOUNCEMENT_SEND_STATUS_1.equals(announcement.getSendStatus())) {
  499 + if (tokenOk || ANNOUNCEMENT_SEND_STATUS_1.equals(announcement.getSendStatus())) {
500 500 modelAndView.addObject("data", announcement);
501 501 modelAndView.setViewName("announcement/showContent");
502 502 return modelAndView;
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java
... ... @@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletRequest;
8 8 import org.apache.shiro.SecurityUtils;
9 9 import org.jeecg.common.api.vo.Result;
10 10 import org.jeecg.common.constant.CommonConstant;
  11 +import org.jeecg.common.constant.DataBaseConstant;
11 12 import org.jeecg.common.constant.WebsocketConst;
12 13 import org.jeecg.common.system.vo.LoginUser;
13 14 import org.jeecg.common.util.SqlInjectionUtil;
... ... @@ -76,7 +77,7 @@ public class SysAnnouncementSendController {
76 77 SqlInjectionUtil.filterContent(order);
77 78  
78 79 if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
79   - if("asc".equals(order)) {
  80 + if(DataBaseConstant.SQL_ASC.equals(order)) {
80 81 queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
81 82 }else {
82 83 queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java
... ... @@ -14,6 +14,7 @@ import org.jeecg.common.system.query.QueryGenerator;
14 14 import org.jeecg.common.system.vo.DictModel;
15 15 import org.jeecg.common.system.vo.LoginUser;
16 16 import org.jeecg.common.util.ImportExcelUtil;
  17 +import org.jeecg.common.util.SqlInjectionUtil;
17 18 import org.jeecg.common.util.oConvertUtils;
18 19 import org.jeecg.modules.system.entity.SysCategory;
19 20 import org.jeecg.modules.system.model.TreeSelectModel;
... ... @@ -47,7 +48,12 @@ import java.util.stream.Collectors;
47 48 public class SysCategoryController {
48 49 @Autowired
49 50 private ISysCategoryService sysCategoryService;
50   -
  51 +
  52 + /**
  53 + * 分类编码0
  54 + */
  55 + private static final String CATEGORY_ROOT_CODE = "0";
  56 +
51 57 /**
52 58 * 分页列表查询
53 59 * @param sysCategory
... ... @@ -294,7 +300,12 @@ public class SysCategoryController {
294 300 public Result<SysCategory> loadOne(@RequestParam(name="field") String field,@RequestParam(name="val") String val) {
295 301 Result<SysCategory> result = new Result<SysCategory>();
296 302 try {
297   -
  303 + //update-begin-author:taoyan date:2022-5-6 for: issues/3663 sql注入问题
  304 + boolean isClassField = SqlInjectionUtil.isClassField(field, SysCategory.class);
  305 + if (!isClassField) {
  306 + return Result.error("字段无效,请检查!");
  307 + }
  308 + //update-end-author:taoyan date:2022-5-6 for: issues/3663 sql注入问题
298 309 QueryWrapper<SysCategory> query = new QueryWrapper<SysCategory>();
299 310 query.eq(field, val);
300 311 List<SysCategory> ls = this.sysCategoryService.list(query);
... ... @@ -463,7 +474,7 @@ public class SysCategoryController {
463 474 public Result<List<DictModel>> loadAllData(@RequestParam(name="code",required = true) String code) {
464 475 Result<List<DictModel>> result = new Result<List<DictModel>>();
465 476 LambdaQueryWrapper<SysCategory> query = new LambdaQueryWrapper<SysCategory>();
466   - if(oConvertUtils.isNotEmpty(code) && !"0".equals(code)){
  477 + if(oConvertUtils.isNotEmpty(code) && !CATEGORY_ROOT_CODE.equals(code)){
467 478 query.likeRight(SysCategory::getCode,code);
468 479 }
469 480 List<SysCategory> list = this.sysCategoryService.list(query);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDataSourceController.java
1 1 package org.jeecg.modules.system.controller;
2 2  
3   -import cn.hutool.core.util.CharsetUtil;
4   -import cn.hutool.core.util.HexUtil;
5   -import cn.hutool.crypto.SecureUtil;
6   -import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
7   -import cn.hutool.crypto.symmetric.SymmetricCrypto;
  3 +
8 4 import com.alibaba.fastjson.JSONArray;
9 5 import com.alibaba.fastjson.JSONObject;
  6 +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
  7 +import com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator;
  8 +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
10 9 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
11 10 import com.baomidou.mybatisplus.core.metadata.IPage;
12 11 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
... ... @@ -29,6 +28,7 @@ import org.springframework.web.servlet.ModelAndView;
29 28  
30 29 import javax.servlet.http.HttpServletRequest;
31 30 import javax.servlet.http.HttpServletResponse;
  31 +import javax.sql.DataSource;
32 32 import java.util.Arrays;
33 33 import java.util.List;
34 34  
... ... @@ -69,18 +69,6 @@ public class SysDataSourceController extends JeecgController&lt;SysDataSource, ISys
69 69 QueryWrapper<SysDataSource> queryWrapper = QueryGenerator.initQueryWrapper(sysDataSource, req.getParameterMap());
70 70 Page<SysDataSource> page = new Page<>(pageNo, pageSize);
71 71 IPage<SysDataSource> pageList = sysDataSourceService.page(page, queryWrapper);
72   - try {
73   - List<SysDataSource> records = pageList.getRecords();
74   - records.forEach(item->{
75   - String dbPassword = item.getDbPassword();
76   - if(StringUtils.isNotBlank(dbPassword)){
77   - String decodedStr = SecurityUtil.jiemi(dbPassword);
78   - item.setDbPassword(decodedStr);
79   - }
80   - });
81   - } catch (Exception e) {
82   - e.printStackTrace();
83   - }
84 72 return Result.ok(pageList);
85 73 }
86 74  
... ... @@ -109,17 +97,7 @@ public class SysDataSourceController extends JeecgController&lt;SysDataSource, ISys
109 97 @ApiOperation(value = "多数据源管理-添加", notes = "多数据源管理-添加")
110 98 @PostMapping(value = "/add")
111 99 public Result<?> add(@RequestBody SysDataSource sysDataSource) {
112   - try {
113   - String dbPassword = sysDataSource.getDbPassword();
114   - if(StringUtils.isNotBlank(dbPassword)){
115   - String encrypt = SecurityUtil.jiami(dbPassword);
116   - sysDataSource.setDbPassword(encrypt);
117   - }
118   - sysDataSourceService.save(sysDataSource);
119   - } catch (Exception e) {
120   - e.printStackTrace();
121   - }
122   - return Result.ok("添加成功!");
  100 + return sysDataSourceService.saveDataSource(sysDataSource);
123 101 }
124 102  
125 103 /**
... ... @@ -132,19 +110,7 @@ public class SysDataSourceController extends JeecgController&lt;SysDataSource, ISys
132 110 @ApiOperation(value = "多数据源管理-编辑", notes = "多数据源管理-编辑")
133 111 @RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
134 112 public Result<?> edit(@RequestBody SysDataSource sysDataSource) {
135   - try {
136   - SysDataSource d = sysDataSourceService.getById(sysDataSource.getId());
137   - DataSourceCachePool.removeCache(d.getCode());
138   - String dbPassword = sysDataSource.getDbPassword();
139   - if(StringUtils.isNotBlank(dbPassword)){
140   - String encrypt = SecurityUtil.jiami(dbPassword);
141   - sysDataSource.setDbPassword(encrypt);
142   - }
143   - sysDataSourceService.updateById(sysDataSource);
144   - } catch (Exception e) {
145   - e.printStackTrace();
146   - }
147   - return Result.ok("编辑成功!");
  113 + return sysDataSourceService.editDataSource(sysDataSource);
148 114 }
149 115  
150 116 /**
... ... @@ -157,10 +123,7 @@ public class SysDataSourceController extends JeecgController&lt;SysDataSource, ISys
157 123 @ApiOperation(value = "多数据源管理-通过id删除", notes = "多数据源管理-通过id删除")
158 124 @DeleteMapping(value = "/delete")
159 125 public Result<?> delete(@RequestParam(name = "id") String id) {
160   - SysDataSource sysDataSource = sysDataSourceService.getById(id);
161   - DataSourceCachePool.removeCache(sysDataSource.getCode());
162   - sysDataSourceService.removeById(id);
163   - return Result.ok("删除成功!");
  126 + return sysDataSourceService.deleteDataSource(id);
164 127 }
165 128  
166 129 /**
... ... @@ -191,8 +154,14 @@ public class SysDataSourceController extends JeecgController&lt;SysDataSource, ISys
191 154 @AutoLog(value = "多数据源管理-通过id查询")
192 155 @ApiOperation(value = "多数据源管理-通过id查询", notes = "多数据源管理-通过id查询")
193 156 @GetMapping(value = "/queryById")
194   - public Result<?> queryById(@RequestParam(name = "id") String id) {
  157 + public Result<?> queryById(@RequestParam(name = "id") String id) throws InterruptedException {
195 158 SysDataSource sysDataSource = sysDataSourceService.getById(id);
  159 + //密码解密
  160 + String dbPassword = sysDataSource.getDbPassword();
  161 + if(StringUtils.isNotBlank(dbPassword)){
  162 + String decodedStr = SecurityUtil.jiemi(dbPassword);
  163 + sysDataSource.setDbPassword(decodedStr);
  164 + }
196 165 return Result.ok(sysDataSource);
197 166 }
198 167  
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java
... ... @@ -123,13 +123,14 @@ public class SysDepartController {
123 123 * 异步查询部门list
124 124 * @param parentId 父节点 异步加载时传递
125 125 * @param ids 前端回显是传递
  126 + * @param primaryKey 主键字段(id或者orgCode)
126 127 * @return
127 128 */
128 129 @RequestMapping(value = "/queryDepartTreeSync", method = RequestMethod.GET)
129   - public Result<List<SysDepartTreeModel>> queryDepartTreeSync(@RequestParam(name = "pid", required = false) String parentId,@RequestParam(name = "ids", required = false) String ids) {
  130 + public Result<List<SysDepartTreeModel>> queryDepartTreeSync(@RequestParam(name = "pid", required = false) String parentId,@RequestParam(name = "ids", required = false) String ids, @RequestParam(name = "primaryKey", required = false) String primaryKey) {
130 131 Result<List<SysDepartTreeModel>> result = new Result<>();
131 132 try {
132   - List<SysDepartTreeModel> list = sysDepartService.queryTreeListByPid(parentId,ids);
  133 + List<SysDepartTreeModel> list = sysDepartService.queryTreeListByPid(parentId,ids, primaryKey);
133 134 result.setResult(list);
134 135 result.setSuccess(true);
135 136 } catch (Exception e) {
... ... @@ -460,7 +461,7 @@ public class SysDepartController {
460 461 LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
461 462 query.orderByAsc(SysDepart::getOrgCode);
462 463 if(oConvertUtils.isNotEmpty(id)){
463   - String arr[] = id.split(",");
  464 + String[] arr = id.split(",");
464 465 query.in(SysDepart::getId,arr);
465 466 }
466 467 List<SysDepart> ls = this.sysDepartService.list(query);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java
... ... @@ -237,7 +237,7 @@ public class SysDepartPermissionController extends JeecgController&lt;SysDepartPerm
237 237 Result<List<String>> result = new Result<>();
238 238 try {
239 239 List<SysDepartRolePermission> list = sysDepartRolePermissionService.list(new QueryWrapper<SysDepartRolePermission>().lambda().eq(SysDepartRolePermission::getRoleId, roleId));
240   - result.setResult(list.stream().map(SysDepartRolePermission -> String.valueOf(SysDepartRolePermission.getPermissionId())).collect(Collectors.toList()));
  240 + result.setResult(list.stream().map(sysDepartRolePermission -> String.valueOf(sysDepartRolePermission.getPermissionId())).collect(Collectors.toList()));
241 241 result.setSuccess(true);
242 242 } catch (Exception e) {
243 243 log.error(e.getMessage(), e);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDictController.java
... ... @@ -12,6 +12,7 @@ import org.apache.shiro.authz.annotation.RequiresRoles;
12 12 import org.jeecg.common.api.vo.Result;
13 13 import org.jeecg.common.constant.CacheConstant;
14 14 import org.jeecg.common.constant.CommonConstant;
  15 +import org.jeecg.common.constant.SymbolConstant;
15 16 import org.jeecg.common.system.query.QueryGenerator;
16 17 import org.jeecg.common.system.vo.DictModel;
17 18 import org.jeecg.common.system.vo.DictQuery;
... ... @@ -277,8 +278,8 @@ public class SysDictController {
277 278 }
278 279 //update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口,加一些安全机制
279 280 try {
280   - if(dictCode.indexOf(",")!=-1) {
281   - String[] params = dictCode.split(",");
  281 + if(dictCode.indexOf(SymbolConstant.COMMA)!=-1) {
  282 + String[] params = dictCode.split(SymbolConstant.COMMA);
282 283 if(params.length!=3) {
283 284 result.error500("字典Code格式不正确!");
284 285 return result;
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysLogController.java
... ... @@ -6,6 +6,7 @@ import java.util.Arrays;
6 6 import javax.servlet.http.HttpServletRequest;
7 7  
8 8 import org.jeecg.common.api.vo.Result;
  9 +import org.jeecg.common.constant.CommonConstant;
9 10 import org.jeecg.common.system.query.QueryGenerator;
10 11 import org.jeecg.common.util.oConvertUtils;
11 12 import org.jeecg.modules.system.entity.SysLog;
... ... @@ -38,7 +39,12 @@ public class SysLogController {
38 39  
39 40 @Autowired
40 41 private ISysLogService sysLogService;
41   -
  42 +
  43 + /**
  44 + * 全部清除
  45 + */
  46 + private static final String ALL_ClEAR = "allclear";
  47 +
42 48 /**
43 49 * @功能:查询日志记录
44 50 * @param syslog
... ... @@ -103,7 +109,7 @@ public class SysLogController {
103 109 if(ids==null || "".equals(ids.trim())) {
104 110 result.error500("参数不识别!");
105 111 }else {
106   - if("allclear".equals(ids)) {
  112 + if(ALL_ClEAR.equals(ids)) {
107 113 this.sysLogService.removeAll();
108 114 result.success("清除成功!");
109 115 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java
1 1 package org.jeecg.modules.system.controller;
2 2  
  3 +import cn.hutool.core.util.ObjectUtil;
3 4 import com.alibaba.fastjson.JSONArray;
4 5 import com.alibaba.fastjson.JSONObject;
5 6 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
... ... @@ -10,11 +11,12 @@ import org.apache.shiro.SecurityUtils;
10 11 import org.apache.shiro.authz.annotation.RequiresRoles;
11 12 import org.jeecg.common.api.vo.Result;
12 13 import org.jeecg.common.constant.CommonConstant;
  14 +import org.jeecg.common.constant.SymbolConstant;
13 15 import org.jeecg.common.constant.enums.RoleIndexConfigEnum;
14 16 import org.jeecg.common.system.vo.LoginUser;
15 17 import org.jeecg.common.util.Md5Util;
16 18 import org.jeecg.common.util.oConvertUtils;
17   -import org.jeecg.config.JeeccgBaseConfig;
  19 +import org.jeecg.config.JeecgBaseConfig;
18 20 import org.jeecg.modules.base.service.BaseCommonService;
19 21 import org.jeecg.modules.system.entity.*;
20 22 import org.jeecg.modules.system.model.SysPermissionTree;
... ... @@ -57,7 +59,7 @@ public class SysPermissionController {
57 59 private ISysUserService sysUserService;
58 60  
59 61 @Autowired
60   - private JeeccgBaseConfig jeeccgBaseConfig;
  62 + private JeecgBaseConfig jeecgBaseConfig;
61 63  
62 64 @Autowired
63 65 private BaseCommonService baseCommonService;
... ... @@ -65,6 +67,11 @@ public class SysPermissionController {
65 67 @Autowired
66 68 private ISysRoleIndexService sysRoleIndexService;
67 69  
  70 + /**
  71 + * 子菜单
  72 + */
  73 + private static final String CHILDREN = "children";
  74 +
68 75 /**
69 76 * 加载数据节点
70 77 *
... ... @@ -212,6 +219,7 @@ public class SysPermissionController {
212 219 * @return
213 220 */
214 221 @RequestMapping(value = "/getUserPermissionByToken", method = RequestMethod.GET)
  222 + //@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX)
215 223 public Result<?> getUserPermissionByToken(HttpServletRequest request) {
216 224 Result<JSONObject> result = new Result<JSONObject>();
217 225 try {
... ... @@ -229,14 +237,29 @@ public class SysPermissionController {
229 237 }
230 238 //update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
231 239  
232   - //update-begin--Author:liusq Date:20210624 for:自定义首页地址LOWCOD-1578
233   - List<String> roles = sysUserService.getRole(loginUser.getUsername());
234   - String compUrl = RoleIndexConfigEnum.getIndexByRoles(roles);
235   - if(StringUtils.isNotBlank(compUrl)){
  240 + //update-begin--Author:zyf Date:20220425 for:自定义首页地址 LOWCOD-1578
  241 + String version = request.getHeader(CommonConstant.VERSION);
  242 + //update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
  243 + SysRoleIndex roleIndex= sysUserService.getDynamicIndexByUserRole(loginUser.getUsername(),version);
  244 + //update-end---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
  245 + //update-end--Author:zyf Date:20220425 for:自定义首页地址 LOWCOD-1578
  246 +
  247 + if(roleIndex!=null){
236 248 List<SysPermission> menus = metaList.stream().filter(sysPermission -> "首页".equals(sysPermission.getName())).collect(Collectors.toList());
237   - menus.get(0).setComponent(compUrl);
  249 + //update-begin---author:liusq ---date:2022-06-29 for:设置自定义首页地址和组件----------
  250 + String component = roleIndex.getComponent();
  251 + String routeUrl = roleIndex.getUrl();
  252 + boolean route = roleIndex.isRoute();
  253 + if(oConvertUtils.isNotEmpty(routeUrl)){
  254 + menus.get(0).setComponent(component);
  255 + menus.get(0).setRoute(route);
  256 + menus.get(0).setUrl(routeUrl);
  257 + }else{
  258 + menus.get(0).setComponent(component);
  259 + }
  260 + //update-end---author:liusq ---date:2022-06-29 for:设置自定义首页地址和组件-----------
238 261 }
239   - //update-end--Author:liusq Date:20210624 for:自定义首页地址LOWCOD-1578
  262 +
240 263 JSONObject json = new JSONObject();
241 264 JSONArray menujsonArray = new JSONArray();
242 265 this.getPermissionJsonArray(menujsonArray, metaList, null);
... ... @@ -259,7 +282,7 @@ public class SysPermissionController {
259 282 json.put("auth", authjsonArray);
260 283 //全部权限配置集合(按钮权限,访问权限)
261 284 json.put("allAuth", allauthjsonArray);
262   - json.put("sysSafeMode", jeeccgBaseConfig.getSafeMode());
  285 + json.put("sysSafeMode", jeecgBaseConfig.getSafeMode());
263 286 result.setResult(json);
264 287 } catch (Exception e) {
265 288 result.error500("查询失败:" + e.getMessage());
... ... @@ -306,7 +329,7 @@ public class SysPermissionController {
306 329 //全部权限配置集合(按钮权限,访问权限)
307 330 result.put("allAuth", allAuthArray);
308 331 // 系统安全模式
309   - result.put("sysSafeMode", jeeccgBaseConfig.getSafeMode());
  332 + result.put("sysSafeMode", jeecgBaseConfig.getSafeMode());
310 333 return Result.OK(result);
311 334 } catch (Exception e) {
312 335 log.error(e.getMessage(), e);
... ... @@ -418,7 +441,7 @@ public class SysPermissionController {
418 441 List<TreeModel> treeList = new ArrayList<>();
419 442 getTreeModelList(treeList, list, null);
420 443  
421   - Map<String, Object> resMap = new HashMap<String, Object>();
  444 + Map<String, Object> resMap = new HashMap<String, Object>(5);
422 445 // 全部树节点数据
423 446 resMap.put("treeList", treeList);
424 447 // 全部树ids
... ... @@ -464,7 +487,7 @@ public class SysPermissionController {
464 487 Result<List<String>> result = new Result<>();
465 488 try {
466 489 List<SysRolePermission> list = sysRolePermissionService.list(new QueryWrapper<SysRolePermission>().lambda().eq(SysRolePermission::getRoleId, roleId));
467   - result.setResult(list.stream().map(SysRolePermission -> String.valueOf(SysRolePermission.getPermissionId())).collect(Collectors.toList()));
  490 + result.setResult(list.stream().map(sysRolePermission -> String.valueOf(sysRolePermission.getPermissionId())).collect(Collectors.toList()));
468 491 result.setSuccess(true);
469 492 } catch (Exception e) {
470 493 log.error(e.getMessage(), e);
... ... @@ -546,8 +569,8 @@ public class SysPermissionController {
546 569 jsonArray = jsonArray.stream().map(obj -> {
547 570 JSONObject returnObj = new JSONObject();
548 571 JSONObject jsonObj = (JSONObject)obj;
549   - if(jsonObj.containsKey("children")){
550   - JSONArray childrens = jsonObj.getJSONArray("children");
  572 + if(jsonObj.containsKey(CHILDREN)){
  573 + JSONArray childrens = jsonObj.getJSONArray(CHILDREN);
551 574 childrens = childrens.stream().filter(arrObj -> !"true".equals(((JSONObject) arrObj).getString("hidden"))).collect(Collectors.toCollection(JSONArray::new));
552 575 if(childrens==null || childrens.size()==0){
553 576 jsonObj.put("hidden",true);
... ... @@ -675,7 +698,7 @@ public class SysPermissionController {
675 698 json.put("route", "0");
676 699 }
677 700  
678   - if (isWWWHttpUrl(permission.getUrl())) {
  701 + if (isWwwHttpUrl(permission.getUrl())) {
679 702 json.put("path", Md5Util.md5Encode(permission.getUrl(), "utf-8"));
680 703 } else {
681 704 json.put("path", permission.getUrl());
... ... @@ -736,7 +759,7 @@ public class SysPermissionController {
736 759 meta.put("icon", permission.getIcon());
737 760 }
738 761 }
739   - if (isWWWHttpUrl(permission.getUrl())) {
  762 + if (isWwwHttpUrl(permission.getUrl())) {
740 763 meta.put("url", permission.getUrl());
741 764 }
742 765 // update-begin--Author:sunjianlei Date:20210918 for:新增适配vue3项目的隐藏tab功能
... ... @@ -756,8 +779,9 @@ public class SysPermissionController {
756 779 *
757 780 * @return
758 781 */
759   - private boolean isWWWHttpUrl(String url) {
760   - if (url != null && (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("{{"))) {
  782 + private boolean isWwwHttpUrl(String url) {
  783 + boolean flag = url != null && (url.startsWith(CommonConstant.HTTP_PROTOCOL) || url.startsWith(CommonConstant.HTTPS_PROTOCOL) || url.startsWith(SymbolConstant.DOUBLE_LEFT_CURLY_BRACKET));
  784 + if (flag) {
761 785 return true;
762 786 }
763 787 return false;
... ... @@ -771,7 +795,7 @@ public class SysPermissionController {
771 795 */
772 796 private String urlToRouteName(String url) {
773 797 if (oConvertUtils.isNotEmpty(url)) {
774   - if (url.startsWith("/")) {
  798 + if (url.startsWith(SymbolConstant.SINGLE_SLASH)) {
775 799 url = url.substring(1);
776 800 }
777 801 url = url.replace("/", "-");
... ... @@ -883,7 +907,7 @@ public class SysPermissionController {
883 907 Result<List<String>> result = new Result<>();
884 908 try {
885 909 List<SysDepartPermission> list = sysDepartPermissionService.list(new QueryWrapper<SysDepartPermission>().lambda().eq(SysDepartPermission::getDepartId, departId));
886   - result.setResult(list.stream().map(SysDepartPermission -> String.valueOf(SysDepartPermission.getPermissionId())).collect(Collectors.toList()));
  910 + result.setResult(list.stream().map(sysDepartPermission -> String.valueOf(sysDepartPermission.getPermissionId())).collect(Collectors.toList()));
887 911 result.setSuccess(true);
888 912 } catch (Exception e) {
889 913 log.error(e.getMessage(), e);
... ... @@ -914,4 +938,5 @@ public class SysPermissionController {
914 938 }
915 939 return result;
916 940 }
  941 +
917 942 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java
... ... @@ -68,7 +68,8 @@ public class SysRoleIndexController extends JeecgController&lt;SysRoleIndex, ISysRo
68 68 @AutoLog(value = "角色首页配置-添加")
69 69 @ApiOperation(value = "角色首页配置-添加", notes = "角色首页配置-添加")
70 70 @PostMapping(value = "/add")
71   - public Result<?> add(@RequestBody SysRoleIndex sysRoleIndex) {
  71 + //@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX)
  72 + public Result<?> add(@RequestBody SysRoleIndex sysRoleIndex,HttpServletRequest request) {
72 73 sysRoleIndexService.save(sysRoleIndex);
73 74 return Result.OK("添加成功!");
74 75 }
... ... @@ -82,7 +83,8 @@ public class SysRoleIndexController extends JeecgController&lt;SysRoleIndex, ISysRo
82 83 @AutoLog(value = "角色首页配置-编辑")
83 84 @ApiOperation(value = "角色首页配置-编辑", notes = "角色首页配置-编辑")
84 85 @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
85   - public Result<?> edit(@RequestBody SysRoleIndex sysRoleIndex) {
  86 + //@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX)
  87 + public Result<?> edit(@RequestBody SysRoleIndex sysRoleIndex,HttpServletRequest request) {
86 88 sysRoleIndexService.updateById(sysRoleIndex);
87 89 return Result.OK("编辑成功!");
88 90 }
... ... @@ -161,7 +163,8 @@ public class SysRoleIndexController extends JeecgController&lt;SysRoleIndex, ISysRo
161 163 @AutoLog(value = "角色首页配置-通过code查询")
162 164 @ApiOperation(value = "角色首页配置-通过code查询", notes = "角色首页配置-通过code查询")
163 165 @GetMapping(value = "/queryByCode")
164   - public Result<?> queryByCode(@RequestParam(name = "roleCode", required = true) String roleCode) {
  166 + //@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX)
  167 + public Result<?> queryByCode(@RequestParam(name = "roleCode", required = true) String roleCode,HttpServletRequest request) {
165 168 SysRoleIndex sysRoleIndex = sysRoleIndexService.getOne(new LambdaQueryWrapper<SysRoleIndex>().eq(SysRoleIndex::getRoleCode, roleCode));
166 169 return Result.OK(sysRoleIndex);
167 170 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java
... ... @@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j;
9 9 import org.apache.shiro.SecurityUtils;
10 10 import org.jeecg.common.api.vo.Result;
11 11 import org.jeecg.common.aspect.annotation.PermissionData;
  12 +import org.jeecg.common.constant.SymbolConstant;
12 13 import org.jeecg.common.system.query.QueryGenerator;
13 14 import org.jeecg.common.system.vo.LoginUser;
14 15 import org.jeecg.common.util.oConvertUtils;
... ... @@ -204,7 +205,7 @@ public class SysTenantController {
204 205 Map<String,Object> map = new HashMap(5);
205 206 if (oConvertUtils.isNotEmpty(tenantIds)) {
206 207 List<Integer> tenantIdList = new ArrayList<>();
207   - for(String id: tenantIds.split(",")){
  208 + for(String id: tenantIds.split(SymbolConstant.COMMA)){
208 209 tenantIdList.add(Integer.valueOf(id));
209 210 }
210 211 // 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUploadController.java
... ... @@ -6,8 +6,8 @@ import org.jeecg.common.exception.JeecgBootException;
6 6 import org.jeecg.common.util.CommonUtils;
7 7 import org.jeecg.common.util.MinioUtil;
8 8 import org.jeecg.common.util.oConvertUtils;
9   -import org.jeecg.modules.oss.entity.OSSFile;
10   -import org.jeecg.modules.oss.service.IOSSFileService;
  9 +import org.jeecg.modules.oss.entity.OssFile;
  10 +import org.jeecg.modules.oss.service.IOssFileService;
11 11 import org.springframework.beans.factory.annotation.Autowired;
12 12 import org.springframework.web.bind.annotation.PostMapping;
13 13 import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -26,7 +26,7 @@ import javax.servlet.http.HttpServletRequest;
26 26 @RequestMapping("/sys/upload")
27 27 public class SysUploadController {
28 28 @Autowired
29   - private IOSSFileService ossFileService;
  29 + private IOssFileService ossFileService;
30 30  
31 31 /**
32 32 * 上传
... ... @@ -38,7 +38,8 @@ public class SysUploadController {
38 38 String bizPath = request.getParameter("biz");
39 39  
40 40 //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
41   - if (oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"))) {
  41 + boolean flag = oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"));
  42 + if (flag) {
42 43 throw new JeecgBootException("上传目录bizPath,格式非法!");
43 44 }
44 45  
... ... @@ -51,16 +52,16 @@ public class SysUploadController {
51 52 // 获取文件名
52 53 String orgName = file.getOriginalFilename();
53 54 orgName = CommonUtils.getFileName(orgName);
54   - String file_url = MinioUtil.upload(file,bizPath);
55   - if(oConvertUtils.isEmpty(file_url)){
  55 + String fileUrl = MinioUtil.upload(file,bizPath);
  56 + if(oConvertUtils.isEmpty(fileUrl)){
56 57 return Result.error("上传失败,请检查配置信息是否正确!");
57 58 }
58 59 //保存文件信息
59   - OSSFile minioFile = new OSSFile();
  60 + OssFile minioFile = new OssFile();
60 61 minioFile.setFileName(orgName);
61   - minioFile.setUrl(file_url);
  62 + minioFile.setUrl(fileUrl);
62 63 ossFileService.save(minioFile);
63   - result.setMessage(file_url);
  64 + result.setMessage(fileUrl);
64 65 result.setSuccess(true);
65 66 return result;
66 67 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserController.java
... ... @@ -18,6 +18,7 @@ import org.apache.shiro.authz.annotation.RequiresRoles;
18 18 import org.jeecg.common.api.vo.Result;
19 19 import org.jeecg.common.aspect.annotation.PermissionData;
20 20 import org.jeecg.common.constant.CommonConstant;
  21 +import org.jeecg.common.constant.SymbolConstant;
21 22 import org.jeecg.common.system.api.ISysBaseAPI;
22 23 import org.jeecg.modules.base.service.BaseCommonService;
23 24 import org.jeecg.common.system.query.QueryGenerator;
... ... @@ -159,7 +160,7 @@ public class SysUserController {
159 160 }
160 161  
161 162 //@RequiresRoles({"admin"})
162   - //@RequiresPermissions("user:add")
  163 + //Permissions("system:user:add")
163 164 @RequestMapping(value = "/add", method = RequestMethod.POST)
164 165 public Result<SysUser> add(@RequestBody JSONObject jsonObject) {
165 166 Result<SysUser> result = new Result<SysUser>();
... ... @@ -174,6 +175,8 @@ public class SysUserController {
174 175 user.setPassword(passwordEncode);
175 176 user.setStatus(1);
176 177 user.setDelFlag(CommonConstant.DEL_FLAG_0);
  178 + //用户表字段org_code不能在这里设置他的值
  179 + user.setOrgCode(null);
177 180 // 保存用户走一个service 保证事务
178 181 sysUserService.saveUser(user, selectedRoles, selectedDeparts);
179 182 baseCommonService.addLog("添加用户,username: " +user.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
... ... @@ -186,7 +189,7 @@ public class SysUserController {
186 189 }
187 190  
188 191 //@RequiresRoles({"admin"})
189   - //@RequiresPermissions("user:edit")
  192 + //Permissions("system:user:edit")
190 193 @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
191 194 public Result<SysUser> edit(@RequestBody JSONObject jsonObject) {
192 195 Result<SysUser> result = new Result<SysUser>();
... ... @@ -206,6 +209,8 @@ public class SysUserController {
206 209 //vue3.0前端只传递了departIds
207 210 departs=user.getDepartIds();
208 211 }
  212 + //用户表字段org_code不能在这里设置他的值
  213 + user.setOrgCode(null);
209 214 // 修改用户走一个service 保证事务
210 215 sysUserService.editUser(user, roles, departs);
211 216 result.success("修改成功!");
... ... @@ -439,8 +444,13 @@ public class SysUserController {
439 444 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
440 445 @RequestParam(name = "departId", required = false) String departId,
441 446 @RequestParam(name="realname",required=false) String realname,
442   - @RequestParam(name="username",required=false) String username) {
443   - IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo);
  447 + @RequestParam(name="username",required=false) String username,
  448 + @RequestParam(name="id",required = false) String id) {
  449 + //update-begin-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
  450 + String[] arr = new String[]{departId, realname, username, id};
  451 + SqlInjectionUtil.filterContent(arr, SymbolConstant.SINGLE_QUOTATION_MARK);
  452 + //update-end-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
  453 + IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo,id);
444 454 return Result.OK(pageList);
445 455 }
446 456  
... ... @@ -450,6 +460,8 @@ public class SysUserController {
450 460 * @param request
451 461 * @param sysUser
452 462 */
  463 + //@RequiresRoles({"admin"})
  464 + //@RequiresPermissions("system:user:export")
453 465 @RequestMapping(value = "/exportXls")
454 466 public ModelAndView exportXls(SysUser sysUser,HttpServletRequest request) {
455 467 // Step.1 组装查询条件
... ... @@ -483,7 +495,7 @@ public class SysUserController {
483 495 * @return
484 496 */
485 497 //@RequiresRoles({"admin"})
486   - //@RequiresPermissions("user:import")
  498 + //Permissions("system:user:import")
487 499 @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
488 500 public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response)throws IOException {
489 501 MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
... ... @@ -1267,6 +1279,15 @@ public class SysUserController {
1267 1279 sysUser.setPhone(phone);
1268 1280 }
1269 1281 if(StringUtils.isNotBlank(email)){
  1282 + //update-begin---author:wangshuai ---date:20220708 for:[VUEN-1528]积木官网邮箱重复,应该提示准确------------
  1283 + LambdaQueryWrapper<SysUser> emailQuery = new LambdaQueryWrapper<>();
  1284 + emailQuery.eq(SysUser::getEmail,email);
  1285 + long count = sysUserService.count(emailQuery);
  1286 + if (!email.equals(sysUser.getEmail()) && count!=0) {
  1287 + result.error500("保存失败,邮箱已存在!");
  1288 + return result;
  1289 + }
  1290 + //update-end---author:wangshuai ---date:20220708 for:[VUEN-1528]积木官网邮箱重复,应该提示准确--------------
1270 1291 sysUser.setEmail(email);
1271 1292 }
1272 1293 if(null != birthday){
... ... @@ -1277,7 +1298,7 @@ public class SysUserController {
1277 1298 }
1278 1299 } catch (Exception e) {
1279 1300 log.error(e.getMessage(), e);
1280   - result.error500("操作失败!");
  1301 + result.error500("保存失败!");
1281 1302 }
1282 1303 return result;
1283 1304 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java
... ... @@ -246,7 +246,7 @@ public class ThirdAppController {
246 246 // 第三方app的类型
247 247 String app = params.getString("app");
248 248 // 消息id
249   - String msg_task_id = params.getString("msg_task_id");
  249 + String msgTaskId = params.getString("msg_task_id");
250 250  
251 251 if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) {
252 252 if (thirdAppConfig.isWechatEnterpriseEnabled()) {
... ... @@ -255,7 +255,7 @@ public class ThirdAppController {
255 255 return Result.error("企业微信已被禁用");
256 256 } else if (ThirdAppConfig.DINGTALK.equals(app)) {
257 257 if (thirdAppConfig.isDingtalkEnabled()) {
258   - Response<JSONObject> response = dingtalkService.recallMessageResponse(msg_task_id);
  258 + Response<JSONObject> response = dingtalkService.recallMessageResponse(msgTaskId);
259 259 if (response.isSuccess()) {
260 260 return Result.OK("撤回成功", response);
261 261 } else {
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java
... ... @@ -332,7 +332,10 @@ public class ThirdLoginController {
332 332 builder.append("&scope=openid");
333 333 // 跟随authCode原样返回。
334 334 builder.append("&state=").append(state);
335   - url = builder.toString();
  335 + //update-begin---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录------------
  336 + builder.append("&prompt=").append("consent");
  337 + //update-end---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录--------------
  338 + url = builder.toString();
336 339 } else {
337 340 return "不支持的source";
338 341 }
... ... @@ -377,9 +380,28 @@ public class ThirdLoginController {
377 380 return "不支持的source";
378 381 }
379 382 try {
380   - String token = saveToken(loginUser);
  383 +
  384 + //update-begin-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
  385 + String redirect = "";
  386 + if (state.indexOf("?") > 0) {
  387 + String[] arr = state.split("\\?");
  388 + state = arr[0];
  389 + if(arr.length>1){
  390 + redirect = arr[1];
  391 + }
  392 + }
  393 +
  394 + String token = saveToken(loginUser);
381 395 state += "/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8");
382   - state += "&thirdType=" + "wechat_enterprise";
  396 + //update-begin---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录------------
  397 + state += "&thirdType=" + source;
  398 + //state += "&thirdType=" + "wechat_enterprise";
  399 + if (redirect != null && redirect.length() > 0) {
  400 + state += "&" + redirect;
  401 + }
  402 + //update-end-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
  403 +
  404 + //update-end---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录------------
383 405 log.info("OAuth2登录重定向地址: " + state);
384 406 try {
385 407 response.sendRedirect(state);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysRoleIndex.java
... ... @@ -40,6 +40,17 @@ public class SysRoleIndex {
40 40 @Excel(name = "路由地址", width = 15)
41 41 @ApiModelProperty(value = "路由地址")
42 42 private java.lang.String url;
  43 + /**路由地址*/
  44 + @Excel(name = "路由地址", width = 15)
  45 + @ApiModelProperty(value = "组件")
  46 + private java.lang.String component;
  47 + /**
  48 + * 是否路由菜单: 0:不是 1:是(默认值1)
  49 + */
  50 + @Excel(name = "是否路由菜单", width = 15)
  51 + @ApiModelProperty(value = "是否路由菜单")
  52 + @TableField(value="is_route")
  53 + private boolean route;
43 54 /**优先级*/
44 55 @Excel(name = "优先级", width = 15)
45 56 @ApiModelProperty(value = "优先级")
... ... @@ -72,4 +83,12 @@ public class SysRoleIndex {
72 83 @Excel(name = "所属部门", width = 15)
73 84 @ApiModelProperty(value = "所属部门")
74 85 private java.lang.String sysOrgCode;
  86 +
  87 +
  88 + public SysRoleIndex() {
  89 +
  90 + }
  91 + public SysRoleIndex(String componentUrl){
  92 + this.component = componentUrl;
  93 + }
75 94 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysUser.java
... ... @@ -2,6 +2,7 @@ package org.jeecg.modules.system.entity;
2 2  
3 3 import java.util.Date;
4 4  
  5 +import com.baomidou.mybatisplus.annotation.TableField;
5 6 import com.baomidou.mybatisplus.annotation.TableLogic;
6 7 import com.fasterxml.jackson.annotation.JsonIgnore;
7 8 import com.fasterxml.jackson.annotation.JsonProperty;
... ... @@ -182,4 +183,10 @@ public class SysUser implements Serializable {
182 183  
183 184 /**设备id uniapp推送用*/
184 185 private String clientId;
  186 +
  187 + /**
  188 + * 登录首页地址
  189 + */
  190 + @TableField(exist = false)
  191 + private String homePath;
185 192 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java
... ... @@ -124,28 +124,28 @@ public interface SysDictMapper extends BaseMapper&lt;SysDict&gt; {
124 124 @Deprecated
125 125 public String queryTableDictTextByKey(@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("key") String key);
126 126  
127   - /**
128   - * 通过查询指定table的 text code key 获取字典值,可批量查询
129   - *
130   - * @param table
131   - * @param text
132   - * @param code
133   - * @param keys
134   - * @return
135   - */
136   - @Deprecated
137   - List<DictModel> queryTableDictTextByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keys") List<String> keys);
  127 +// /**
  128 +// * 通过查询指定table的 text code key 获取字典值,可批量查询
  129 +// *
  130 +// * @param table
  131 +// * @param text
  132 +// * @param code
  133 +// * @param keys
  134 +// * @return
  135 +// */
  136 +// @Deprecated
  137 +// List<DictModel> queryTableDictTextByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keys") List<String> keys);
138 138  
139   - /**
140   - * 通过查询指定table的 text code key 获取字典值,包含value
141   - * @param table
142   - * @param text
143   - * @param code
144   - * @param keyArray
145   - * @return List<DictModel>
146   - */
147   - @Deprecated
148   - public List<DictModel> queryTableDictByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyArray") String[] keyArray);
  139 +// D /**
  140 +//// * 通过查询指定table的 text code key 获取字典值,包含value
  141 +//// * @param table
  142 +//// * @param text
  143 +//// * @param code
  144 +//// * @param keyArray
  145 +//// * @return List<DictModel>
  146 +//// */
  147 +//// @Deprecated
  148 +//// public List<DictModel> queryTableictByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyArray") String[] keyArray);
149 149  
150 150 /**
151 151 * 查询所有部门 作为字典信息 id -->value,departName -->text
... ... @@ -159,28 +159,28 @@ public interface SysDictMapper extends BaseMapper&lt;SysDict&gt; {
159 159 */
160 160 public List<DictModel> queryAllUserBackDictModel();
161 161  
162   - /**
163   - * 通过关键字查询出字典表
164   - * @param table
165   - * @param text
166   - * @param code
167   - * @param keyword
168   - * @return
169   - */
170   - @Deprecated
171   - public List<DictModel> queryTableDictItems(@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("keyword") String keyword);
  162 +// /**
  163 +// * 通过关键字查询出字典表
  164 +// * @param table
  165 +// * @param text
  166 +// * @param code
  167 +// * @param keyword
  168 +// * @return
  169 +// */
  170 +// @Deprecated
  171 +// public List<DictModel> queryTableDictItems(@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("keyword") String keyword);
172 172  
173 173  
174   - /**
175   - * 通过关键字查询出字典表
176   - * @param page
177   - * @param table
178   - * @param text
179   - * @param code
180   - * @param keyword
181   - * @return
182   - */
183   - IPage<DictModel> queryTableDictItems(Page<DictModel> page, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyword") String keyword);
  174 +// /**
  175 +// * 通过关键字查询出字典表
  176 +// * @param page
  177 +// * @param table
  178 +// * @param text
  179 +// * @param code
  180 +// * @param keyword
  181 +// * @return
  182 +// */
  183 +// //IPage<DictModel> queryTableDictItems(Page<DictModel> page, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyword") String keyword);
184 184  
185 185 /**
186 186 * 根据表名、显示字段名、存储字段名 查询树
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysRoleMapper.java
... ... @@ -18,16 +18,17 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
18 18 public interface SysRoleMapper extends BaseMapper<SysRole> {
19 19  
20 20 /**
21   - * @Description: 删除角色与用户关系
  21 + * 删除角色与用户关系
22 22 * @Author scott
23 23 * @Date 2019/12/13 16:12
  24 + * @param roleId
24 25 */
25 26 @Delete("delete from sys_user_role where role_id = #{roleId}")
26 27 void deleteRoleUserRelation(@Param("roleId") String roleId);
27 28  
28 29  
29 30 /**
30   - * @Description: 删除角色与权限关系
  31 + * 删除角色与权限关系
31 32 * @Author scott
32 33 * @param roleId
33 34 * @Date 2019/12/13 16:12
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysCategoryMapper.xml
... ... @@ -11,9 +11,25 @@
11 11 from sys_category
12 12 where pid = #{pid}
13 13 <if test="query!= null">
14   - <foreach collection="query.entrySet()" item="value" index="key" >
15   - and ${key} = #{value}
16   - </foreach>
  14 + <if test="query.code !=null and query.code != ''">
  15 + and code = #{query.code}
  16 + </if>
  17 +
  18 + <if test="query.name !=null and query.name != ''">
  19 + and name = #{query.name}
  20 + </if>
  21 +
  22 + <if test="query.id !=null and query.id != ''">
  23 + and id = #{query.id}
  24 + </if>
  25 +
  26 + <if test="query.createBy !=null and query.createBy != ''">
  27 + and create_by = #{query.createBy}
  28 + </if>
  29 +
  30 + <if test="query.sysOrgCode !=null and query.sysOrgCode != ''">
  31 + and sys_org_code = #{query.sysOrgCode}
  32 + </if>
17 33 </if>
18 34 </select>
19 35  
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml
... ... @@ -80,22 +80,22 @@
80 80 select ${text} as "text" from ${table} where ${code}= #{key}
81 81 </select>
82 82  
83   - <!--通过查询指定table的 text code key 获取字典值,可批量查询-->
  83 + <!--通过查询指定table的 text code key 获取字典值,可批量查询
84 84 <select id="queryTableDictTextByKeys" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
85 85 select ${text} as "text", ${code} as "value" from ${table} where ${code} IN (
86 86 <foreach item="key" collection="keys" separator=",">
87 87 #{key}
88 88 </foreach>
89 89 )
90   - </select>
  90 + </select>-->
91 91  
92   - <!--通过查询指定table的 text code key 获取字典值,包含value-->
  92 + <!--通过查询指定table的 text code key 获取字典值,包含value
93 93 <select id="queryTableDictByKeys" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
94 94 select ${text} as "text", ${code} as "value" from ${table} where ${code} in
95 95 <foreach item="key" collection="keyArray" open="(" separator="," close=")">
96 96 #{key}
97 97 </foreach>
98   - </select>
  98 + </select>-->
99 99  
100 100 <!-- 重复校验 sql语句 -->
101 101 <select id="duplicateCheckCountSql" resultType="Long" parameterType="org.jeecg.modules.system.model.DuplicateCheckVo">
... ... @@ -117,10 +117,10 @@
117 117 select username as "value",realname as "text" from sys_user where del_flag = '0'
118 118 </select>
119 119  
120   - <!--通过查询指定table的 text code 获取字典数据,且支持关键字查询 -->
  120 + <!--通过查询指定table的 text code 获取字典数据,且支持关键字查询
121 121 <select id="queryTableDictItems" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
122 122 select ${text} as "text",${code} as "value" from ${table} where ${text} like #{keyword}
123   - </select>
  123 + </select> -->
124 124  
125 125 <!-- 根据表名、显示字段名、存储字段名、父ID查询树 -->
126 126 <select id="queryTreeList" parameterType="Object" resultType="org.jeecg.modules.system.model.TreeSelectModel">
... ... @@ -150,6 +150,16 @@
150 150 <foreach collection="query.entrySet()" item="value" index="key" >
151 151 and ${key} LIKE #{value}
152 152 </foreach>
  153 + <!-- udapte-end-author:sunjianlei date:20220615 for: 【issues/3709】自定义树查询条件没有处理父ID,没有树状结构了 -->
  154 + <choose>
  155 + <when test="pid != null and pid != ''">
  156 + and ${pidField} = #{pid}
  157 + </when>
  158 + <otherwise>
  159 + and (${pidField} = '' OR ${pidField} IS NULL)
  160 + </otherwise>
  161 + </choose>
  162 + <!-- udapte-end-author:sunjianlei date:20220615 for: 【issues/3709】自定义树查询条件没有处理父ID,没有树状结构了 -->
153 163 </if>
154 164 <!-- udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】自定义树查询条件查不出数据 -->
155 165 </select>
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/model/SysPermissionTree.java
... ... @@ -52,6 +52,11 @@ public class SysPermissionTree implements Serializable {
52 52 private String component;
53 53  
54 54 /**
  55 + * 组件名字
  56 + */
  57 + private String componentName;
  58 +
  59 + /**
55 60 * 跳转网页链接
56 61 */
57 62 private String url;
... ... @@ -141,6 +146,7 @@ public class SysPermissionTree implements Serializable {
141 146 this.perms = permission.getPerms();
142 147 this.permsType = permission.getPermsType();
143 148 this.component = permission.getComponent();
  149 + this.componentName = permission.getComponentName();
144 150 this.createBy = permission.getCreateBy();
145 151 this.createTime = permission.getCreateTime();
146 152 this.delFlag = permission.getDelFlag();
... ... @@ -266,6 +272,14 @@ public class SysPermissionTree implements Serializable {
266 272 this.component = component;
267 273 }
268 274  
  275 + public String getComponentName() {
  276 + return componentName;
  277 + }
  278 +
  279 + public void setComponentName(String componentName) {
  280 + this.componentName = componentName;
  281 + }
  282 +
269 283 public String getUrl() {
270 284 return url;
271 285 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/security/DictQueryBlackListHandler.java
1 1 package org.jeecg.modules.system.security;
2 2  
  3 +import org.jeecg.common.constant.CommonConstant;
3 4 import org.jeecg.common.constant.SymbolConstant;
4 5 import org.jeecg.common.util.oConvertUtils;
5 6 import org.jeecg.common.util.security.AbstractQueryBlackListHandler;
... ... @@ -32,8 +33,9 @@ public class DictQueryBlackListHandler extends AbstractQueryBlackListHandler {
32 33 QueryTable table = new QueryTable(tableName, "");
33 34 // 无论什么场景 第二、三个元素一定是表的字段,直接add
34 35 table.addField(arr[1].trim());
35   - if (oConvertUtils.isNotEmpty(arr[2].trim())) {
36   - table.addField(arr[2].trim());
  36 + String filed = arr[2].trim();
  37 + if (oConvertUtils.isNotEmpty(filed)) {
  38 + table.addField(filed);
37 39 }
38 40 List<QueryTable> list = new ArrayList<>();
39 41 list.add(table);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysCategoryService.java
... ... @@ -20,6 +20,11 @@ public interface ISysCategoryService extends IService&lt;SysCategory&gt; {
20 20 public static final String ROOT_PID_VALUE = "0";
21 21  
22 22 /**
  23 + * 存在子节点
  24 + */
  25 + public static final String HAS_CHILD = "1";
  26 +
  27 + /**
23 28 * 添加分类字典
24 29 * @param sysCategory
25 30 */
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDataSourceService.java
1 1 package org.jeecg.modules.system.service;
2 2  
3 3 import com.baomidou.mybatisplus.extension.service.IService;
  4 +import org.jeecg.common.api.vo.Result;
4 5 import org.jeecg.modules.system.entity.SysDataSource;
5 6  
6 7 /**
... ... @@ -11,4 +12,25 @@ import org.jeecg.modules.system.entity.SysDataSource;
11 12 */
12 13 public interface ISysDataSourceService extends IService<SysDataSource> {
13 14  
  15 + /**
  16 + * 添加数据源
  17 + * @param sysDataSource
  18 + * @return
  19 + */
  20 + Result saveDataSource(SysDataSource sysDataSource);
  21 +
  22 + /**
  23 + * 修改数据源
  24 + * @param sysDataSource
  25 + * @return
  26 + */
  27 + Result editDataSource(SysDataSource sysDataSource);
  28 +
  29 +
  30 + /**
  31 + * 删除数据源
  32 + * @param id
  33 + * @return
  34 + */
  35 + Result deleteDataSource(String id);
14 36 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java
... ... @@ -127,9 +127,10 @@ public interface ISysDepartService extends IService&lt;SysDepart&gt;{
127 127 * 获取我的部门下级所有部门
128 128 * @param parentId 父id
129 129 * @param ids 多个部门id
  130 + * @param primaryKey 主键字段(id或者orgCode)
130 131 * @return
131 132 */
132   - List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids);
  133 + List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids, String primaryKey);
133 134  
134 135 /**
135 136 * 获取某个部门的所有父级部门的ID
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDictService.java
... ... @@ -158,16 +158,16 @@ public interface ISysDictService extends IService&lt;SysDict&gt; {
158 158 */
159 159 public List<DictModel> queryAllUserBackDictModel();
160 160  
161   - /**
162   - * 通过关键字查询字典表
163   - * @param table
164   - * @param text
165   - * @param code
166   - * @param keyword
167   - * @return
168   - */
169   - @Deprecated
170   - public List<DictModel> queryTableDictItems(String table, String text, String code,String keyword);
  161 +// /**
  162 +// * 通过关键字查询字典表
  163 +// * @param table
  164 +// * @param text
  165 +// * @param code
  166 +// * @param keyword
  167 +// * @return
  168 +// */
  169 +// @Deprecated
  170 +// public List<DictModel> queryTableDictItems(String table, String text, String code,String keyword);
171 171  
172 172 /**
173 173 * 查询字典表数据 只查询前10条
... ... @@ -179,6 +179,7 @@ public interface ISysDictService extends IService&lt;SysDict&gt; {
179 179 * @param pageSize 每页条数
180 180 * @return
181 181 */
  182 + @Deprecated
182 183 public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize);
183 184  
184 185 /**
... ... @@ -190,6 +191,7 @@ public interface ISysDictService extends IService&lt;SysDict&gt; {
190 191 * @param keyword
191 192 * @return
192 193 */
  194 + @Deprecated
193 195 public List<DictModel> queryAllTableDictItems(String table, String text, String code, String condition, String keyword);
194 196 /**
195 197 * 根据表名、显示字段名、存储字段名 查询树
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java
... ... @@ -49,8 +49,10 @@ public interface ISysUserDepartService extends IService&lt;SysUserDepart&gt; {
49 49 * @param username
50 50 * @param pageSize
51 51 * @param pageNo
  52 + * @param realname
  53 + * @param id
52 54 * @return
53 55 */
54   - IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo);
  56 + IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id);
55 57  
56 58 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserService.java
... ... @@ -6,7 +6,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
6 6 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
7 7 import com.baomidou.mybatisplus.extension.service.IService;
8 8 import org.jeecg.common.api.vo.Result;
  9 +import org.jeecg.common.system.vo.LoginUser;
9 10 import org.jeecg.common.system.vo.SysUserCacheInfo;
  11 +import org.jeecg.modules.system.entity.SysRoleIndex;
10 12 import org.jeecg.modules.system.entity.SysUser;
11 13 import org.jeecg.modules.system.model.SysUserSysDepartModel;
12 14 import org.springframework.transaction.annotation.Transactional;
... ... @@ -87,12 +89,22 @@ public interface ISysUserService extends IService&lt;SysUser&gt; {
87 89 * @return
88 90 */
89 91 public List<String> getRole(String username);
  92 +
  93 + /**
  94 + * 获取根据登录用户的角色获取动态首页
  95 + *
  96 + * @param username
  97 + * @param version 前端UI版本
  98 + * @return
  99 + */
  100 + public SysRoleIndex getDynamicIndexByUserRole(String username,String version);
90 101  
91 102 /**
92 103 * 查询用户信息包括 部门信息
93 104 * @param username
94 105 * @return
95 106 */
  107 + @Deprecated
96 108 public SysUserCacheInfo getCacheUser(String username);
97 109  
98 110 /**
... ... @@ -175,6 +187,7 @@ public interface ISysUserService extends IService&lt;SysUser&gt; {
175 187 /**
176 188 * 根据手机号获取用户名和密码
177 189 * @param phone 手机号
  190 + * @return SysUser
178 191 */
179 192 public SysUser getUserByPhone(String phone);
180 193  
... ... @@ -280,4 +293,12 @@ public interface ISysUserService extends IService&lt;SysUser&gt; {
280 293 */
281 294 List<String> userIdToUsername(Collection<String> userIdList);
282 295  
  296 +
  297 + /**
  298 + * 获取用户信息 字段信息是加密后的 【加密用户信息】
  299 + * @param username
  300 + * @return
  301 + */
  302 + LoginUser getEncodeUserInfo(String username);
  303 +
283 304 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java
1 1 package org.jeecg.modules.system.service.impl;
  2 +
2 3 import com.alibaba.fastjson.JSON;
3 4 import com.alibaba.fastjson.JSONObject;
4 5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
... ... @@ -14,19 +15,22 @@ import org.apache.shiro.SecurityUtils;
14 15 import org.jeecg.common.api.dto.OnlineAuthDTO;
15 16 import org.jeecg.common.api.dto.message.*;
16 17 import org.jeecg.common.aspect.UrlMatchEnum;
17   -import org.jeecg.common.constant.CacheConstant;
18   -import org.jeecg.common.constant.CommonConstant;
19   -import org.jeecg.common.constant.DataBaseConstant;
20   -import org.jeecg.common.constant.WebsocketConst;
  18 +import org.jeecg.common.constant.*;
  19 +import org.jeecg.common.constant.enums.MessageTypeEnum;
  20 +import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
21 21 import org.jeecg.common.exception.JeecgBootException;
22 22 import org.jeecg.common.system.api.ISysBaseAPI;
23 23 import org.jeecg.common.system.query.QueryGenerator;
24 24 import org.jeecg.common.system.vo.*;
25 25 import org.jeecg.common.util.SysAnnmentTypeEnum;
26 26 import org.jeecg.common.util.YouBianCodeUtil;
  27 +import org.jeecg.common.util.dynamic.db.FreemarkerParseFactory;
27 28 import org.jeecg.common.util.oConvertUtils;
28 29 import org.jeecg.modules.message.entity.SysMessageTemplate;
  30 +import org.jeecg.modules.message.handle.impl.DdSendMsgHandle;
29 31 import org.jeecg.modules.message.handle.impl.EmailSendMsgHandle;
  32 +import org.jeecg.modules.message.handle.impl.QywxSendMsgHandle;
  33 +import org.jeecg.modules.message.handle.impl.SystemSendMsgHandle;
30 34 import org.jeecg.modules.message.service.ISysMessageTemplateService;
31 35 import org.jeecg.modules.message.websocket.WebSocket;
32 36 import org.jeecg.modules.system.entity.*;
... ... @@ -58,11 +62,10 @@ import java.util.*;
58 62 public class SysBaseApiImpl implements ISysBaseAPI {
59 63 /** 当前系统数据库类型 */
60 64 private static String DB_TYPE = "";
  65 +
61 66 @Autowired
62 67 private ISysMessageTemplateService sysMessageTemplateService;
63 68 @Resource
64   - private SysLogMapper sysLogMapper;
65   - @Resource
66 69 private SysUserMapper userMapper;
67 70 @Resource
68 71 private SysUserRoleMapper sysUserRoleMapper;
... ... @@ -82,7 +85,6 @@ public class SysBaseApiImpl implements ISysBaseAPI {
82 85 private SysDepartMapper departMapper;
83 86 @Resource
84 87 private SysCategoryMapper categoryMapper;
85   -
86 88 @Autowired
87 89 private ISysDataSourceService dataSourceService;
88 90 @Autowired
... ... @@ -91,28 +93,33 @@ public class SysBaseApiImpl implements ISysBaseAPI {
91 93 private SysPermissionMapper sysPermissionMapper;
92 94 @Autowired
93 95 private ISysPermissionDataRuleService sysPermissionDataRuleService;
94   -
95 96 @Autowired
96 97 private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
97 98 @Autowired
98 99 private ThirdAppDingtalkServiceImpl dingtalkService;
99   -
100 100 @Autowired
101 101 ISysCategoryService sysCategoryService;
  102 + @Autowired
  103 + private ISysUserService sysUserService;
102 104  
103 105 @Override
104   - @Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
  106 + //@SensitiveDecode
105 107 public LoginUser getUserByName(String username) {
106   - if(oConvertUtils.isEmpty(username)) {
  108 + //update-begin-author:taoyan date:2022-6-6 for: VUEN-1276 【v3流程图】测试bug 1、通过我发起的流程或者流程实例,查看历史,流程图预览问题
  109 + if (oConvertUtils.isEmpty(username)) {
107 110 return null;
108 111 }
109   - LoginUser loginUser = new LoginUser();
110   - SysUser sysUser = userMapper.getUserByName(username);
111   - if(sysUser==null) {
112   - return null;
  112 + //update-end-author:taoyan date:2022-6-6 for: VUEN-1276 【v3流程图】测试bug 1、通过我发起的流程或者流程实例,查看历史,流程图预览问题
  113 + LoginUser user = sysUserService.getEncodeUserInfo(username);
  114 +
  115 + //相同类中方法间调用时脱敏解密 Aop会失效,获取用户信息太重要,此处采用原生解密方法,不采用@SensitiveDecodeAble注解方式
  116 + try {
  117 + SensitiveInfoUtil.handlerObject(user, false);
  118 + } catch (IllegalAccessException e) {
  119 + e.printStackTrace();
113 120 }
114   - BeanUtils.copyProperties(sysUser, loginUser);
115   - return loginUser;
  121 +
  122 + return user;
116 123 }
117 124  
118 125 @Override
... ... @@ -204,6 +211,14 @@ public class SysBaseApiImpl implements ISysBaseAPI {
204 211 SysUserCacheInfo info = new SysUserCacheInfo();
205 212 info.setOneDepart(true);
206 213 LoginUser user = this.getUserByName(username);
  214 +
  215 +// try {
  216 +// //相同类中方法间调用时脱敏@SensitiveDecodeAble解密 Aop失效处理
  217 +// SensitiveInfoUtil.handlerObject(user, false);
  218 +// } catch (IllegalAccessException e) {
  219 +// e.printStackTrace();
  220 +// }
  221 +
207 222 if(user!=null) {
208 223 info.setSysUserCode(user.getUsername());
209 224 info.setSysUserName(user.getRealname());
... ... @@ -290,7 +305,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
290 305 @Override
291 306 public List<DictModel> queryTableDictItemsByCode(String table, String text, String code) {
292 307 //update-begin-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑,想法不错 LOWCOD-799
293   - if(table.indexOf("#{")>=0){
  308 + if(table.indexOf(SymbolConstant.SYS_VAR_PREFIX)>=0){
294 309 table = QueryGenerator.getSqlRuleValue(table);
295 310 }
296 311 //update-end-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑,想法不错 LOWCOD-799
... ... @@ -528,15 +543,15 @@ public class SysBaseApiImpl implements ISysBaseAPI {
528 543 try {
529 544 DatabaseMetaData md = connection.getMetaData();
530 545 String dbType = md.getDatabaseProductName().toLowerCase();
531   - if(dbType.indexOf("mysql")>=0) {
  546 + if(dbType.indexOf(DataBaseConstant.DB_TYPE_MYSQL.toLowerCase())>=0) {
532 547 DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL;
533   - }else if(dbType.indexOf("oracle")>=0) {
  548 + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_ORACLE.toLowerCase())>=0) {
534 549 DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE;
535   - }else if(dbType.indexOf("sqlserver")>=0||dbType.indexOf("sql server")>=0) {
  550 + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_SQLSERVER.toLowerCase())>=0||dbType.indexOf(DataBaseConstant.DB_TYPE_SQL_SERVER_BLANK)>=0) {
536 551 DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
537   - }else if(dbType.indexOf("postgresql")>=0) {
  552 + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_POSTGRESQL.toLowerCase())>=0) {
538 553 DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
539   - }else if(dbType.indexOf("mariadb")>=0) {
  554 + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_MARIADB.toLowerCase())>=0) {
540 555 DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
541 556 }else {
542 557 log.error("数据库类型:[" + dbType + "]不识别!");
... ... @@ -777,6 +792,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
777 792 if(userDepartList != null){
778 793 //查找所属公司
779 794 String orgCodes = "";
  795 + StringBuilder orgCodesBuilder = new StringBuilder();
  796 + orgCodesBuilder.append(orgCodes);
780 797 for(SysUserDepart userDepart : userDepartList){
781 798 //查询所属公司编码
782 799 SysDepart depart = sysDepartService.getById(userDepart.getDepId());
... ... @@ -785,10 +802,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
785 802 if(depart != null && depart.getOrgCode() != null){
786 803 compyOrgCode = depart.getOrgCode().substring(0,length);
787 804 if(orgCodes.indexOf(compyOrgCode) == -1){
788   - orgCodes = orgCodes + "," + compyOrgCode;
  805 + orgCodesBuilder.append(SymbolConstant.COMMA).append(compyOrgCode);
789 806 }
790 807 }
791 808 }
  809 + orgCodes = orgCodesBuilder.toString();
792 810 if(oConvertUtils.isNotEmpty(orgCodes)){
793 811 orgCodes = orgCodes.substring(1);
794 812 List<String> listIds = departMapper.getSubDepIdsByOrgCodes(orgCodes.split(","));
... ... @@ -1037,7 +1055,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
1037 1055 @Override
1038 1056 public void sendEmailMsg(String email, String title, String content) {
1039 1057 EmailSendMsgHandle emailHandle=new EmailSendMsgHandle();
1040   - emailHandle.SendMsg(email, title, content);
  1058 + emailHandle.sendMsg(email, title, content);
1041 1059 }
1042 1060  
1043 1061 /**
... ... @@ -1154,4 +1172,54 @@ public class SysBaseApiImpl implements ISysBaseAPI {
1154 1172 return sysDictService.queryTableDictTextByKeys(table, text, code, Arrays.asList(keys.split(",")));
1155 1173 }
1156 1174  
  1175 + //-------------------------------------流程节点发送模板消息-----------------------------------------------
  1176 + @Autowired
  1177 + private QywxSendMsgHandle qywxSendMsgHandle;
  1178 +
  1179 + @Autowired
  1180 + private SystemSendMsgHandle systemSendMsgHandle;
  1181 +
  1182 + @Autowired
  1183 + private EmailSendMsgHandle emailSendMsgHandle;
  1184 +
  1185 + @Autowired
  1186 + private DdSendMsgHandle ddSendMsgHandle;
  1187 +
  1188 + @Override
  1189 + public void sendTemplateMessage(MessageDTO message) {
  1190 + String messageType = message.getType();
  1191 + //update-begin-author:taoyan date:2022-7-9 for: 将模板解析代码移至消息发送, 而不是调用的地方
  1192 + String templateCode = message.getTemplateCode();
  1193 + if(oConvertUtils.isNotEmpty(templateCode)){
  1194 + String content = getTemplateContent(templateCode);
  1195 + if(oConvertUtils.isNotEmpty(content) && null!=message.getData()){
  1196 + content = FreemarkerParseFactory.parseTemplateContent(content, message.getData());
  1197 + }
  1198 + message.setContent(content);
  1199 + }
  1200 + if(oConvertUtils.isEmpty(message.getContent())){
  1201 + throw new JeecgBootException("发送消息失败,消息内容为空!");
  1202 + }
  1203 + //update-end-author:taoyan date:2022-7-9 for: 将模板解析代码移至消息发送, 而不是调用的地方
  1204 + if(MessageTypeEnum.XT.getType().equals(messageType)){
  1205 + systemSendMsgHandle.sendMessage(message);
  1206 + }else if(MessageTypeEnum.YJ.getType().equals(messageType)){
  1207 + emailSendMsgHandle.sendMessage(message);
  1208 + }else if(MessageTypeEnum.DD.getType().equals(messageType)){
  1209 + ddSendMsgHandle.sendMessage(message);
  1210 + }else if(MessageTypeEnum.QYWX.getType().equals(messageType)){
  1211 + qywxSendMsgHandle.sendMessage(message);
  1212 + }
  1213 + }
  1214 +
  1215 + @Override
  1216 + public String getTemplateContent(String code) {
  1217 + List<SysMessageTemplate> list = sysMessageTemplateService.selectByCode(code);
  1218 + if(list==null || list.size()==0){
  1219 + return null;
  1220 + }
  1221 + return list.get(0).getTemplateContent();
  1222 + }
  1223 + //-------------------------------------流程节点发送模板消息-----------------------------------------------
  1224 +
1157 1225 }
1158 1226 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java
... ... @@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
5 5 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
6 6 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
7 7 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  8 +import org.jeecg.common.constant.CommonConstant;
8 9 import org.jeecg.common.constant.FillRuleConstant;
  10 +import org.jeecg.common.constant.SymbolConstant;
9 11 import org.jeecg.common.exception.JeecgBootException;
10 12 import org.jeecg.common.util.FillRuleUtil;
11 13 import org.jeecg.common.util.oConvertUtils;
... ... @@ -43,8 +45,8 @@ public class SysCategoryServiceImpl extends ServiceImpl&lt;SysCategoryMapper, SysCa
43 45 if(!ISysCategoryService.ROOT_PID_VALUE.equals(categoryPid)){
44 46 SysCategory parent = baseMapper.selectById(categoryPid);
45 47 parentCode = parent.getCode();
46   - if(parent!=null && !"1".equals(parent.getHasChild())){
47   - parent.setHasChild("1");
  48 + if(parent!=null && !ISysCategoryService.HAS_CHILD.equals(parent.getHasChild())){
  49 + parent.setHasChild(ISysCategoryService.HAS_CHILD);
48 50 baseMapper.updateById(parent);
49 51 }
50 52 }
... ... @@ -66,8 +68,8 @@ public class SysCategoryServiceImpl extends ServiceImpl&lt;SysCategoryMapper, SysCa
66 68 }else{
67 69 //如果当前节点父ID不为空 则设置父节点的hasChild 为1
68 70 SysCategory parent = baseMapper.selectById(sysCategory.getPid());
69   - if(parent!=null && !"1".equals(parent.getHasChild())){
70   - parent.setHasChild("1");
  71 + if(parent!=null && !ISysCategoryService.HAS_CHILD.equals(parent.getHasChild())){
  72 + parent.setHasChild(ISysCategoryService.HAS_CHILD);
71 73 baseMapper.updateById(parent);
72 74 }
73 75 }
... ... @@ -170,14 +172,15 @@ public class SysCategoryServiceImpl extends ServiceImpl&lt;SysCategoryMapper, SysCa
170 172 queryWrapper.eq(SysCategory::getPid,metaPid);
171 173 queryWrapper.notIn(SysCategory::getId,Arrays.asList(idArr));
172 174 List<SysCategory> dataList = this.baseMapper.selectList(queryWrapper);
173   - if((dataList == null || dataList.size()==0) && !Arrays.asList(idArr).contains(metaPid)
174   - && !sb.toString().contains(metaPid)){
  175 + boolean flag = (dataList == null || dataList.size()==0) && !Arrays.asList(idArr).contains(metaPid)
  176 + && !sb.toString().contains(metaPid);
  177 + if(flag){
175 178 //如果当前节点原本有子节点 现在木有了,更新状态
176 179 sb.append(metaPid).append(",");
177 180 }
178 181 }
179 182 }
180   - if(sb.toString().endsWith(",")){
  183 + if(sb.toString().endsWith(SymbolConstant.COMMA)){
181 184 sb = sb.deleteCharAt(sb.length() - 1);
182 185 }
183 186 return sb.toString();
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDataSourceServiceImpl.java
1 1 package org.jeecg.modules.system.service.impl;
2 2  
  3 +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
  4 +import com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator;
  5 +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
  6 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
3 7 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  8 +import org.apache.commons.lang.StringUtils;
  9 +import org.jeecg.common.api.vo.Result;
  10 +import org.jeecg.common.util.dynamic.db.DataSourceCachePool;
4 11 import org.jeecg.modules.system.entity.SysDataSource;
5 12 import org.jeecg.modules.system.mapper.SysDataSourceMapper;
6 13 import org.jeecg.modules.system.service.ISysDataSourceService;
  14 +import org.jeecg.modules.system.util.SecurityUtil;
  15 +import org.springframework.beans.factory.annotation.Autowired;
7 16 import org.springframework.stereotype.Service;
8 17  
  18 +import javax.sql.DataSource;
  19 +
9 20 /**
10 21 * @Description: 多数据源管理
11 22 * @Author: jeecg-boot
... ... @@ -15,4 +26,106 @@ import org.springframework.stereotype.Service;
15 26 @Service
16 27 public class SysDataSourceServiceImpl extends ServiceImpl<SysDataSourceMapper, SysDataSource> implements ISysDataSourceService {
17 28  
  29 + @Autowired
  30 + private DruidDataSourceCreator dataSourceCreator;
  31 +
  32 + @Autowired
  33 + private DataSource dataSource;
  34 +
  35 + @Override
  36 + public Result saveDataSource(SysDataSource sysDataSource) {
  37 + try {
  38 + long count = checkDbCode(sysDataSource.getCode());
  39 + if (count > 0) {
  40 + return Result.error("数据源编码已存在");
  41 + }
  42 + String dbPassword = sysDataSource.getDbPassword();
  43 + if (StringUtils.isNotBlank(dbPassword)) {
  44 + String encrypt = SecurityUtil.jiami(dbPassword);
  45 + sysDataSource.setDbPassword(encrypt);
  46 + }
  47 + boolean result = save(sysDataSource);
  48 + if (result) {
  49 + //动态创建数据源
  50 + //addDynamicDataSource(sysDataSource, dbPassword);
  51 + }
  52 + } catch (Exception e) {
  53 + e.printStackTrace();
  54 + }
  55 + return Result.OK("添加成功!");
  56 + }
  57 +
  58 + @Override
  59 + public Result editDataSource(SysDataSource sysDataSource) {
  60 + try {
  61 + SysDataSource d = getById(sysDataSource.getId());
  62 + DataSourceCachePool.removeCache(d.getCode());
  63 + String dbPassword = sysDataSource.getDbPassword();
  64 + if (StringUtils.isNotBlank(dbPassword)) {
  65 + String encrypt = SecurityUtil.jiami(dbPassword);
  66 + sysDataSource.setDbPassword(encrypt);
  67 + }
  68 + Boolean result=updateById(sysDataSource);
  69 + if(result){
  70 + //先删除老的数据源
  71 + // removeDynamicDataSource(d.getCode());
  72 + //添加新的数据源
  73 + //addDynamicDataSource(sysDataSource,dbPassword);
  74 + }
  75 + } catch (Exception e) {
  76 + e.printStackTrace();
  77 + }
  78 + return Result.OK("编辑成功!");
  79 + }
  80 +
  81 + @Override
  82 + public Result deleteDataSource(String id) {
  83 + SysDataSource sysDataSource = getById(id);
  84 + DataSourceCachePool.removeCache(sysDataSource.getCode());
  85 + removeById(id);
  86 + return Result.OK("删除成功!");
  87 + }
  88 +
  89 + /**
  90 + * 动态添加数据源 【注册mybatis动态数据源】
  91 + *
  92 + * @param sysDataSource 添加数据源数据对象
  93 + * @param dbPassword 未加密的密码
  94 + */
  95 + private void addDynamicDataSource(SysDataSource sysDataSource, String dbPassword) {
  96 + DataSourceProperty dataSourceProperty = new DataSourceProperty();
  97 + dataSourceProperty.setUrl(sysDataSource.getDbUrl());
  98 + dataSourceProperty.setPassword(dbPassword);
  99 + dataSourceProperty.setDriverClassName(sysDataSource.getDbDriver());
  100 + dataSourceProperty.setUsername(sysDataSource.getDbUsername());
  101 + DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
  102 + DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty);
  103 + try {
  104 + ds.addDataSource(sysDataSource.getCode(), dataSource);
  105 + } catch (Exception e) {
  106 + e.printStackTrace();
  107 + }
  108 + }
  109 +
  110 + /**
  111 + * 删除数据源
  112 + * @param code
  113 + */
  114 + private void removeDynamicDataSource(String code) {
  115 + DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
  116 + ds.removeDataSource(code);
  117 + }
  118 +
  119 + /**
  120 + * 检查数据源编码是否存在
  121 + *
  122 + * @param dbCode
  123 + * @return
  124 + */
  125 + private long checkDbCode(String dbCode) {
  126 + QueryWrapper<SysDataSource> qw = new QueryWrapper();
  127 + qw.lambda().eq(true, SysDataSource::getCode, dbCode);
  128 + return count(qw);
  129 + }
  130 +
18 131 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java
... ... @@ -10,6 +10,7 @@ import org.apache.commons.lang.StringUtils;
10 10 import org.jeecg.common.constant.CacheConstant;
11 11 import org.jeecg.common.constant.CommonConstant;
12 12 import org.jeecg.common.constant.FillRuleConstant;
  13 +import org.jeecg.common.constant.SymbolConstant;
13 14 import org.jeecg.common.util.FillRuleUtil;
14 15 import org.jeecg.common.util.YouBianCodeUtil;
15 16 import org.jeecg.common.util.oConvertUtils;
... ... @@ -469,14 +470,14 @@ public class SysDepartServiceImpl extends ServiceImpl&lt;SysDepartMapper, SysDepart
469 470 */
470 471 private String getMinLengthNode(String[] str){
471 472 int min =str[0].length();
472   - String orgCode = str[0];
  473 + StringBuilder orgCodeBuilder = new StringBuilder(str[0]);
473 474 for(int i =1;i<str.length;i++){
474 475 if(str[i].length()<=min){
475 476 min = str[i].length();
476   - orgCode = orgCode+","+str[i];
  477 + orgCodeBuilder.append(SymbolConstant.COMMA).append(str[i]);
477 478 }
478 479 }
479   - return orgCode;
  480 + return orgCodeBuilder.toString();
480 481 }
481 482 /**
482 483 * 获取部门树信息根据关键字
... ... @@ -504,13 +505,18 @@ public class SysDepartServiceImpl extends ServiceImpl&lt;SysDepartMapper, SysDepart
504 505 * 根据parentId查询部门树
505 506 * @param parentId
506 507 * @param ids 前端回显传递
  508 + * @param primaryKey 主键字段(id或者orgCode)
507 509 * @return
508 510 */
509 511 @Override
510   - public List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids) {
  512 + public List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids, String primaryKey) {
511 513 Consumer<LambdaQueryWrapper<SysDepart>> square = i -> {
512 514 if (oConvertUtils.isNotEmpty(ids)) {
513   - i.in(SysDepart::getId, ids.split(","));
  515 + if (CommonConstant.DEPART_KEY_ORG_CODE.equals(primaryKey)) {
  516 + i.in(SysDepart::getOrgCode, ids.split(SymbolConstant.COMMA));
  517 + } else {
  518 + i.in(SysDepart::getId, ids.split(SymbolConstant.COMMA));
  519 + }
514 520 } else {
515 521 if(oConvertUtils.isEmpty(parentId)){
516 522 i.and(q->q.isNull(true,SysDepart::getParentId).or().eq(true,SysDepart::getParentId,""));
... ... @@ -519,10 +525,12 @@ public class SysDepartServiceImpl extends ServiceImpl&lt;SysDepartMapper, SysDepart
519 525 }
520 526 }
521 527 };
522   - LambdaQueryWrapper<SysDepart> lqw=new LambdaQueryWrapper();
  528 + LambdaQueryWrapper<SysDepart> lqw=new LambdaQueryWrapper<>();
523 529 lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
524 530 lqw.func(square);
525   - lqw.orderByDesc(SysDepart::getDepartOrder);
  531 + //update-begin---author:wangshuai ---date:20220527 for:[VUEN-1143]排序不对,vue3和2应该都有问题,应该按照升序排------------
  532 + lqw.orderByAsc(SysDepart::getDepartOrder);
  533 + //update-end---author:wangshuai ---date:20220527 for:[VUEN-1143]排序不对,vue3和2应该都有问题,应该按照升序排--------------
526 534 List<SysDepart> list = list(lqw);
527 535 //update-begin---author:wangshuai ---date:20220316 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
528 536 //设置用户id,让前台显示
... ... @@ -549,7 +557,7 @@ public class SysDepartServiceImpl extends ServiceImpl&lt;SysDepartMapper, SysDepart
549 557 @Override
550 558 public JSONObject queryAllParentIdByDepartId(String departId) {
551 559 JSONObject result = new JSONObject();
552   - for (String id : departId.split(",")) {
  560 + for (String id : departId.split(SymbolConstant.COMMA)) {
553 561 JSONObject all = this.queryAllParentId("id", id);
554 562 result.put(id, all);
555 563 }
... ... @@ -559,7 +567,7 @@ public class SysDepartServiceImpl extends ServiceImpl&lt;SysDepartMapper, SysDepart
559 567 @Override
560 568 public JSONObject queryAllParentIdByOrgCode(String orgCode) {
561 569 JSONObject result = new JSONObject();
562   - for (String code : orgCode.split(",")) {
  570 + for (String code : orgCode.split(SymbolConstant.COMMA)) {
563 571 JSONObject all = this.queryAllParentId("org_code", code);
564 572 result.put(code, all);
565 573 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java
... ... @@ -7,8 +7,11 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7 7 import lombok.extern.slf4j.Slf4j;
8 8 import org.jeecg.common.constant.CacheConstant;
9 9 import org.jeecg.common.constant.CommonConstant;
  10 +import org.jeecg.common.constant.DataBaseConstant;
  11 +import org.jeecg.common.constant.SymbolConstant;
10 12 import org.jeecg.common.system.query.QueryGenerator;
11 13 import org.jeecg.common.system.util.JwtUtil;
  14 +import org.jeecg.common.system.util.ResourceUtil;
12 15 import org.jeecg.common.system.vo.DictModel;
13 16 import org.jeecg.common.system.vo.DictModelMany;
14 17 import org.jeecg.common.system.vo.DictQuery;
... ... @@ -25,10 +28,7 @@ import org.springframework.cache.annotation.Cacheable;
25 28 import org.springframework.stereotype.Service;
26 29 import org.springframework.transaction.annotation.Transactional;
27 30  
28   -import java.util.ArrayList;
29   -import java.util.HashMap;
30   -import java.util.List;
31   -import java.util.Map;
  31 +import java.util.*;
32 32 import java.util.stream.Collectors;
33 33  
34 34 /**
... ... @@ -97,6 +97,10 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
97 97 }).collect(Collectors.toList());
98 98 res.put(d.getDictCode(), dictModelList);
99 99 }
  100 + //update-begin-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
  101 + Map<String, List<DictModel>> enumRes = ResourceUtil.getEnumDictData();
  102 + res.putAll(enumRes);
  103 + //update-end-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
100 104 log.debug("-------登录加载系统字典-----" + res.toString());
101 105 return res;
102 106 }
... ... @@ -123,6 +127,10 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
123 127 List<DictModel> dictItemList = dictMap.computeIfAbsent(dict.getDictCode(), i -> new ArrayList<>());
124 128 dictItemList.add(new DictModel(dict.getValue(), dict.getText()));
125 129 }
  130 + //update-begin-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
  131 + Map<String, List<DictModel>> enumRes = ResourceUtil.queryManyDictByKeys(dictCodeList, keys);
  132 + dictMap.putAll(enumRes);
  133 + //update-end-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
126 134 return dictMap;
127 135 }
128 136  
... ... @@ -167,7 +175,7 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
167 175 public List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> keys) {
168 176 //update-begin-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件
169 177 String filterSql = null;
170   - if(table.toLowerCase().indexOf("where")>0){
  178 + if(table.toLowerCase().indexOf(DataBaseConstant.SQL_WHERE)>0){
171 179 String[] arr = table.split(" (?i)where ");
172 180 table = arr[0];
173 181 filterSql = arr[1];
... ... @@ -200,7 +208,16 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
200 208 return null;
201 209 }
202 210 String[] keyArray = keys.split(",");
203   - List<DictModel> dicts = sysDictMapper.queryTableDictByKeys(table, text, code, keyArray);
  211 +
  212 + //update-begin-author:taoyan date:2022-4-24 for: 下拉搜索组件,表单编辑页面回显下拉搜索的文本的时候,因为表名后配置了条件,导致sql执行失败,
  213 + String filterSql = null;
  214 + if(table.toLowerCase().indexOf("where")!=-1){
  215 + String[] arr = table.split(" (?i)where ");
  216 + table = arr[0];
  217 + filterSql = arr[1];
  218 + }
  219 + List<DictModel> dicts = sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, Arrays.asList(keyArray));
  220 + //update-end-author:taoyan date:2022-4-24 for: 下拉搜索组件,表单编辑页面回显下拉搜索的文本的时候,因为表名后配置了条件,导致sql执行失败,
204 221 List<String> texts = new ArrayList<>(dicts.size());
205 222  
206 223 // update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
... ... @@ -261,15 +278,19 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
261 278 return baseMapper.queryAllUserBackDictModel();
262 279 }
263 280  
264   - @Override
265   - public List<DictModel> queryTableDictItems(String table, String text, String code, String keyword) {
266   - return baseMapper.queryTableDictItems(table, text, code, "%"+keyword+"%");
267   - }
  281 +// @Override
  282 +// public List<DictModel> queryTableDictItems(String table, String text, String code, String keyword) {
  283 +// return baseMapper.queryTableDictItems(table, text, code, "%"+keyword+"%");
  284 +// }
268 285  
269 286 @Override
270 287 public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize) {
271 288 Page<DictModel> page = new Page<DictModel>(1, pageSize);
272 289 page.setSearchCount(false);
  290 +
  291 + //【issues/3713】字典接口存在SQL注入风险
  292 + SqlInjectionUtil.specialFilterContentForDictSql(code);
  293 +
273 294 String filterSql = getFilterSql(table, text, code, condition, keyword);
274 295 IPage<DictModel> pageList = baseMapper.queryTableDictWithFilter(page, table, text, code, filterSql);
275 296 return pageList.getRecords();
... ... @@ -284,15 +305,15 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
284 305 * @return
285 306 */
286 307 private String getFilterSql(String table, String text, String code, String condition, String keyword){
287   - String keywordSql = null, filterSql = "", sql_where = " where ";
  308 + String keywordSql = null, filterSql = "", sqlWhere = " where ";
288 309 // update-begin-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
289   - if (table.toLowerCase().contains(" where ")) {
290   - sql_where = " and ";
  310 + if (table.toLowerCase().contains(sqlWhere)) {
  311 + sqlWhere = " and ";
291 312 }
292 313 // update-end-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
293 314 if(oConvertUtils.isNotEmpty(keyword)){
294 315 // 判断是否是多选
295   - if (keyword.contains(",")) {
  316 + if (keyword.contains(SymbolConstant.COMMA)) {
296 317 //update-begin--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致 ----
297 318 String inKeywords = "'" + String.join("','", keyword.split(",")) + "'";
298 319 //update-end--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致----
... ... @@ -302,11 +323,11 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
302 323 }
303 324 }
304 325 if(oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)){
305   - filterSql+= sql_where + condition + " and " + keywordSql;
  326 + filterSql+= sqlWhere + condition + " and " + keywordSql;
306 327 }else if(oConvertUtils.isNotEmpty(condition)){
307   - filterSql+= sql_where + condition;
  328 + filterSql+= sqlWhere + condition;
308 329 }else if(oConvertUtils.isNotEmpty(keywordSql)){
309   - filterSql+= sql_where + keywordSql;
  330 + filterSql+= sqlWhere + keywordSql;
310 331 }
311 332 return filterSql;
312 333 }
... ... @@ -319,13 +340,7 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
319 340  
320 341 @Override
321 342 public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField) {
322   - List<TreeSelectModel> result = baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField);
323   - // udapte-begin-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点
324   - if (query != null) {
325   - result.forEach(r -> r.setLeaf(true));
326   - }
327   - return result;
328   - // udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点
  343 + return baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField);
329 344 }
330 345  
331 346 @Override
... ... @@ -354,7 +369,7 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
354 369 @Override
355 370 public List<DictModel> getDictItems(String dictCode) {
356 371 List<DictModel> ls;
357   - if (dictCode.contains(",")) {
  372 + if (dictCode.contains(SymbolConstant.COMMA)) {
358 373 //关联表字典(举例:sys_user,realname,id)
359 374 String[] params = dictCode.split(",");
360 375 if (params.length < 3) {
... ... @@ -362,11 +377,16 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
362 377 return null;
363 378 }
364 379 //SQL注入校验(只限制非法串改数据库)
365   - final String[] sqlInjCheck = {params[0], params[1], params[2]};
  380 + //update-begin-author:taoyan date:2022-7-4 for: issues/I5BNY9 指定带过滤条件的字典table在生成代码后失效
  381 + // 表名后也有可能带条件and语句 不能走filterContent方法
  382 + SqlInjectionUtil.specialFilterContentForDictSql(params[0]);
  383 + final String[] sqlInjCheck = {params[1], params[2]};
  384 + //update-end-author:taoyan date:2022-7-4 for: issues/I5BNY9 指定带过滤条件的字典table在生成代码后失效
  385 + //【issues/3713】字典接口存在SQL注入风险
366 386 SqlInjectionUtil.filterContent(sqlInjCheck);
367 387 if (params.length == 4) {
368 388 // SQL注入校验(查询条件SQL 特殊check,此方法仅供此处使用)
369   - SqlInjectionUtil.specialFilterContent(params[3]);
  389 + SqlInjectionUtil.specialFilterContentForDictSql(params[3]);
370 390 ls = this.queryTableDictItemsByCodeAndFilter(params[0], params[1], params[2], params[3]);
371 391 } else if (params.length == 3) {
372 392 ls = this.queryTableDictItemsByCode(params[0], params[1], params[2]);
... ... @@ -383,7 +403,10 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
383 403  
384 404 @Override
385 405 public List<DictModel> loadDict(String dictCode, String keyword, Integer pageSize) {
386   - if (dictCode.contains(",")) {
  406 + //【issues/3713】字典接口存在SQL注入风险
  407 + SqlInjectionUtil.specialFilterContentForDictSql(dictCode);
  408 +
  409 + if (dictCode.contains(SymbolConstant.COMMA)) {
387 410 //update-begin-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件
388 411 String[] params = dictCode.split(",");
389 412 String condition = null;
... ... @@ -393,11 +416,16 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
393 416 } else if (params.length == 4) {
394 417 condition = params[3];
395 418 // update-begin-author:taoyan date:20220314 for: online表单下拉搜索框表字典配置#{sys_org_code}报错 #3500
396   - if(condition.indexOf("#{")>=0){
  419 + if(condition.indexOf(SymbolConstant.SYS_VAR_PREFIX)>=0){
397 420 condition = QueryGenerator.getSqlRuleValue(condition);
398 421 }
399 422 // update-end-author:taoyan date:20220314 for: online表单下拉搜索框表字典配置#{sys_org_code}报错 #3500
400 423 }
  424 +
  425 + // 字典Code格式不正确 [表名为空]
  426 + if(oConvertUtils.isEmpty(params[0])){
  427 + return null;
  428 + }
401 429 List<DictModel> ls;
402 430 if (pageSize != null) {
403 431 ls = this.queryLittleTableDictItems(params[0], params[1], params[2], condition, keyword, pageSize);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java
... ... @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
8 8 import lombok.extern.slf4j.Slf4j;
9 9 import org.jeecg.common.base.BaseMap;
10 10 import org.jeecg.common.constant.CacheConstant;
  11 +import org.jeecg.common.constant.CommonConstant;
11 12 import org.jeecg.common.constant.GlobalConstants;
12 13 import org.jeecg.common.util.oConvertUtils;
13 14 import org.jeecg.modules.system.entity.SysGatewayRoute;
... ... @@ -35,6 +36,7 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl&lt;SysGatewayRouteMappe
35 36 @Autowired
36 37 private RedisTemplate<String, Object> redisTemplate;
37 38  
  39 + private static final String STRING_STATUS = "status";
38 40  
39 41 @Override
40 42 public void addRoute2Redis(String key) {
... ... @@ -75,10 +77,10 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl&lt;SysGatewayRouteMappe
75 77 }
76 78 route.setFilters(filters);
77 79 route.setUri(json.getString("uri"));
78   - if (json.get("status") == null) {
  80 + if (json.get(STRING_STATUS) == null) {
79 81 route.setStatus(1);
80 82 } else {
81   - route.setStatus(json.getInteger("status"));
  83 + route.setStatus(json.getInteger(STRING_STATUS));
82 84 }
83 85 this.saveOrUpdate(route);
84 86 resreshRouter(null);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysLogServiceImpl.java
... ... @@ -31,8 +31,6 @@ public class SysLogServiceImpl extends ServiceImpl&lt;SysLogMapper, SysLog&gt; impleme
31 31  
32 32 @Resource
33 33 private SysLogMapper sysLogMapper;
34   - @Autowired
35   - private SysBaseApiImpl sysBaseAPI;
36 34  
37 35 /**
38 36 * @功能:清空所有日志记录
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionDataRuleImpl.java
... ... @@ -88,7 +88,8 @@ public class SysPermissionDataRuleImpl extends ServiceImpl&lt;SysPermissionDataRule
88 88 public void savePermissionDataRule(SysPermissionDataRule sysPermissionDataRule) {
89 89 this.save(sysPermissionDataRule);
90 90 SysPermission permission = sysPermissionMapper.selectById(sysPermissionDataRule.getPermissionId());
91   - if(permission!=null && (permission.getRuleFlag()==null || permission.getRuleFlag().equals(CommonConstant.RULE_FLAG_0))) {
  91 + boolean flag = permission != null && (permission.getRuleFlag() == null || permission.getRuleFlag().equals(CommonConstant.RULE_FLAG_0));
  92 + if(flag) {
92 93 permission.setRuleFlag(CommonConstant.RULE_FLAG_1);
93 94 sysPermissionMapper.updateById(permission);
94 95 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java
... ... @@ -200,7 +200,8 @@ public class SysPermissionServiceImpl extends ServiceImpl&lt;SysPermissionMapper, S
200 200  
201 201 //如果当前菜单的父菜单变了,则需要修改新父菜单和老父菜单的,叶子节点状态
202 202 String pid = sysPermission.getParentId();
203   - if((oConvertUtils.isNotEmpty(pid) && !pid.equals(p.getParentId())) || oConvertUtils.isEmpty(pid)&&oConvertUtils.isNotEmpty(p.getParentId())) {
  203 + boolean flag = (oConvertUtils.isNotEmpty(pid) && !pid.equals(p.getParentId())) || oConvertUtils.isEmpty(pid)&&oConvertUtils.isNotEmpty(p.getParentId());
  204 + if (flag) {
204 205 //a.设置新的父菜单不为叶子节点
205 206 this.sysPermissionMapper.setMenuLeaf(pid, 0);
206 207 //b.判断老的菜单下是否还有其他子菜单,没有的话则设置为叶子节点
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java
... ... @@ -44,13 +44,13 @@ public class SysUserDepartServiceImpl extends ServiceImpl&lt;SysUserDepartMapper, S
44 44 */
45 45 @Override
46 46 public List<DepartIdModel> queryDepartIdsOfUser(String userId) {
47   - LambdaQueryWrapper<SysUserDepart> queryUDep = new LambdaQueryWrapper<SysUserDepart>();
  47 + LambdaQueryWrapper<SysUserDepart> queryUserDep = new LambdaQueryWrapper<SysUserDepart>();
48 48 LambdaQueryWrapper<SysDepart> queryDep = new LambdaQueryWrapper<SysDepart>();
49 49 try {
50   - queryUDep.eq(SysUserDepart::getUserId, userId);
  50 + queryUserDep.eq(SysUserDepart::getUserId, userId);
51 51 List<String> depIdList = new ArrayList<>();
52 52 List<DepartIdModel> depIdModelList = new ArrayList<>();
53   - List<SysUserDepart> userDepList = this.list(queryUDep);
  53 + List<SysUserDepart> userDepList = this.list(queryUserDep);
54 54 if(userDepList != null && userDepList.size() > 0) {
55 55 for(SysUserDepart userDepart : userDepList) {
56 56 depIdList.add(userDepart.getDepId());
... ... @@ -78,10 +78,10 @@ public class SysUserDepartServiceImpl extends ServiceImpl&lt;SysUserDepartMapper, S
78 78 */
79 79 @Override
80 80 public List<SysUser> queryUserByDepId(String depId) {
81   - LambdaQueryWrapper<SysUserDepart> queryUDep = new LambdaQueryWrapper<SysUserDepart>();
82   - queryUDep.eq(SysUserDepart::getDepId, depId);
  81 + LambdaQueryWrapper<SysUserDepart> queryUserDep = new LambdaQueryWrapper<SysUserDepart>();
  82 + queryUserDep.eq(SysUserDepart::getDepId, depId);
83 83 List<String> userIdList = new ArrayList<>();
84   - List<SysUserDepart> uDepList = this.list(queryUDep);
  84 + List<SysUserDepart> uDepList = this.list(queryUserDep);
85 85 if(uDepList != null && uDepList.size() > 0) {
86 86 for(SysUserDepart uDep : uDepList) {
87 87 userIdList.add(uDep.getUserId());
... ... @@ -121,7 +121,7 @@ public class SysUserDepartServiceImpl extends ServiceImpl&lt;SysUserDepartMapper, S
121 121 }
122 122  
123 123 @Override
124   - public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo) {
  124 + public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id) {
125 125 IPage<SysUser> pageList = null;
126 126 // 部门ID不存在 直接查询用户表即可
127 127 Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
... ... @@ -133,6 +133,11 @@ public class SysUserDepartServiceImpl extends ServiceImpl&lt;SysUserDepartMapper, S
133 133 if(oConvertUtils.isNotEmpty(username)){
134 134 query.like(SysUser::getUsername, username);
135 135 }
  136 + //update-begin---author:wangshuai ---date:20220608 for:[VUEN-1238]邮箱回复时,发送到显示的为用户id------------
  137 + if(oConvertUtils.isNotEmpty(id)){
  138 + query.eq(SysUser::getId, id);
  139 + }
  140 + //update-end---author:wangshuai ---date:20220608 for:[VUEN-1238]邮箱回复时,发送到显示的为用户id------------
136 141 pageList = sysUserMapper.selectPage(page, query);
137 142 }else{
138 143 // 有部门ID 需要走自定义sql
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java
... ... @@ -9,6 +9,9 @@ import lombok.extern.slf4j.Slf4j;
9 9 import org.jeecg.common.api.vo.Result;
10 10 import org.jeecg.common.constant.CacheConstant;
11 11 import org.jeecg.common.constant.CommonConstant;
  12 +import org.jeecg.common.constant.enums.RoleIndexConfigEnum;
  13 +import org.jeecg.common.desensitization.annotation.SensitiveEncode;
  14 +import org.jeecg.common.system.vo.LoginUser;
12 15 import org.jeecg.common.system.vo.SysUserCacheInfo;
13 16 import org.jeecg.common.util.PasswordUtil;
14 17 import org.jeecg.common.util.UUIDGenerator;
... ... @@ -19,6 +22,7 @@ import org.jeecg.modules.system.mapper.*;
19 22 import org.jeecg.modules.system.model.SysUserSysDepartModel;
20 23 import org.jeecg.modules.system.service.ISysUserService;
21 24 import org.jeecg.modules.system.vo.SysUserDepVo;
  25 +import org.springframework.beans.BeanUtils;
22 26 import org.springframework.beans.factory.annotation.Autowired;
23 27 import org.springframework.cache.annotation.CacheEvict;
24 28 import org.springframework.cache.annotation.Cacheable;
... ... @@ -65,6 +69,8 @@ public class SysUserServiceImpl extends ServiceImpl&lt;SysUserMapper, SysUser&gt; impl
65 69 ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
66 70 @Autowired
67 71 ThirdAppDingtalkServiceImpl dingtalkService;
  72 + @Autowired
  73 + SysRoleIndexMapper sysRoleIndexMapper;
68 74  
69 75 @Override
70 76 @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true)
... ... @@ -155,7 +161,40 @@ public class SysUserServiceImpl extends ServiceImpl&lt;SysUserMapper, SysUser&gt; impl
155 161 public List<String> getRole(String username) {
156 162 return sysUserRoleMapper.getRoleByUserName(username);
157 163 }
158   -
  164 +
  165 + /**
  166 + * 获取动态首页路由配置
  167 + * @param username
  168 + * @param version
  169 + * @return
  170 + */
  171 + @Override
  172 + public SysRoleIndex getDynamicIndexByUserRole(String username,String version) {
  173 + List<String> roles = sysUserRoleMapper.getRoleByUserName(username);
  174 + String componentUrl = RoleIndexConfigEnum.getIndexByRoles(roles);
  175 + SysRoleIndex roleIndex = new SysRoleIndex(componentUrl);
  176 + //只有 X-Version=v3 的时候,才读取sys_role_index表获取角色首页配置
  177 + if (oConvertUtils.isNotEmpty(version) && roles!=null && roles.size()>0) {
  178 + LambdaQueryWrapper<SysRoleIndex> routeIndexQuery = new LambdaQueryWrapper();
  179 + //用户所有角色
  180 + routeIndexQuery.in(SysRoleIndex::getRoleCode, roles);
  181 + //角色首页状态0:未开启 1:开启
  182 + routeIndexQuery.eq(SysRoleIndex::getStatus, CommonConstant.STATUS_1);
  183 + //优先级正序排序
  184 + routeIndexQuery.orderByAsc(SysRoleIndex::getPriority);
  185 + List<SysRoleIndex> list = sysRoleIndexMapper.selectList(routeIndexQuery);
  186 + if (null != list && list.size() > 0) {
  187 + roleIndex = list.get(0);
  188 + }
  189 + }
  190 +
  191 + //如果componentUrl为空,则返回空
  192 + if(oConvertUtils.isEmpty(roleIndex.getComponent())){
  193 + return null;
  194 + }
  195 + return roleIndex;
  196 + }
  197 +
159 198 /**
160 199 * 通过用户名获取用户角色集合
161 200 * @param username 用户名
... ... @@ -200,7 +239,6 @@ public class SysUserServiceImpl extends ServiceImpl&lt;SysUserMapper, SysUser&gt; impl
200 239 * @return
201 240 */
202 241 @Override
203   - @Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
204 242 public SysUserCacheInfo getCacheUser(String username) {
205 243 SysUserCacheInfo info = new SysUserCacheInfo();
206 244 info.setOneDepart(true);
... ... @@ -558,4 +596,19 @@ public class SysUserServiceImpl extends ServiceImpl&lt;SysUserMapper, SysUser&gt; impl
558 596 return userList.stream().map(SysUser::getUsername).collect(Collectors.toList());
559 597 }
560 598  
  599 + @Override
  600 + @Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
  601 + @SensitiveEncode
  602 + public LoginUser getEncodeUserInfo(String username){
  603 + if(oConvertUtils.isEmpty(username)) {
  604 + return null;
  605 + }
  606 + LoginUser loginUser = new LoginUser();
  607 + SysUser sysUser = userMapper.getUserByName(username);
  608 + if(sysUser==null) {
  609 + return null;
  610 + }
  611 + BeanUtils.copyProperties(sysUser, loginUser);
  612 + return loginUser;
  613 + }
561 614 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java
... ... @@ -67,15 +67,20 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
67 67 private SysAnnouncementSendMapper sysAnnouncementSendMapper;
68 68  
69 69 /**
  70 + * errcode
  71 + */
  72 + private static final String ERR_CODE = "errcode";
  73 +
  74 + /**
70 75 * 第三方APP类型,当前固定为 wechat_enterprise
71 76 */
72 77 public final String THIRD_TYPE = ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase();
73 78  
74 79 @Override
75 80 public String getAccessToken() {
76   - String CORP_ID = thirdAppConfig.getWechatEnterprise().getClientId();
77   - String SECRET = thirdAppConfig.getWechatEnterprise().getClientSecret();
78   - AccessToken accessToken = JwAccessTokenAPI.getAccessToken(CORP_ID, SECRET);
  81 + String corpId = thirdAppConfig.getWechatEnterprise().getClientId();
  82 + String secret = thirdAppConfig.getWechatEnterprise().getClientSecret();
  83 + AccessToken accessToken = JwAccessTokenAPI.getAccessToken(corpId, secret);
79 84 if (accessToken != null) {
80 85 return accessToken.getAccesstoken();
81 86 }
... ... @@ -85,14 +90,14 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
85 90  
86 91 /** 获取APPToken,新版企业微信的秘钥是分开的 */
87 92 public String getAppAccessToken() {
88   - String CORP_ID = thirdAppConfig.getWechatEnterprise().getClientId();
89   - String SECRET = thirdAppConfig.getWechatEnterprise().getAgentAppSecret();
  93 + String corpId = thirdAppConfig.getWechatEnterprise().getClientId();
  94 + String secret = thirdAppConfig.getWechatEnterprise().getAgentAppSecret();
90 95 // 如果没有配置APP秘钥,就说明是老企业,可以通用秘钥
91   - if (oConvertUtils.isEmpty(SECRET)) {
92   - SECRET = thirdAppConfig.getWechatEnterprise().getClientSecret();
  96 + if (oConvertUtils.isEmpty(secret)) {
  97 + secret = thirdAppConfig.getWechatEnterprise().getClientSecret();
93 98 }
94 99  
95   - AccessToken accessToken = JwAccessTokenAPI.getAccessToken(CORP_ID, SECRET);
  100 + AccessToken accessToken = JwAccessTokenAPI.getAccessToken(corpId, secret);
96 101 if (accessToken != null) {
97 102 return accessToken.getAccesstoken();
98 103 }
... ... @@ -464,6 +469,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
464 469 case 60104:
465 470 msg = "手机号码已存在";
466 471 break;
  472 + default:
467 473 }
468 474 String str = String.format("用户 %s(%s) 同步失败!错误码:%s——%s", sysUser.getUsername(), sysUser.getRealname(), errCode, msg);
469 475 syncInfo.addFailInfo(str);
... ... @@ -567,7 +573,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
567 573 // 企业微信规则:1表示启用成员,0表示禁用成员
568 574 // JEECG规则:1正常,2冻结
569 575 if (sysUser.getStatus() != null) {
570   - if (sysUser.getStatus() == 1 || sysUser.getStatus() == 2) {
  576 + if (CommonConstant.USER_UNFREEZE.equals(sysUser.getStatus()) || CommonConstant.USER_FREEZE.equals(sysUser.getStatus())) {
571 577 user.setEnable(sysUser.getStatus() == 1 ? 1 : 0);
572 578 } else {
573 579 user.setEnable(1);
... ... @@ -837,7 +843,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
837 843 JSONObject response = JwUserAPI.getUserInfoByCode(code, accessToken);
838 844 if (response != null) {
839 845 log.info("response: " + response.toJSONString());
840   - if (response.getIntValue("errcode") == 0) {
  846 + if (response.getIntValue(ERR_CODE) == 0) {
841 847 return response.getString("UserId");
842 848 }
843 849 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/PermissionDataUtil.java
... ... @@ -2,6 +2,8 @@ package org.jeecg.modules.system.util;
2 2  
3 3 import java.util.List;
4 4  
  5 +import org.jeecg.common.constant.CommonConstant;
  6 +import org.jeecg.common.constant.SymbolConstant;
5 7 import org.jeecg.common.util.oConvertUtils;
6 8 import org.jeecg.modules.system.entity.SysPermission;
7 9  
... ... @@ -11,6 +13,21 @@ import org.jeecg.modules.system.entity.SysPermission;
11 13 */
12 14 public class PermissionDataUtil {
13 15  
  16 + /**
  17 + * 路径:views/
  18 + */
  19 + private static final String PATH_VIEWS = "views/";
  20 +
  21 + /**
  22 + * 路径:src/views/
  23 + */
  24 + private static final String PATH_SRC_VIEWS = "src/views/";
  25 +
  26 + /**
  27 + * .vue后缀
  28 + */
  29 + private static final String VUE_SUFFIX = ".vue";
  30 +
14 31 /**
15 32 * 智能处理错误数据,简化用户失误操作
16 33 *
... ... @@ -24,17 +41,17 @@ public class PermissionDataUtil {
24 41 // 组件
25 42 if (oConvertUtils.isNotEmpty(permission.getComponent())) {
26 43 String component = permission.getComponent();
27   - if (component.startsWith("/")) {
  44 + if (component.startsWith(SymbolConstant.SINGLE_SLASH)) {
28 45 component = component.substring(1);
29 46 }
30   - if (component.startsWith("views/")) {
31   - component = component.replaceFirst("views/", "");
  47 + if (component.startsWith(PATH_VIEWS)) {
  48 + component = component.replaceFirst(PATH_VIEWS, "");
32 49 }
33   - if (component.startsWith("src/views/")) {
34   - component = component.replaceFirst("src/views/", "");
  50 + if (component.startsWith(PATH_SRC_VIEWS)) {
  51 + component = component.replaceFirst(PATH_SRC_VIEWS, "");
35 52 }
36   - if (component.endsWith(".vue")) {
37   - component = component.replace(".vue", "");
  53 + if (component.endsWith(VUE_SUFFIX)) {
  54 + component = component.replace(VUE_SUFFIX, "");
38 55 }
39 56 permission.setComponent(component);
40 57 }
... ... @@ -42,11 +59,11 @@ public class PermissionDataUtil {
42 59 // 请求URL
43 60 if (oConvertUtils.isNotEmpty(permission.getUrl())) {
44 61 String url = permission.getUrl();
45   - if (url.endsWith(".vue")) {
46   - url = url.replace(".vue", "");
  62 + if (url.endsWith(VUE_SUFFIX)) {
  63 + url = url.replace(VUE_SUFFIX, "");
47 64 }
48   - if (!url.startsWith("http") && !url.startsWith("/")&&!url.trim().startsWith("{{")) {
49   - url = "/" + url;
  65 + if (!url.startsWith(CommonConstant.STR_HTTP) && !url.startsWith(SymbolConstant.SINGLE_SLASH)&&!url.trim().startsWith(SymbolConstant.DOUBLE_LEFT_CURLY_BRACKET)) {
  66 + url = SymbolConstant.SINGLE_SLASH + url;
50 67 }
51 68 permission.setUrl(url);
52 69 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/RandImageUtil.java
... ... @@ -15,26 +15,26 @@ import java.util.Random;
15 15 */
16 16 public class RandImageUtil {
17 17  
18   - public static final String key = "JEECG_LOGIN_KEY";
  18 + public static final String KEY = "JEECG_LOGIN_KEY";
19 19  
20 20 /**
21 21 * 定义图形大小
22 22 */
23   - private static final int width = 105;
  23 + private static final int WIDTH = 105;
24 24 /**
25 25 * 定义图形大小
26 26 */
27   - private static final int height = 35;
  27 + private static final int HEIGHT = 35;
28 28  
29 29 /**
30 30 * 定义干扰线数量
31 31 */
32   - private static final int count = 200;
  32 + private static final int COUNT = 200;
33 33  
34 34 /**
35 35 * 干扰线的长度=1.414*lineWidth
36 36 */
37   - private static final int lineWidth = 2;
  37 + private static final int LINE_WIDTH = 2;
38 38  
39 39 /**
40 40 * 图片格式
... ... @@ -85,28 +85,28 @@ public class RandImageUtil {
85 85  
86 86 private static BufferedImage getImageBuffer(String resultCode){
87 87 // 在内存中创建图象
88   - final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  88 + final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
89 89 // 获取图形上下文
90 90 final Graphics2D graphics = (Graphics2D) image.getGraphics();
91 91 // 设定背景颜色
92 92 // ---1
93 93 graphics.setColor(Color.WHITE);
94   - graphics.fillRect(0, 0, width, height);
  94 + graphics.fillRect(0, 0, WIDTH, HEIGHT);
95 95 // 设定边框颜色
96 96 // graphics.setColor(getRandColor(100, 200)); // ---2
97   - graphics.drawRect(0, 0, width - 1, height - 1);
  97 + graphics.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
98 98  
99 99 final Random random = new Random();
100 100 // 随机产生干扰线,使图象中的认证码不易被其它程序探测到
101   - for (int i = 0; i < count; i++) {
  101 + for (int i = 0; i < COUNT; i++) {
102 102 // ---3
103 103 graphics.setColor(getRandColor(150, 200));
104 104  
105 105 // 保证画在边框之内
106   - final int x = random.nextInt(width - lineWidth - 1) + 1;
107   - final int y = random.nextInt(height - lineWidth - 1) + 1;
108   - final int xl = random.nextInt(lineWidth);
109   - final int yl = random.nextInt(lineWidth);
  106 + final int x = random.nextInt(WIDTH - LINE_WIDTH - 1) + 1;
  107 + final int y = random.nextInt(HEIGHT - LINE_WIDTH - 1) + 1;
  108 + final int xl = random.nextInt(LINE_WIDTH);
  109 + final int yl = random.nextInt(LINE_WIDTH);
110 110 graphics.drawLine(x, y, x + xl, y + yl);
111 111 }
112 112 // 取随机产生的认证码
... ... @@ -129,11 +129,12 @@ public class RandImageUtil {
129 129  
130 130 private static Color getRandColor(int fc, int bc) { // 取得给定范围随机颜色
131 131 final Random random = new Random();
132   - if (fc > 255) {
133   - fc = 255;
  132 + int length = 255;
  133 + if (fc > length) {
  134 + fc = length;
134 135 }
135   - if (bc > 255) {
136   - bc = 255;
  136 + if (bc > length) {
  137 + bc = length;
137 138 }
138 139  
139 140 final int r = fc + random.nextInt(bc - fc);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/XssUtils.java 0 → 100644
  1 +package org.jeecg.modules.system.util;
  2 +
  3 +import org.springframework.web.util.HtmlUtils;
  4 +
  5 +import java.util.regex.Pattern;
  6 +
  7 +/**
  8 + * @Description: 工具类XSSUtils,现在的做法是替换成空字符,CSDN的是进行转义,比如文字开头的"<"转成&lt;
  9 + * @author: lsq
  10 + * @date: 2021年07月26日 19:13
  11 + */
  12 +public class XssUtils {
  13 +
  14 + private static Pattern[] patterns = new Pattern[]{
  15 + //Script fragments
  16 + Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
  17 + //src='...'
  18 + Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
  19 + Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
  20 + //script tags
  21 + Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
  22 + Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
  23 + //eval(...)
  24 + Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
  25 + //expression(...)
  26 + Pattern.compile("e­xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
  27 + //javascript:...
  28 + Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
  29 + //vbscript:...
  30 + Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
  31 + //onload(...)=...
  32 + Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
  33 + };
  34 +
  35 + public static String scriptXss(String value) {
  36 + if (value != null) {
  37 + value = value.replaceAll(" ", "");
  38 + for(Pattern scriptPattern: patterns){
  39 + value = scriptPattern.matcher(value).replaceAll("");
  40 + }
  41 + }
  42 + return HtmlUtils.htmlEscape(value);
  43 + }
  44 +
  45 + public static void main(String[] args) {
  46 + String s = scriptXss("<img src=x onload=alert(111).*?><script></script>javascript:eval()\\\\.");
  47 + System.err.println("s======>" + s);
  48 + }
  49 +}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/application-dev.yml
... ... @@ -184,7 +184,11 @@ jeecg:
184 184 # 签名密钥串(前后端要一致,正式发布请自行修改)
185 185 signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
186 186 # 本地:local\Minio:minio\阿里云:alioss
187   - uploadType: local
  187 + uploadType: minio
  188 + # 前端访问地址
  189 + domainUrl:
  190 + pc: http://localhost:3100
  191 + app: http://localhost:8051
188 192 path:
189 193 #文件上传根目录 设置
190 194 upload: /opt/upFiles
... ... @@ -328,4 +332,4 @@ third-app:
328 332 client-id: ??
329 333 # appSecret
330 334 client-secret: ??
331   - agent-id: ??
332 335 \ No newline at end of file
  336 + agent-id: ??
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/application-prod.yml
... ... @@ -39,10 +39,10 @@ spring:
39 39 quartz:
40 40 job-store-type: jdbc
41 41 initialize-schema: embedded
42   - #延迟1秒启动定时任务
43   - startup-delay: 1s
44 42 #定时任务启动开关,true-开 false-关
45 43 auto-startup: true
  44 + #延迟1秒启动定时任务
  45 + startup-delay: 1s
46 46 #启动时更新己存在的Job
47 47 overwrite-existing-jobs: true
48 48 properties:
... ... @@ -185,6 +185,10 @@ jeecg:
185 185 signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
186 186 # 本地:local\Minio:minio\阿里云:alioss
187 187 uploadType: alioss
  188 + # 前端访问地址
  189 + domainUrl:
  190 + pc: http://localhost:3100
  191 + app: http://localhost:8051
188 192 path:
189 193 #文件上传根目录 设置
190 194 upload: /opt/jeecg-boot/upload
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/application-test.yml
... ... @@ -185,6 +185,10 @@ jeecg:
185 185 signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
186 186 # 本地:local\Minio:minio\阿里云:alioss
187 187 uploadType: local
  188 + # 前端访问地址
  189 + domainUrl:
  190 + pc: http://localhost:3100
  191 + app: http://localhost:8051
188 192 path:
189 193 #文件上传根目录 设置
190 194 upload: D://opt//upFiles
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/banner.txt
... ... @@ -9,6 +9,6 @@ ${AnsiColor.BRIGHT_BLUE}
9 9  
10 10  
11 11 ${AnsiColor.BRIGHT_GREEN}
12   -Jeecg Boot Version: 3.2.0
  12 +Jeecg Boot Version: 3.3.0
13 13 Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
14 14 ${AnsiColor.BLACK}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl
1 1 -- 注意:该页面对应的前台目录为views/${entityPackage}文件夹下
2 2 -- 如果你想更改到其他目录,请修改sql中component字段对应的值
3 3  
  4 +<#assign id = '${.now?string["yyyyMMddhhmmSSsss"]}0'>
  5 +
4 6 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, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external)
5   -VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}', NULL, '${tableVo.ftlDescription}', '/${entityPackage}/${entityName?uncap_first}List', '${entityPackage}/${entityName}List', NULL, NULL, 0, NULL, '1', 1.00, 0, NULL, 1, 1, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0);
6 7 \ No newline at end of file
  8 +VALUES ('${id}', NULL, '${tableVo.ftlDescription}', '/${entityPackage}/${entityName?uncap_first}List', '${entityPackage}/${entityName}List', NULL, NULL, 0, NULL, '1', 1.00, 0, NULL, 1, 1, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0);
  9 +
  10 +-- 权限控制sql
  11 +-- 新增
  12 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
  13 +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}1', '${id}', '添加${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:add', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
  14 +-- 编辑
  15 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
  16 +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}2', '${id}', '编辑${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:edit', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
  17 +-- 删除
  18 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
  19 +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}3', '${id}', '删除${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:delete', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
  20 +-- 批量删除
  21 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
  22 +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}4', '${id}', '批量删除${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:deleteBatch', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
  23 +-- 导出excel
  24 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
  25 +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}5', '${id}', '导出excel_${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:exportXls', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
  26 +-- 导入excel
  27 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
  28 +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}6', '${id}', '导入excel_${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:importExcel', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0);
7 29 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/core.ftl
... ... @@ -32,7 +32,7 @@
32 32 { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
33 33 <#-- 邮政编码 -->
34 34 <#elseif fieldValidType == 'p'>
35   - { pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
  35 + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'},
36 36 <#-- 字母 -->
37 37 <#elseif fieldValidType == 's'>
38 38 { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl
... ... @@ -28,7 +28,7 @@
28 28 { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}<#rt>,
29 29 <#-- 邮政编码 -->
30 30 <#elseif fieldValidType == 'p'>
31   - { pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'}<#rt>,
  31 + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}<#rt>,
32 32 <#-- 字母 -->
33 33 <#elseif fieldValidType == 's'>
34 34 { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}<#rt>,
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
... ... @@ -86,6 +86,7 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
86 86 */
87 87 @AutoLog(value = "${tableVo.ftlDescription}-添加")
88 88 @ApiOperation(value="${tableVo.ftlDescription}-添加", notes="${tableVo.ftlDescription}-添加")
  89 + //@RequiresPermissions("${bussiPackage}:${tableName}:add")
89 90 @PostMapping(value = "/add")
90 91 public Result<String> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
91 92 <#if bpm_flag>
... ... @@ -103,6 +104,7 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
103 104 */
104 105 @AutoLog(value = "${tableVo.ftlDescription}-编辑")
105 106 @ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
  107 + //@RequiresPermissions("${bussiPackage}:${tableName}:edit")
106 108 @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
107 109 public Result<String> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
108 110 ${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
... ... @@ -117,6 +119,7 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
117 119 */
118 120 @AutoLog(value = "${tableVo.ftlDescription}-通过id删除")
119 121 @ApiOperation(value="${tableVo.ftlDescription}-通过id删除", notes="${tableVo.ftlDescription}-通过id删除")
  122 + //@RequiresPermissions("${bussiPackage}:${tableName}:delete")
120 123 @DeleteMapping(value = "/delete")
121 124 public Result<String> delete(@RequestParam(name="id",required=true) String id) {
122 125 ${entityName?uncap_first}Service.removeById(id);
... ... @@ -131,6 +134,7 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
131 134 */
132 135 @AutoLog(value = "${tableVo.ftlDescription}-批量删除")
133 136 @ApiOperation(value="${tableVo.ftlDescription}-批量删除", notes="${tableVo.ftlDescription}-批量删除")
  137 + //@RequiresPermissions("${bussiPackage}:${tableName}:deleteBatch")
134 138 @DeleteMapping(value = "/deleteBatch")
135 139 public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
136 140 this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(",")));
... ... @@ -160,6 +164,7 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
160 164 * @param request
161 165 * @param ${entityName?uncap_first}
162 166 */
  167 + //@RequiresPermissions("${bussiPackage}:${tableName}:exportXls")
163 168 @RequestMapping(value = "/exportXls")
164 169 public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) {
165 170 return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}");
... ... @@ -172,6 +177,7 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
172 177 * @param response
173 178 * @return
174 179 */
  180 + //@RequiresPermissions("${tableName}:importExcel")
175 181 @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
176 182 public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
177 183 return super.importExcel(request, response, ${entityName}.class);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei
... ... @@ -55,7 +55,7 @@
55 55 <template v-if="toggleSearchStatus">
56 56 </#if>
57 57 <#-- update-begin-author:taoyan date:20220303 for: /issues/3420 内嵌风格,datetime控件样式异常 -->
58   - <#if po.queryModel=='group' && po.classType=='datetime'>
  58 + <#if po.queryMode?default("")?trim=='group' && po.classType=='datetime'>
59 59 ${indent}<a-col :xl="10" :lg="12" :md="12" :sm="24">
60 60 <#else>
61 61 ${indent}<a-col :xl="6" :lg="7" :md="8" :sm="24">
... ...
jeecg-boot/jeecg-boot-module-system/src/test/java/org/jeecg/modules/system/test/SysUserTest.java
1 1 package org.jeecg.modules.system.test;
2 2  
  3 +import com.alibaba.fastjson.JSONObject;
3 4 import org.jeecg.JeecgSystemApplication;
4 5 import org.jeecg.common.constant.CommonConstant;
5 6 import org.jeecg.common.system.util.JwtUtil;
... ... @@ -9,13 +10,11 @@ import org.junit.Test;
9 10 import org.junit.runner.RunWith;
10 11 import org.springframework.beans.factory.annotation.Autowired;
11 12 import org.springframework.boot.test.context.SpringBootTest;
12   -import org.springframework.test.context.ActiveProfiles;
13   -import org.springframework.test.context.junit4.SpringRunner;
14 13 import org.springframework.http.HttpHeaders;
15 14 import org.springframework.http.HttpMethod;
16 15 import org.springframework.http.MediaType;
17   -import com.alibaba.fastjson.JSONObject;
18 16 import org.springframework.http.ResponseEntity;
  17 +import org.springframework.test.context.junit4.SpringRunner;
19 18  
20 19 /**
21 20 * 系统用户单元测试
... ...