mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-02-03 00:55:33 +08:00
Merge remote-tracking branch 'origin/master' into springboot3
# Conflicts: # jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/Swagger3Config.java # jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/UndertowCustomizer.java # jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysFilesController.java # jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysFiles.java
This commit is contained in:
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>jeecg-system-api</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.7.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>jeecg-system-cloud-api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- feign -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,795 @@
|
||||
package org.jeecg.common.system.api;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.api.CommonAPI;
|
||||
import org.jeecg.common.api.dto.DataLogDTO;
|
||||
import org.jeecg.common.api.dto.OnlineAuthDTO;
|
||||
import org.jeecg.common.api.dto.message.*;
|
||||
import org.jeecg.common.constant.ServiceNameConstants;
|
||||
import org.jeecg.common.constant.enums.EmailTemplateEnum;
|
||||
import org.jeecg.common.desensitization.annotation.SensitiveDecode;
|
||||
import org.jeecg.common.system.api.factory.SysBaseAPIFallbackFactory;
|
||||
import org.jeecg.common.system.vo.*;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* 1、cloud接口数量43 local:35 common:9 额外一个特殊queryAllRole一个当两个用
|
||||
* - 相比较local版
|
||||
* - 去掉了一些方法:addLog、getDatabaseType、queryAllDepart、queryAllUser(Wrapper wrapper)、queryAllUser(String[] userIds, int pageNo, int pageSize)
|
||||
* - 修改了一些方法:createLog、sendSysAnnouncement(只保留了一个,其余全部干掉)
|
||||
* 2、@ConditionalOnMissingClass("org.jeecg.modules.system.service.impl.SysBaseApiImpl")=> 有实现类的时候,不实例化Feign接口
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Component
|
||||
@FeignClient(contextId = "sysBaseRemoteApi", value = ServiceNameConstants.SERVICE_SYSTEM, fallbackFactory = SysBaseAPIFallbackFactory.class)
|
||||
@ConditionalOnMissingClass("org.jeecg.modules.system.service.impl.SysBaseApiImpl")
|
||||
public interface ISysBaseAPI extends CommonAPI {
|
||||
|
||||
/**
|
||||
* 1发送系统消息
|
||||
* @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息
|
||||
*/
|
||||
@PostMapping("/sys/api/sendSysAnnouncement")
|
||||
void sendSysAnnouncement(@RequestBody MessageDTO message);
|
||||
|
||||
/**
|
||||
* 2发送消息 附带业务参数
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
@PostMapping("/sys/api/sendBusAnnouncement")
|
||||
void sendBusAnnouncement(@RequestBody BusMessageDTO message);
|
||||
|
||||
/**
|
||||
* 3通过模板发送消息
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
@PostMapping("/sys/api/sendTemplateAnnouncement")
|
||||
void sendTemplateAnnouncement(@RequestBody TemplateMessageDTO message);
|
||||
|
||||
/**
|
||||
* 4通过模板发送消息 附带业务参数
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
@PostMapping("/sys/api/sendBusTemplateAnnouncement")
|
||||
void sendBusTemplateAnnouncement(@RequestBody BusTemplateMessageDTO message);
|
||||
|
||||
/**
|
||||
* 5通过消息中心模板,生成推送内容
|
||||
* @param templateDTO 使用构造器赋值参数
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/sys/api/parseTemplateByCode")
|
||||
String parseTemplateByCode(@RequestBody TemplateDTO templateDTO);
|
||||
|
||||
/**
|
||||
* 6根据用户id查询用户信息
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@SensitiveDecode
|
||||
@GetMapping("/sys/api/getUserById")
|
||||
LoginUser getUserById(@RequestParam("id") String id);
|
||||
|
||||
/**
|
||||
* 7通过用户账号查询角色集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getRolesByUsername")
|
||||
List<String> getRolesByUsername(@RequestParam("username") String username);
|
||||
|
||||
/**
|
||||
* 7通过用户账号查询角色集合
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getRolesByUserId")
|
||||
List<String> getRolesByUserId(@RequestParam("userId") String userId);
|
||||
|
||||
/**
|
||||
* 8通过用户账号查询部门集合
|
||||
* @param username
|
||||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/sys/api/getDepartIdsByUsername")
|
||||
List<String> getDepartIdsByUsername(@RequestParam("username") String username);
|
||||
|
||||
/**
|
||||
* 8通过用户账号查询部门集合
|
||||
* @param userId
|
||||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/sys/api/getDepartIdsByUserId")
|
||||
List<String> getDepartIdsByUserId(@RequestParam("userId") String userId);
|
||||
|
||||
/**
|
||||
* 8.2 通过用户账号查询部门父ID集合
|
||||
* @param username
|
||||
* @return 部门 parentIds
|
||||
*/
|
||||
@GetMapping("/sys/api/getDepartParentIdsByUsername")
|
||||
Set<String> getDepartParentIdsByUsername(@RequestParam("username")String username);
|
||||
|
||||
/**
|
||||
* 8.3 查询部门父ID集合
|
||||
* @param depIds
|
||||
* @return 部门 parentIds
|
||||
*/
|
||||
@GetMapping("/sys/api/getDepartParentIdsByDepIds")
|
||||
Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set<String> depIds);
|
||||
|
||||
/**
|
||||
* 9通过用户账号查询部门 name
|
||||
* @param username
|
||||
* @return 部门 name
|
||||
*/
|
||||
@GetMapping("/sys/api/getDepartNamesByUsername")
|
||||
List<String> getDepartNamesByUsername(@RequestParam("username") String username);
|
||||
|
||||
/**
|
||||
* 10获取数据字典
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/queryDictItemsByCode")
|
||||
List<DictModel> queryDictItemsByCode(@RequestParam("code") String code);
|
||||
|
||||
/**
|
||||
* 获取有效的数据字典项
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/queryEnableDictItemsByCode")
|
||||
public List<DictModel> queryEnableDictItemsByCode(@RequestParam("code") String code);
|
||||
|
||||
/** 11查询所有的父级字典,按照create_time排序
|
||||
* @return List<DictModel> 字典值集合
|
||||
*/
|
||||
@GetMapping("/sys/api/queryAllDict")
|
||||
List<DictModel> queryAllDict();
|
||||
|
||||
/**
|
||||
* 12查询所有分类字典
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryAllSysCategory")
|
||||
List<SysCategoryModel> queryAllSysCategory();
|
||||
|
||||
/**
|
||||
* 13获取表数据字典
|
||||
* @param tableFilterSql
|
||||
* @param text
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/queryTableDictItemsByCode")
|
||||
List<DictModel> queryTableDictItemsByCode(@RequestParam("tableFilterSql") String tableFilterSql, @RequestParam("text") String text, @RequestParam("code") String code);
|
||||
|
||||
/**
|
||||
* 14查询所有部门 作为字典信息 id -->value,departName -->text
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryAllDepartBackDictModel")
|
||||
List<DictModel> queryAllDepartBackDictModel();
|
||||
|
||||
/**
|
||||
* 15根据业务类型 busType 及业务 busId 修改消息已读
|
||||
* @param busType 业务类型
|
||||
* @param busId 业务id
|
||||
*/
|
||||
@GetMapping("/sys/api/updateSysAnnounReadFlag")
|
||||
public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId")String busId);
|
||||
|
||||
/**
|
||||
* 16查询表字典 支持过滤数据
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param filterSql
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryFilterTableDictInfo")
|
||||
List<DictModel> queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql);
|
||||
|
||||
/**
|
||||
* 17查询指定table的 text code 获取字典,包含text和value
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keyArray
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
@GetMapping("/sys/api/queryTableDictByKeys")
|
||||
public List<String> queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray);
|
||||
|
||||
/**
|
||||
* 18查询所有用户 返回ComboModel
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryAllUserBackCombo")
|
||||
public List<ComboModel> queryAllUserBackCombo();
|
||||
|
||||
/**
|
||||
* 19分页查询用户 返回JSONObject
|
||||
* @param userIds 多个用户id
|
||||
* @param pageNo 当前页数
|
||||
* @param pageSize 每页条数
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryAllUser")
|
||||
public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) Integer pageSize);
|
||||
|
||||
|
||||
/**
|
||||
* 20获取所有角色 带参
|
||||
* @param roleIds 默认选中角色
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryAllRole")
|
||||
public List<ComboModel> queryAllRole(@RequestParam(name = "roleIds",required = false)String[] roleIds);
|
||||
|
||||
/**
|
||||
* 21通过用户账号查询角色Id集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getRoleIdsByUsername")
|
||||
public List<String> getRoleIdsByUsername(@RequestParam("username")String username);
|
||||
|
||||
/**
|
||||
* 22通过部门编号查询部门id
|
||||
* @param orgCode
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getDepartIdsByOrgCode")
|
||||
public String getDepartIdsByOrgCode(@RequestParam("orgCode")String orgCode);
|
||||
|
||||
/**
|
||||
* 23查询所有部门
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getAllSysDepart")
|
||||
public List<SysDepartModel> getAllSysDepart();
|
||||
|
||||
/**
|
||||
* 24查找父级部门
|
||||
* @param departId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getParentDepartId")
|
||||
DictModel getParentDepartId(@RequestParam("departId")String departId);
|
||||
|
||||
/**
|
||||
* 25根据部门Id获取部门负责人
|
||||
* @param deptId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getDeptHeadByDepId")
|
||||
public List<String> getDeptHeadByDepId(@RequestParam("deptId") String deptId);
|
||||
|
||||
/**
|
||||
* 26给指定用户发消息
|
||||
* @param userIds
|
||||
* @param cmd
|
||||
*/
|
||||
@GetMapping("/sys/api/sendWebSocketMsg")
|
||||
public void sendWebSocketMsg(@RequestParam("userIds")String[] userIds, @RequestParam("cmd") String cmd);
|
||||
|
||||
/**
|
||||
* 27根据id获取所有参与用户
|
||||
* @param userIds 多个用户id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryAllUserByIds")
|
||||
public List<UserAccountInfo> queryAllUserByIds(@RequestParam("userIds") String[] userIds);
|
||||
|
||||
/**
|
||||
* 28将会议签到信息推动到预览
|
||||
* userIds
|
||||
* @return
|
||||
* @param userId
|
||||
*/
|
||||
@GetMapping("/sys/api/meetingSignWebsocket")
|
||||
void meetingSignWebsocket(@RequestParam("userId")String userId);
|
||||
|
||||
/**
|
||||
* 29根据name获取所有参与用户
|
||||
* @param userNames 多个用户账号
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserByNames")
|
||||
List<UserAccountInfo> queryUserByNames(@RequestParam("userNames")String[] userNames);
|
||||
|
||||
|
||||
/**
|
||||
* 30获取用户的角色集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getUserRoleSet")
|
||||
Set<String> getUserRoleSet(@RequestParam("username")String username);
|
||||
|
||||
/**
|
||||
* 30获取用户的角色集合
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getUserRoleSetById")
|
||||
Set<String> getUserRoleSetById(@RequestParam("userId")String userId);
|
||||
|
||||
/**
|
||||
* 31获取用户的权限集合
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getUserPermissionSet")
|
||||
Set<String> getUserPermissionSet(@RequestParam("userId") String userId);
|
||||
|
||||
/**
|
||||
* 32判断是否有online访问的权限
|
||||
* @param onlineAuthDTO
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/sys/api/hasOnlineAuth")
|
||||
boolean hasOnlineAuth(@RequestBody OnlineAuthDTO onlineAuthDTO);
|
||||
|
||||
/**
|
||||
* 33通过部门id获取部门全部信息
|
||||
* @param id 部门id
|
||||
* @return SysDepartModel 部门信息
|
||||
*/
|
||||
@GetMapping("/sys/api/selectAllById")
|
||||
SysDepartModel selectAllById(@RequestParam("id") String id);
|
||||
|
||||
/**
|
||||
* 34根据用户id查询用户所属公司下所有用户ids
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryDeptUsersByUserId")
|
||||
List<String> queryDeptUsersByUserId(@RequestParam("userId") String userId);
|
||||
|
||||
|
||||
//---
|
||||
|
||||
/**
|
||||
* 35查询用户角色信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/queryUserRoles")
|
||||
Set<String> queryUserRoles(@RequestParam("username")String username);
|
||||
|
||||
/**
|
||||
* 35查询用户角色信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/queryUserRolesById")
|
||||
Set<String> queryUserRolesById(@RequestParam("userId")String userId);
|
||||
|
||||
/**
|
||||
* 36查询用户权限信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/queryUserAuths")
|
||||
Set<String> queryUserAuths(@RequestParam("userId")String userId);
|
||||
|
||||
/**
|
||||
* 37根据 id 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/getDynamicDbSourceById")
|
||||
DynamicDataSourceModel getDynamicDbSourceById(@RequestParam("dbSourceId") String dbSourceId);
|
||||
|
||||
/**
|
||||
* 38根据 code 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceCode
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/getDynamicDbSourceByCode")
|
||||
DynamicDataSourceModel getDynamicDbSourceByCode(@RequestParam("dbSourceCode") String dbSourceCode);
|
||||
|
||||
/**
|
||||
* 39根据用户账号查询用户信息 CommonAPI中定义
|
||||
* @param username
|
||||
* @return LoginUser 用户信息
|
||||
*/
|
||||
@Override
|
||||
@SensitiveDecode
|
||||
@GetMapping("/sys/api/getUserByName")
|
||||
LoginUser getUserByName(@RequestParam("username") String username);
|
||||
|
||||
/**
|
||||
* 39根据用户账号查询用户ID CommonAPI中定义
|
||||
* @param username
|
||||
* @return 用户ID
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/getUserIdByName")
|
||||
String getUserIdByName(@RequestParam("username") String username);
|
||||
|
||||
/**
|
||||
* 40字典表的 翻译
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/translateDictFromTable")
|
||||
String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key);
|
||||
|
||||
/**
|
||||
* 41普通字典的翻译
|
||||
* @param code
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/translateDict")
|
||||
String translateDict(@RequestParam("code") String code, @RequestParam("key") String key);
|
||||
|
||||
/**
|
||||
* 42查询数据权限
|
||||
* @param component
|
||||
* @param requestPath
|
||||
* @param username 用户姓名
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/queryPermissionDataRule")
|
||||
List<SysPermissionDataRuleModel> queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath")String requestPath, @RequestParam("username") String username);
|
||||
|
||||
/**
|
||||
* 43查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/getCacheUser")
|
||||
SysUserCacheInfo getCacheUser(@RequestParam("username") String username);
|
||||
|
||||
/**
|
||||
* 36根据多个用户账号(逗号分隔),查询返回多个用户信息
|
||||
* @param usernames
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUsersByUsernames")
|
||||
List<JSONObject> queryUsersByUsernames(@RequestParam("usernames") String usernames);
|
||||
|
||||
/**
|
||||
* 37根据多个用户ID(逗号分隔),查询返回多个用户信息
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/sys/api/queryUsersByIds")
|
||||
List<JSONObject> queryUsersByIds(@RequestParam("ids") String ids);
|
||||
|
||||
/**
|
||||
* 38根据多个部门编码(逗号分隔),查询返回多个部门信息
|
||||
* @param orgCodes
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/sys/api/queryDepartsByOrgcodes")
|
||||
List<JSONObject> queryDepartsByOrgcodes(@RequestParam("orgCodes") String orgCodes);
|
||||
|
||||
// /**
|
||||
// * 39根据多个部门编码(逗号分隔),查询返回多个部门信息
|
||||
// * @param ids
|
||||
// * @return
|
||||
// */
|
||||
// @GetMapping("/sys/api/queryDepartsByOrgIds")
|
||||
// List<JSONObject> queryDepartsByOrgIds(@RequestParam("ids") String ids);
|
||||
|
||||
/**
|
||||
* 40发送邮件消息
|
||||
* @param email
|
||||
* @param title
|
||||
* @param content
|
||||
*/
|
||||
@GetMapping("/sys/api/sendEmailMsg")
|
||||
void sendEmailMsg(@RequestParam("email")String email,@RequestParam("title")String title,@RequestParam("content")String content);
|
||||
|
||||
/**
|
||||
* 发送html模版邮件消息
|
||||
*
|
||||
* @param email
|
||||
* @param title
|
||||
* @param emailTemplateEnum 邮件模版枚举
|
||||
* @param params 模版参数
|
||||
*/
|
||||
@GetMapping("/sys/api/sendHtmlTemplateEmail")
|
||||
void sendHtmlTemplateEmail(@RequestParam("email") String email, @RequestParam("title") String title, @RequestParam("emailEnum") EmailTemplateEnum emailTemplateEnum, @RequestParam("params") JSONObject params);
|
||||
/**
|
||||
* 41 获取公司下级部门和公司下所有用户id
|
||||
* @param orgCode 部门编号
|
||||
* @return List<Map>
|
||||
*/
|
||||
@GetMapping("/sys/api/getDeptUserByOrgCode")
|
||||
List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode);
|
||||
|
||||
/**
|
||||
* 42 查询分类字典翻译
|
||||
* @param ids 多个分类字典id
|
||||
* @return List<String>
|
||||
*/
|
||||
@GetMapping("/sys/api/loadCategoryDictItem")
|
||||
List<String> loadCategoryDictItem(@RequestParam("ids") String ids);
|
||||
|
||||
/**
|
||||
* 44 反向翻译分类字典,用于导入
|
||||
*
|
||||
* @param names 名称,逗号分割
|
||||
*/
|
||||
@GetMapping("/sys/api/loadCategoryDictItemByNames")
|
||||
List<String> loadCategoryDictItemByNames(@RequestParam("names") String names, @RequestParam("delNotExist") boolean delNotExist);
|
||||
|
||||
/**
|
||||
* 43 根据字典code加载字典text
|
||||
*
|
||||
* @param dictCode 顺序:tableName,text,code
|
||||
* @param keys 要查询的key
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/loadDictItem")
|
||||
List<String> loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys);
|
||||
|
||||
/**
|
||||
* 复制应用下的所有字典配置到新的租户下
|
||||
*
|
||||
* @param originalAppId 原始低代码应用ID
|
||||
* @param appId 新的低代码应用ID
|
||||
* @param tenantId 新的租户ID
|
||||
* @return Map<String, String> Map<原字典编码, 新字典编码>
|
||||
*/
|
||||
@GetMapping("/sys/api/copyLowAppDict")
|
||||
Map<String, String> copyLowAppDict(@RequestParam("originalAppId") String originalAppId, @RequestParam("appId") String appId, @RequestParam("tenantId") String tenantId);
|
||||
|
||||
/**
|
||||
* 44 根据字典code查询字典项
|
||||
*
|
||||
* @param dictCode 顺序:tableName,text,code
|
||||
* @param dictCode 要查询的key
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getDictItems")
|
||||
List<DictModel> getDictItems(@RequestParam("dictCode") String dictCode);
|
||||
|
||||
/**
|
||||
* 45 根据多个字典code查询多个字典项
|
||||
*
|
||||
* @param dictCodeList
|
||||
* @return key = dictCode ; value=对应的字典项
|
||||
*/
|
||||
@RequestMapping("/sys/api/getManyDictItems")
|
||||
Map<String, List<DictModel>> getManyDictItems(@RequestParam("dictCodeList") List<String> dictCodeList);
|
||||
|
||||
/**
|
||||
* 46 【JSearchSelectTag下拉搜索组件专用接口】
|
||||
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||
*
|
||||
* @param dictCode 字典code格式:table,text,code
|
||||
* @param keyword 过滤关键字
|
||||
* @param pageSize 每页条数
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/loadDictItemByKeyword")
|
||||
List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize);
|
||||
|
||||
/**
|
||||
* 47 根据多个部门id(逗号分隔),查询返回多个部门信息
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryDepartsByIds")
|
||||
List<JSONObject> queryDepartsByIds(@RequestParam("ids") String ids);
|
||||
|
||||
/**
|
||||
* 48 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割
|
||||
* @param dictCodes
|
||||
* @param keys
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/translateManyDict")
|
||||
Map<String, List<DictModel>> translateManyDict(@RequestParam("dictCodes") String dictCodes, @RequestParam("keys") String keys);
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 49 字典表的 翻译,可批量
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys 多个用逗号分割
|
||||
* @param ds
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/translateDictFromTableByKeys")
|
||||
List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys, @RequestParam("ds") String ds);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
/**
|
||||
* 发送模板消息
|
||||
*/
|
||||
@PostMapping("/sys/api/sendTemplateMessage")
|
||||
void sendTemplateMessage(@RequestBody MessageDTO message);
|
||||
|
||||
/**
|
||||
* 获取模板内容
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getTemplateContent")
|
||||
String getTemplateContent(@RequestParam("code") String code);
|
||||
|
||||
/**
|
||||
* 新增数据日志
|
||||
* @param dataLogDto
|
||||
*/
|
||||
@PostMapping("/sys/api/saveDataLog")
|
||||
void saveDataLog(@RequestBody DataLogDTO dataLogDto);
|
||||
|
||||
/**
|
||||
* 更新头像
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/sys/api/updateAvatar")
|
||||
void updateAvatar(@RequestBody LoginUser loginUser);
|
||||
|
||||
@GetMapping("/sys/api/sendAppChatSocket")
|
||||
void sendAppChatSocket(@RequestParam(name="userId") String userId);
|
||||
|
||||
/**
|
||||
* 根据角色id查询角色code
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getRoleCode")
|
||||
String getRoleCodeById(String id);
|
||||
|
||||
/**
|
||||
* 根据roleCode查询角色信息,可逗号分隔多个
|
||||
*
|
||||
* @param roleCodes
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryRoleDictByCode")
|
||||
List<DictModel> queryRoleDictByCode(@RequestParam(name = "roleCodes") String roleCodes);
|
||||
|
||||
|
||||
/**
|
||||
* 根据高级查询条件查询用户
|
||||
* @param superQuery
|
||||
* @param matchType
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserBySuperQuery")
|
||||
List<JSONObject> queryUserBySuperQuery(@RequestParam(name="superQuery")String superQuery,@RequestParam(name="matchType")String matchType);
|
||||
|
||||
|
||||
/**
|
||||
* 根据ID条件查询用户
|
||||
* @param id
|
||||
* @return JSONObject
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserById")
|
||||
JSONObject queryUserById(String id);
|
||||
|
||||
|
||||
/**
|
||||
* 根据高级查询条件查询部门
|
||||
* @param superQuery
|
||||
* @param matchType
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryDeptBySuperQuery")
|
||||
List<JSONObject> queryDeptBySuperQuery(@RequestParam(name="superQuery")String superQuery,@RequestParam(name="matchType")String matchType);
|
||||
|
||||
/**
|
||||
* 根据高级查询条件查询角色
|
||||
* @param superQuery
|
||||
* @param matchType
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryRoleBySuperQuery")
|
||||
List<JSONObject> queryRoleBySuperQuery(@RequestParam(name="superQuery")String superQuery,@RequestParam(name="matchType")String matchType);
|
||||
|
||||
|
||||
/**
|
||||
* 根据租户ID查询用户ID
|
||||
* @param tenantId 租户ID
|
||||
* @return List<String>
|
||||
*/
|
||||
@GetMapping("/sys/api/selectUserIdByTenantId")
|
||||
List<String> selectUserIdByTenantId(@RequestParam("tenantId")String tenantId);
|
||||
|
||||
|
||||
/**
|
||||
* 根据部门ID查询用户ID
|
||||
* @param deptIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserIdsByDeptIds")
|
||||
List<String> queryUserIdsByDeptIds(List<String> deptIds);
|
||||
|
||||
/**
|
||||
* 根据部门ID查询用户账号
|
||||
* @param deptIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserAccountsByDeptIds")
|
||||
List<String> queryUserAccountsByDeptIds(List<String> deptIds);
|
||||
|
||||
/**
|
||||
* 根据角色编码 查询用户ID
|
||||
* @param roleCodes
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserIdsByRoleds")
|
||||
List<String> queryUserIdsByRoleds(List<String> roleCodes);
|
||||
|
||||
/**
|
||||
* 根据职务ID查询用户ID
|
||||
* @param positionIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/queryUserIdsByPositionIds")
|
||||
List<String> queryUserIdsByPositionIds(List<String> positionIds);
|
||||
|
||||
/**
|
||||
* 根据部门和子部门下的所有用户账号
|
||||
*
|
||||
* @param orgCode 部门编码
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getUserAccountsByDepCode")
|
||||
public List<String> getUserAccountsByDepCode(@RequestParam("orgCode")String orgCode);
|
||||
|
||||
/**
|
||||
* 检查查询sql的表和字段是否在白名单中
|
||||
*
|
||||
* @param selectSql
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/dictTableWhiteListCheckBySql")
|
||||
boolean dictTableWhiteListCheckBySql(@RequestParam("selectSql") String selectSql);
|
||||
|
||||
/**
|
||||
* 根据字典表或者字典编码,校验是否在白名单中
|
||||
*
|
||||
* @param tableOrDictCode 表名或dictCode
|
||||
* @param fields 如果传的是dictCode,则该参数必须传null
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/dictTableWhiteListCheckByDict")
|
||||
boolean dictTableWhiteListCheckByDict(
|
||||
@RequestParam("tableOrDictCode") String tableOrDictCode,
|
||||
@RequestParam(value = "fields", required = false) String... fields
|
||||
);
|
||||
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package org.jeecg.common.system.api.factory;
|
||||
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.api.fallback.SysBaseAPIFallback;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Description: SysBaseAPIFallbackFactory
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Component
|
||||
public class SysBaseAPIFallbackFactory implements FallbackFactory<ISysBaseAPI> {
|
||||
|
||||
@Override
|
||||
public ISysBaseAPI create(Throwable throwable) {
|
||||
SysBaseAPIFallback fallback = new SysBaseAPIFallback();
|
||||
fallback.setCause(throwable);
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,467 @@
|
||||
package org.jeecg.common.system.api.fallback;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.DataLogDTO;
|
||||
import org.jeecg.common.api.dto.OnlineAuthDTO;
|
||||
import org.jeecg.common.api.dto.message.*;
|
||||
import org.jeecg.common.constant.enums.EmailTemplateEnum;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.vo.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 进入fallback的方法 检查是否token未设置
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
public class SysBaseAPIFallback implements ISysBaseAPI {
|
||||
|
||||
@Setter
|
||||
private Throwable cause;
|
||||
|
||||
@Override
|
||||
public void sendSysAnnouncement(MessageDTO message) {
|
||||
log.error("发送消息失败 {}", cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBusAnnouncement(BusMessageDTO message) {
|
||||
log.error("发送消息失败 {}", cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTemplateAnnouncement(TemplateMessageDTO message) {
|
||||
log.error("发送消息失败 {}", cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBusTemplateAnnouncement(BusTemplateMessageDTO message) {
|
||||
log.error("发送消息失败 {}", cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseTemplateByCode(TemplateDTO templateDTO) {
|
||||
log.error("通过模板获取消息内容失败 {}", cause);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginUser getUserById(String id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRolesByUsername(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRolesByUserId(String userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDepartIdsByUsername(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDepartIdsByUserId(String userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDepartParentIdsByUsername(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDepartParentIdsByDepIds(Set<String> depIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDepartNamesByUsername(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryDictItemsByCode(String code) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryEnableDictItemsByCode(String code) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryAllDict() {
|
||||
log.error("fegin接口queryAllDict失败:"+cause.getMessage(), cause);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysCategoryModel> queryAllSysCategory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryTableDictItemsByCode(String tableFilterSql, String text, String code) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryAllDepartBackDictModel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSysAnnounReadFlag(String busType, String busId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryFilterTableDictInfo(String table, String text, String code, String filterSql) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryTableDictByKeys(String table, String text, String code, String[] keyArray) {
|
||||
log.error("queryTableDictByKeys查询失败 {}", cause);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ComboModel> queryAllUserBackCombo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject queryAllUser(String userIds, Integer pageNo, Integer pageSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ComboModel> queryAllRole(String[] roleIds) {
|
||||
log.error("获取角色信息失败 {}", cause);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRoleIdsByUsername(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDepartIdsByOrgCode(String orgCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysDepartModel> getAllSysDepart() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictModel getParentDepartId(String departId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDeptHeadByDepId(String deptId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendWebSocketMsg(String[] userIds, String cmd) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserAccountInfo> queryAllUserByIds(String[] userIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void meetingSignWebsocket(String userId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserAccountInfo> queryUserByNames(String[] userNames) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUserRoleSet(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUserRoleSetById(String userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUserPermissionSet(String userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOnlineAuth(OnlineAuthDTO onlineAuthDTO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysDepartModel selectAllById(String id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryDeptUsersByUserId(String userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> queryUserRoles(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> queryUserRolesById(String userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> queryUserAuths(String userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginUser getUserByName(String username) {
|
||||
log.error("jeecg-system服务节点不通,导致获取登录用户信息失败: " + cause.getMessage(), cause);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserIdByName(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translateDictFromTable(String table, String text, String code, String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translateDict(String code, String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUserCacheInfo getCacheUser(String username) {
|
||||
log.error("获取用户信息失败 {}", cause);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> queryUsersByUsernames(String usernames) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> queryUsersByIds(String ids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> queryDepartsByOrgcodes(String orgCodes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> queryDepartsByIds(String ids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
@Override
|
||||
public List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys, String dataSource) {
|
||||
return null;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
@Override
|
||||
public void sendTemplateMessage(MessageDTO message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateContent(String code) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveDataLog(DataLogDTO dataLogDto) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendEmailMsg(String email,String title,String content) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendHtmlTemplateEmail(String email, String title, EmailTemplateEnum emailTemplateEnum, JSONObject params) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map> getDeptUserByOrgCode(String orgCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public List<JSONObject> queryDepartsByOrgIds(String ids) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public List<String> loadCategoryDictItem(String ids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> loadCategoryDictItemByNames(String names, boolean delNotExist) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> loadDictItem(String dictCode, String keys) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> copyLowAppDict(String originalAppId, String appId, String tenantId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> getDictItems(String dictCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<DictModel>> getManyDictItems(List<String> dictCodeList) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAvatar(LoginUser loginUser) { }
|
||||
|
||||
@Override
|
||||
public void sendAppChatSocket(String userId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRoleCodeById(String id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryRoleDictByCode(String roleCodes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> queryUserBySuperQuery(String superQuery, String matchType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject queryUserById(String id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> queryDeptBySuperQuery(String superQuery, String matchType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> queryRoleBySuperQuery(String superQuery, String matchType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> selectUserIdByTenantId(String tenantId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryUserIdsByDeptIds(List<String> deptIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryUserAccountsByDeptIds(List<String> deptIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryUserIdsByRoleds(List<String> roleCodes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryUserIdsByPositionIds(List<String> positionIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUserAccountsByDepCode(String orgCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dictTableWhiteListCheckBySql(String selectSql) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dictTableWhiteListCheckByDict(String tableOrDictCode, String... fields) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,180 @@
|
||||
//package org.jeecg.config;
|
||||
//
|
||||
//import java.io.IOException;
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.Arrays;
|
||||
//import java.util.List;
|
||||
//import java.util.SortedMap;
|
||||
//
|
||||
//import javax.servlet.http.HttpServletRequest;
|
||||
//
|
||||
//import org.jeecg.common.config.mqtoken.UserTokenContext;
|
||||
//import org.jeecg.common.constant.CommonConstant;
|
||||
//import org.jeecg.common.util.DateUtils;
|
||||
//import org.jeecg.common.util.PathMatcherUtil;
|
||||
//import org.jeecg.config.sign.interceptor.SignAuthConfiguration;
|
||||
//import org.jeecg.config.sign.util.HttpUtils;
|
||||
//import org.jeecg.config.sign.util.SignUtil;
|
||||
//import org.springframework.beans.factory.ObjectFactory;
|
||||
//import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
//import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
//import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
//import org.springframework.cloud.openfeign.FeignAutoConfiguration;
|
||||
//import org.springframework.cloud.openfeign.support.SpringDecoder;
|
||||
//import org.springframework.cloud.openfeign.support.SpringEncoder;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.context.annotation.Primary;
|
||||
//import org.springframework.context.annotation.Scope;
|
||||
//import org.springframework.http.MediaType;
|
||||
//import org.springframework.web.context.request.RequestContextHolder;
|
||||
//import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
//
|
||||
//import com.alibaba.fastjson.JSON;
|
||||
//import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
//import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||
//import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||
//import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer;
|
||||
//
|
||||
//import feign.Feign;
|
||||
//import feign.Logger;
|
||||
//import feign.RequestInterceptor;
|
||||
//import feign.codec.Decoder;
|
||||
//import feign.codec.Encoder;
|
||||
//import feign.form.spring.SpringFormEncoder;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//
|
||||
///**
|
||||
// * @Description: FeignConfig
|
||||
// * @author: JeecgBoot
|
||||
// */
|
||||
//@ConditionalOnClass(Feign.class)
|
||||
//@AutoConfigureBefore(FeignAutoConfiguration.class)
|
||||
//@Slf4j
|
||||
//@Configuration
|
||||
//public class FeignConfig {
|
||||
//
|
||||
// /**
|
||||
// * 设置feign header参数
|
||||
// * 【X_ACCESS_TOKEN】【X_SIGN】【X_TIMESTAMP】
|
||||
// * @return
|
||||
// */
|
||||
// @Bean
|
||||
// public RequestInterceptor requestInterceptor() {
|
||||
// return requestTemplate -> {
|
||||
// ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
// if (null != attributes) {
|
||||
// HttpServletRequest request = attributes.getRequest();
|
||||
// log.debug("Feign request: {}", request.getRequestURI());
|
||||
// // 将token信息放入header中
|
||||
// String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||
// if(token==null || "".equals(token)){
|
||||
// token = request.getParameter("token");
|
||||
// }
|
||||
// log.info("Feign Login Request token: {}", token);
|
||||
// requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
|
||||
// }else{
|
||||
// //解决后台任务、MQ中调用feign接口,无会话token的问题
|
||||
// String token = UserTokenContext.getToken();
|
||||
// log.info("Feign No Login token: {}", token);
|
||||
// requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
|
||||
// }
|
||||
//
|
||||
// //================================================================================================================
|
||||
// //针对特殊接口,进行加签验证 ——根据URL地址过滤请求 【字典表参数签名验证】
|
||||
// if (PathMatcherUtil.matches(Arrays.asList(SignAuthConfiguration.SIGN_URL_LIST),requestTemplate.path())) {
|
||||
// try {
|
||||
// log.info("============================ [begin] fegin api url ============================");
|
||||
// log.info(requestTemplate.path());
|
||||
// log.info(requestTemplate.method());
|
||||
// String queryLine = requestTemplate.queryLine();
|
||||
// String questionMark="?";
|
||||
// if(queryLine!=null && queryLine.startsWith(questionMark)){
|
||||
// queryLine = queryLine.substring(1);
|
||||
// }
|
||||
// log.info(queryLine);
|
||||
// if(requestTemplate.body()!=null){
|
||||
// log.info(new String(requestTemplate.body()));
|
||||
// }
|
||||
// SortedMap<String, String> allParams = HttpUtils.getAllParams(requestTemplate.path(),queryLine,requestTemplate.body(),requestTemplate.method());
|
||||
// String sign = SignUtil.getParamsSign(allParams);
|
||||
// log.info(" Feign request params sign: {}",sign);
|
||||
// log.info("============================ [end] fegin api url ============================");
|
||||
// requestTemplate.header(CommonConstant.X_SIGN, sign);
|
||||
// requestTemplate.header(CommonConstant.X_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// //================================================================================================================
|
||||
// };
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * Feign 客户端的日志记录,默认级别为NONE
|
||||
// * Logger.Level 的具体级别如下:
|
||||
// * NONE:不记录任何信息
|
||||
// * BASIC:仅记录请求方法、URL以及响应状态码和执行时间
|
||||
// * HEADERS:除了记录 BASIC级别的信息外,还会记录请求和响应的头信息
|
||||
// * FULL:记录所有请求与响应的明细,包括头信息、请求体、元数据
|
||||
// */
|
||||
// @Bean
|
||||
// Logger.Level feignLoggerLevel() {
|
||||
// return Logger.Level.FULL;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Feign支持文件上传
|
||||
// * @param messageConverters
|
||||
// * @return
|
||||
// */
|
||||
// @Bean
|
||||
// @Primary
|
||||
// @Scope("prototype")
|
||||
// public Encoder multipartFormEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
|
||||
// return new SpringFormEncoder(new SpringEncoder(messageConverters));
|
||||
// }
|
||||
//
|
||||
// // update-begin--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ----------
|
||||
// /**
|
||||
// * 给 Feign 添加 FastJson 的解析支持
|
||||
// */
|
||||
// @Bean
|
||||
// public Encoder feignEncoder() {
|
||||
// return new SpringEncoder(feignHttpMessageConverter());
|
||||
// }
|
||||
//
|
||||
// @Bean("apiFeignDecoder")
|
||||
// public Decoder feignDecoder() {
|
||||
// return new SpringDecoder(feignHttpMessageConverter());
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 设置解码器为fastjson
|
||||
// *
|
||||
// * @return
|
||||
// */
|
||||
// private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
|
||||
// final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(this.getFastJsonConverter());
|
||||
// return () -> httpMessageConverters;
|
||||
// }
|
||||
//
|
||||
// private FastJsonHttpMessageConverter getFastJsonConverter() {
|
||||
// FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
|
||||
//
|
||||
// List<MediaType> supportedMediaTypes = new ArrayList<>();
|
||||
// MediaType mediaTypeJson = MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE);
|
||||
// supportedMediaTypes.add(mediaTypeJson);
|
||||
// converter.setSupportedMediaTypes(supportedMediaTypes);
|
||||
// FastJsonConfig config = new FastJsonConfig();
|
||||
// config.getSerializeConfig().put(JSON.class, new SwaggerJsonSerializer());
|
||||
// config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
|
||||
// converter.setFastJsonConfig(config);
|
||||
//
|
||||
// return converter;
|
||||
// }
|
||||
// // update-end--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ----------
|
||||
//
|
||||
//}
|
||||
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>jeecg-system-api</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.7.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>jeecg-system-local-api</artifactId>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,547 @@
|
||||
package org.jeecg.common.system.api;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.api.CommonAPI;
|
||||
import org.jeecg.common.api.dto.DataLogDTO;
|
||||
import org.jeecg.common.api.dto.OnlineAuthDTO;
|
||||
import org.jeecg.common.api.dto.message.*;
|
||||
import org.jeecg.common.constant.enums.EmailTemplateEnum;
|
||||
import org.jeecg.common.system.vo.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Description 底层共通业务API,提供其他独立模块调用
|
||||
* @Author scott
|
||||
* @Date 2019-4-20
|
||||
* @Version V1.0
|
||||
*/
|
||||
public interface ISysBaseAPI extends CommonAPI {
|
||||
|
||||
//=======OLD 系统消息推送接口============================
|
||||
/**
|
||||
* 1发送系统消息
|
||||
* @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息
|
||||
*/
|
||||
void sendSysAnnouncement(MessageDTO message);
|
||||
|
||||
/**
|
||||
* 2发送消息 附带业务参数
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
void sendBusAnnouncement(BusMessageDTO message);
|
||||
|
||||
/**
|
||||
* 3通过模板发送消息
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
void sendTemplateAnnouncement(TemplateMessageDTO message);
|
||||
|
||||
/**
|
||||
* 4通过模板发送消息 附带业务参数
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
void sendBusTemplateAnnouncement(BusTemplateMessageDTO message);
|
||||
|
||||
/**
|
||||
* 5通过消息中心模板,生成推送内容
|
||||
* @param templateDTO 使用构造器赋值参数
|
||||
* @return
|
||||
*/
|
||||
String parseTemplateByCode(TemplateDTO templateDTO);
|
||||
//=======OLD 系统消息推送接口============================
|
||||
|
||||
//=======TY NEW 自定义消息推送接口,邮件、钉钉、企业微信、系统消息============================
|
||||
/**
|
||||
* NEW发送模板消息【新,支持自定义推送类型: 邮件、钉钉、企业微信、系统消息】
|
||||
* @param message
|
||||
*/
|
||||
void sendTemplateMessage(MessageDTO message);
|
||||
|
||||
/**
|
||||
* NEW根据模板编码获取模板内容【新,支持自定义推送类型】
|
||||
* @param templateCode
|
||||
* @return
|
||||
*/
|
||||
String getTemplateContent(String templateCode);
|
||||
//=======TY NEW 自定义消息推送接口,邮件、钉钉、企业微信、系统消息============================
|
||||
|
||||
/**
|
||||
* 6根据用户id查询用户信息
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
LoginUser getUserById(String id);
|
||||
|
||||
/**
|
||||
* 7通过用户账号查询角色集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
List<String> getRolesByUsername(String username);
|
||||
|
||||
/**
|
||||
* 7通过用户账号查询角色集合
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
List<String> getRolesByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 8通过用户账号查询部门集合
|
||||
* @param username
|
||||
* @return 部门 id
|
||||
*/
|
||||
List<String> getDepartIdsByUsername(String username);
|
||||
/**
|
||||
* 8通过用户账号查询部门集合
|
||||
* @param userId
|
||||
* @return 部门 id
|
||||
*/
|
||||
List<String> getDepartIdsByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 8.2 通过用户账号查询部门父ID集合
|
||||
* @param username
|
||||
* @return 部门 parentIds
|
||||
*/
|
||||
Set<String> getDepartParentIdsByUsername(String username);
|
||||
|
||||
/**
|
||||
* 8.2 查询部门父ID集合
|
||||
* @param depIds
|
||||
* @return 部门 parentIds
|
||||
*/
|
||||
Set<String> getDepartParentIdsByDepIds(Set<String> depIds);
|
||||
|
||||
/**
|
||||
* 9通过用户账号查询部门 name
|
||||
* @param username
|
||||
* @return 部门 name
|
||||
*/
|
||||
List<String> getDepartNamesByUsername(String username);
|
||||
|
||||
|
||||
|
||||
/** 11查询所有的父级字典,按照create_time排序
|
||||
* @return List<DictModel> 字典集合
|
||||
*/
|
||||
public List<DictModel> queryAllDict();
|
||||
|
||||
/**
|
||||
* 12查询所有分类字典
|
||||
* @return
|
||||
*/
|
||||
public List<SysCategoryModel> queryAllSysCategory();
|
||||
|
||||
|
||||
/**
|
||||
* 14查询所有部门 作为字典信息 id -->value,departName -->text
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryAllDepartBackDictModel();
|
||||
|
||||
/**
|
||||
* 15根据业务类型及业务id修改消息已读
|
||||
* @param busType
|
||||
* @param busId
|
||||
*/
|
||||
public void updateSysAnnounReadFlag(String busType, String busId);
|
||||
|
||||
/**
|
||||
* 16查询表字典 支持过滤数据
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param filterSql
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryFilterTableDictInfo(String table, String text, String code, String filterSql);
|
||||
|
||||
/**
|
||||
* 17查询指定table的 text code 获取字典,包含text和value
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keyArray
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public List<String> queryTableDictByKeys(String table, String text, String code, String[] keyArray);
|
||||
|
||||
/**
|
||||
* 18查询所有用户 返回ComboModel
|
||||
* @return
|
||||
*/
|
||||
public List<ComboModel> queryAllUserBackCombo();
|
||||
|
||||
/**
|
||||
* 19分页查询用户 返回JSONObject
|
||||
* @param userIds 多个用户id
|
||||
* @param pageNo 当前页数
|
||||
* @param pageSize 每页显示条数
|
||||
* @return
|
||||
*/
|
||||
public JSONObject queryAllUser(String userIds, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 20获取所有角色
|
||||
* @return
|
||||
*/
|
||||
public List<ComboModel> queryAllRole();
|
||||
|
||||
/**
|
||||
* 21获取所有角色 带参
|
||||
* @param roleIds 默认选中角色
|
||||
* @return
|
||||
*/
|
||||
public List<ComboModel> queryAllRole(String[] roleIds );
|
||||
|
||||
/**
|
||||
* 22通过用户账号查询角色Id集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public List<String> getRoleIdsByUsername(String username);
|
||||
|
||||
/**
|
||||
* 23通过部门编号查询部门id
|
||||
* @param orgCode
|
||||
* @return
|
||||
*/
|
||||
public String getDepartIdsByOrgCode(String orgCode);
|
||||
|
||||
/**
|
||||
* 24查询所有部门
|
||||
* @return
|
||||
*/
|
||||
public List<SysDepartModel> getAllSysDepart();
|
||||
|
||||
/**
|
||||
* 25查找父级部门
|
||||
* @param departId
|
||||
* @return
|
||||
*/
|
||||
DictModel getParentDepartId(String departId);
|
||||
|
||||
/**
|
||||
* 26根据部门Id获取部门负责人
|
||||
* @param deptId
|
||||
* @return
|
||||
*/
|
||||
public List<String> getDeptHeadByDepId(String deptId);
|
||||
|
||||
/**
|
||||
* 27给指定用户发消息
|
||||
* @param userIds
|
||||
* @param cmd
|
||||
*/
|
||||
public void sendWebSocketMsg(String[] userIds, String cmd);
|
||||
|
||||
/**
|
||||
* 28根据id获取所有参与用户
|
||||
* @param userIds 多个用户id
|
||||
* @return
|
||||
*/
|
||||
public List<UserAccountInfo> queryAllUserByIds(String[] userIds);
|
||||
|
||||
/**
|
||||
* 29将会议签到信息推动到预览
|
||||
* userIds
|
||||
* @return
|
||||
* @param userId
|
||||
*/
|
||||
void meetingSignWebsocket(String userId);
|
||||
|
||||
/**
|
||||
* 30根据name获取所有参与用户
|
||||
* @param userNames 多个用户账户
|
||||
* @return
|
||||
*/
|
||||
List<UserAccountInfo> queryUserByNames(String[] userNames);
|
||||
|
||||
|
||||
/**
|
||||
* 根据高级查询条件查询用户
|
||||
* @param superQuery
|
||||
* @param matchType
|
||||
* @return
|
||||
*/
|
||||
List<JSONObject> queryUserBySuperQuery(String superQuery,String matchType);
|
||||
|
||||
|
||||
/**
|
||||
* 根据ID查询用户
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
JSONObject queryUserById(String id);
|
||||
|
||||
|
||||
/**
|
||||
* 根据高级查询条件查询部门
|
||||
* @param superQuery
|
||||
* @param matchType
|
||||
* @return
|
||||
*/
|
||||
List<JSONObject> queryDeptBySuperQuery(String superQuery,String matchType);
|
||||
|
||||
/**
|
||||
* 根据高级查询条件查询角色
|
||||
* @param superQuery
|
||||
* @param matchType
|
||||
* @return
|
||||
*/
|
||||
List<JSONObject> queryRoleBySuperQuery(String superQuery,String matchType);
|
||||
|
||||
|
||||
/**
|
||||
* 根据租户ID查询用户ID
|
||||
* @param tenantId 租户ID
|
||||
* @return List<String>
|
||||
*/
|
||||
List<String> selectUserIdByTenantId(String tenantId);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 31获取用户的角色集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
Set<String> getUserRoleSet(String username);
|
||||
/**
|
||||
* 31获取用户的角色集合
|
||||
* @param useId
|
||||
* @return
|
||||
*/
|
||||
Set<String> getUserRoleSetById(String useId);
|
||||
|
||||
/**
|
||||
* 32获取用户的权限集合
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Set<String> getUserPermissionSet(String userId);
|
||||
|
||||
/**
|
||||
* 33判断是否有online访问的权限
|
||||
* @param onlineAuthDTO
|
||||
* @return
|
||||
*/
|
||||
boolean hasOnlineAuth(OnlineAuthDTO onlineAuthDTO);
|
||||
|
||||
/**
|
||||
* 34通过部门id获取部门全部信息
|
||||
* @param id 部门id
|
||||
* @return SysDepartModel对象
|
||||
*/
|
||||
SysDepartModel selectAllById(String id);
|
||||
|
||||
/**
|
||||
* 35根据用户id查询用户所属公司下所有用户ids
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
List<String> queryDeptUsersByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 36根据多个用户账号(逗号分隔),查询返回多个用户信息
|
||||
* @param usernames
|
||||
* @return
|
||||
*/
|
||||
List<JSONObject> queryUsersByUsernames(String usernames);
|
||||
|
||||
/**
|
||||
* 37根据多个用户ID(逗号分隔),查询返回多个用户信息
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
List<JSONObject> queryUsersByIds(String ids);
|
||||
|
||||
/**
|
||||
* 38根据多个部门编码(逗号分隔),查询返回多个部门信息
|
||||
* @param orgCodes
|
||||
* @return
|
||||
*/
|
||||
List<JSONObject> queryDepartsByOrgcodes(String orgCodes);
|
||||
|
||||
/**
|
||||
* 39根据多个部门id(逗号分隔),查询返回多个部门信息
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
List<JSONObject> queryDepartsByIds(String ids);
|
||||
|
||||
/**
|
||||
* 40发送邮件消息
|
||||
* @param email
|
||||
* @param title
|
||||
* @param content
|
||||
*/
|
||||
void sendEmailMsg(String email,String title,String content);
|
||||
|
||||
/**
|
||||
* 40发送模版邮件消息
|
||||
*
|
||||
* @param email 接收邮箱
|
||||
* @param title 邮件标题
|
||||
* @param emailTemplateEnum 邮件模版枚举
|
||||
* @param params 模版参数
|
||||
*/
|
||||
void sendHtmlTemplateEmail(String email, String title, EmailTemplateEnum emailTemplateEnum, JSONObject params);
|
||||
/**
|
||||
* 41 获取公司下级部门和公司下所有用户信息
|
||||
* @param orgCode
|
||||
* @return List<Map>
|
||||
*/
|
||||
List<Map> getDeptUserByOrgCode(String orgCode);
|
||||
|
||||
/**
|
||||
* 查询分类字典翻译
|
||||
* @param ids 多个分类字典id
|
||||
* @return List<String>
|
||||
*/
|
||||
List<String> loadCategoryDictItem(String ids);
|
||||
|
||||
/**
|
||||
* 反向翻译分类字典,用于导入
|
||||
*
|
||||
* @param names 名称,逗号分割
|
||||
*/
|
||||
List<String> loadCategoryDictItemByNames(String names, boolean delNotExist);
|
||||
|
||||
/**
|
||||
* 根据字典code加载字典text
|
||||
*
|
||||
* @param dictCode 顺序:tableName,text,code
|
||||
* @param keys 要查询的key
|
||||
* @return
|
||||
*/
|
||||
List<String> loadDictItem(String dictCode, String keys);
|
||||
|
||||
/**
|
||||
* 复制应用下的所有字典配置到新的租户下
|
||||
*
|
||||
* @param originalAppId 原始低代码应用ID
|
||||
* @param appId 新的低代码应用ID
|
||||
* @param tenantId 新的租户ID
|
||||
* @return Map<String, String> Map<原字典编码, 新字典编码>
|
||||
*/
|
||||
Map<String, String> copyLowAppDict(String originalAppId, String appId, String tenantId);
|
||||
|
||||
/**
|
||||
* 根据字典code查询字典项
|
||||
*
|
||||
* @param dictCode 顺序:tableName,text,code
|
||||
* @param dictCode 要查询的key
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> getDictItems(String dictCode);
|
||||
|
||||
/**
|
||||
* 根据多个字典code查询多个字典项
|
||||
* @param dictCodeList
|
||||
* @return key = dictCode ; value=对应的字典项
|
||||
*/
|
||||
Map<String, List<DictModel>> getManyDictItems(List<String> dictCodeList);
|
||||
|
||||
/**
|
||||
* 【JSearchSelectTag下拉搜索组件专用接口】
|
||||
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||
*
|
||||
* @param dictCode 字典code格式:table,text,code
|
||||
* @param keyword 过滤关键字
|
||||
* @param pageSize 分页条数
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 新增数据日志
|
||||
* @param dataLogDto
|
||||
*/
|
||||
void saveDataLog(DataLogDTO dataLogDto);
|
||||
/**
|
||||
* 更新头像
|
||||
* @param loginUser
|
||||
*/
|
||||
void updateAvatar(LoginUser loginUser);
|
||||
|
||||
/**
|
||||
* 向app端 websocket推送聊天刷新消息
|
||||
* @param userId
|
||||
*/
|
||||
void sendAppChatSocket(String userId);
|
||||
|
||||
/**
|
||||
* 根据角色id查询角色code
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
String getRoleCodeById(String id);
|
||||
|
||||
/**
|
||||
* 根据roleCode查询角色信息,可逗号分隔多个
|
||||
*
|
||||
* @param roleCodes
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> queryRoleDictByCode(String roleCodes);
|
||||
|
||||
/**
|
||||
* 根据部门ID查询用户ID
|
||||
* @param deptIds
|
||||
* @return
|
||||
*/
|
||||
List<String> queryUserIdsByDeptIds(List<String> deptIds);
|
||||
|
||||
/**
|
||||
* 根据部门ID查询用户账号
|
||||
* @param deptIds
|
||||
* @return
|
||||
*/
|
||||
List<String> queryUserAccountsByDeptIds(List<String> deptIds);
|
||||
|
||||
/**
|
||||
* 根据角色编码 查询用户ID
|
||||
* @param roleCodes
|
||||
* @return
|
||||
*/
|
||||
List<String> queryUserIdsByRoleds(List<String> roleCodes);
|
||||
|
||||
/**
|
||||
* 根据职务ID查询用户ID
|
||||
* @param positionIds
|
||||
* @return
|
||||
*/
|
||||
List<String> queryUserIdsByPositionIds(List<String> positionIds);
|
||||
|
||||
/**
|
||||
* 根据部门和子部门下的所有用户账号
|
||||
*
|
||||
* @param orgCode 部门编码
|
||||
* @return
|
||||
*/
|
||||
public List<String> getUserAccountsByDepCode(String orgCode);
|
||||
|
||||
/**
|
||||
* 检查查询sql的表和字段是否在白名单中
|
||||
*
|
||||
* @param selectSql
|
||||
* @return
|
||||
*/
|
||||
boolean dictTableWhiteListCheckBySql(String selectSql);
|
||||
|
||||
/**
|
||||
* 根据字典表或者字典编码,校验是否在白名单中
|
||||
*
|
||||
* @param tableOrDictCode 表名或dictCode
|
||||
* @param fields 如果传的是dictCode,则该参数必须传null
|
||||
* @return
|
||||
*/
|
||||
boolean dictTableWhiteListCheckByDict(String tableOrDictCode, String... fields);
|
||||
|
||||
}
|
||||
26
jeecg-boot/jeecg-module-system/jeecg-system-api/pom.xml
Normal file
26
jeecg-boot/jeecg-module-system/jeecg-system-api/pom.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>jeecg-module-system</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.7.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>jeecg-system-api</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>jeecg-system-local-api</module>
|
||||
<module>jeecg-system-cloud-api</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-base-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
4
jeecg-boot/jeecg-module-system/jeecg-system-biz/.gitattributes
vendored
Normal file
4
jeecg-boot/jeecg-module-system/jeecg-system-biz/.gitattributes
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
*.js linguist-language=Java
|
||||
*.css linguist-language=Java
|
||||
*.html linguist-language=Java
|
||||
*.vue linguist-language=Java
|
||||
49
jeecg-boot/jeecg-module-system/jeecg-system-biz/pom.xml
Normal file
49
jeecg-boot/jeecg-module-system/jeecg-system-biz/pom.xml
Normal file
@ -0,0 +1,49 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-module-system</artifactId>
|
||||
<version>3.7.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>jeecg-system-biz</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-system-local-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot3</groupId>
|
||||
<artifactId>hibernate-re</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 企业微信/钉钉 api -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>jeewx-api</artifactId>
|
||||
</dependency>
|
||||
<!-- 积木报表 -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.jimureport</groupId>
|
||||
<artifactId>jimureport-spring-boot3-starter-fastjson2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot3</groupId>
|
||||
<artifactId>jimureport-drag</artifactId>
|
||||
<version>2.0.2</version>
|
||||
</dependency>
|
||||
<!-- 积木报表 mongo redis 支持包
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.jimureport</groupId>
|
||||
<artifactId>jimureport-nosql-starter</artifactId>
|
||||
</dependency>-->
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,279 @@
|
||||
package org.jeecg.config.firewall.SqlInjection.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.exception.JeecgSqlInjectionException;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.common.util.sqlparse.JSqlParserUtils;
|
||||
import org.jeecg.common.util.sqlparse.vo.SelectSqlInfo;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.config.firewall.SqlInjection.IDictTableWhiteListHandler;
|
||||
import org.jeecg.config.firewall.interceptor.LowCodeModeInterceptor;
|
||||
import org.jeecg.modules.system.entity.SysTableWhiteList;
|
||||
import org.jeecg.modules.system.security.DictQueryBlackListHandler;
|
||||
import org.jeecg.modules.system.service.ISysTableWhiteListService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 通用情况的白名单处理,若有无法处理的情况,可以单独写实现类
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("dictTableWhiteListHandlerImpl")
|
||||
public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler {
|
||||
|
||||
/**
|
||||
* key-表名
|
||||
* value-字段名,多个逗号隔开
|
||||
* 两种配置方式-- 全部配置成小写
|
||||
* whiteTablesRuleMap.put("sys_user", "*") sys_user所有的字段都支持查询
|
||||
* whiteTablesRuleMap.put("sys_user", "username,password") sys_user中的username和password支持查询
|
||||
*/
|
||||
private static final Map<String, String> whiteTablesRuleMap = new HashMap<>();
|
||||
/**
|
||||
* LowCode 是否为 dev 模式
|
||||
*/
|
||||
private static Boolean LOW_CODE_IS_DEV = null;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ISysTableWhiteListService sysTableWhiteListService;
|
||||
@Autowired
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
|
||||
|
||||
/**
|
||||
* 初始化 whiteTablesRuleMap 方法
|
||||
*/
|
||||
private void init() {
|
||||
// 如果当前为dev模式,则每次都查询数据库,防止缓存
|
||||
if (this.isDev()) {
|
||||
DictTableWhiteListHandlerImpl.whiteTablesRuleMap.clear();
|
||||
}
|
||||
// 如果map为空,则从数据库中查询
|
||||
if (DictTableWhiteListHandlerImpl.whiteTablesRuleMap.isEmpty()) {
|
||||
Map<String, String> ruleMap = sysTableWhiteListService.getAllConfigMap();
|
||||
log.info("表字典白名单初始化完成:{}", ruleMap);
|
||||
DictTableWhiteListHandlerImpl.whiteTablesRuleMap.putAll(ruleMap);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPassBySql(String sql) {
|
||||
Map<String, SelectSqlInfo> parsedMap = null;
|
||||
try {
|
||||
parsedMap = JSqlParserUtils.parseAllSelectTable(sql);
|
||||
} catch (Exception e) {
|
||||
log.warn("校验sql语句,解析报错:{}", e.getMessage());
|
||||
}
|
||||
// 如果sql有问题,则肯定执行不了,所以直接返回true
|
||||
if (parsedMap == null) {
|
||||
return true;
|
||||
}
|
||||
log.info("获取select sql信息 :{} ", parsedMap);
|
||||
// 遍历当前sql中的所有表名,如果有其中一个表或表的字段不在白名单中,则不通过
|
||||
for (Map.Entry<String, SelectSqlInfo> entry : parsedMap.entrySet()) {
|
||||
SelectSqlInfo sqlInfo = entry.getValue();
|
||||
if (sqlInfo.isSelectAll()) {
|
||||
log.warn("查询语句中包含 * 字段,暂时先通过");
|
||||
continue;
|
||||
}
|
||||
Set<String> queryFields = sqlInfo.getAllRealSelectFields();
|
||||
// 校验表名和字段是否允许查询
|
||||
String tableName = entry.getKey();
|
||||
if (!this.checkWhiteList(tableName, queryFields)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPassByDict(String dictCodeString) {
|
||||
if (oConvertUtils.isEmpty(dictCodeString)) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
// 针对转义字符进行解码
|
||||
dictCodeString = URLDecoder.decode(dictCodeString, "UTF-8");
|
||||
} catch (Exception e) {
|
||||
log.warn(e.getMessage());
|
||||
//this.throwException("字典code解码失败,可能是使用了非法字符,请检查!");
|
||||
}
|
||||
dictCodeString = dictCodeString.trim();
|
||||
String[] arr = dictCodeString.split(SymbolConstant.COMMA);
|
||||
// 获取表名
|
||||
String tableName = this.getTableName(arr[0]);
|
||||
// 获取查询字段
|
||||
arr = Arrays.copyOfRange(arr, 1, arr.length);
|
||||
// distinct的作用是去重,相当于 Set<String>
|
||||
String[] fields = Arrays.stream(arr).map(String::trim).distinct().toArray(String[]::new);
|
||||
// 校验表名和字段是否允许查询
|
||||
return this.isPassByDict(tableName, fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPassByDict(String tableName, String... fields) {
|
||||
if (oConvertUtils.isEmpty(tableName)) {
|
||||
return true;
|
||||
}
|
||||
if (fields == null || fields.length == 0) {
|
||||
fields = new String[]{"*"};
|
||||
}
|
||||
String sql = "select " + String.join(",", fields) + " from " + tableName;
|
||||
log.info("字典拼接的查询SQL:{}", sql);
|
||||
try {
|
||||
// 进行SQL解析
|
||||
JSqlParserUtils.parseSelectSqlInfo(sql);
|
||||
} catch (Exception e) {
|
||||
// 如果SQL解析失败,则通过字段名和表名进行校验
|
||||
return checkWhiteList(tableName, new HashSet<>(Arrays.asList(fields)));
|
||||
}
|
||||
// 通过SQL解析进行校验,可防止SQL注入
|
||||
return this.isPassBySql(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验表名和字段是否在白名单内
|
||||
*
|
||||
* @param tableName
|
||||
* @param queryFields
|
||||
* @return
|
||||
*/
|
||||
public boolean checkWhiteList(String tableName, Set<String> queryFields) {
|
||||
this.init();
|
||||
// 1、判断“表名”是否通过校验,如果为空则未通过校验
|
||||
if (oConvertUtils.isEmpty(tableName)) {
|
||||
log.error("白名单校验:表名为空");
|
||||
this.throwException();
|
||||
}
|
||||
// 统一转成小写
|
||||
tableName = tableName.toLowerCase();
|
||||
String allowFieldStr = DictTableWhiteListHandlerImpl.whiteTablesRuleMap.get(tableName);
|
||||
log.info("checkWhiteList tableName: {}", tableName);
|
||||
if (oConvertUtils.isEmpty(allowFieldStr)) {
|
||||
// 如果是dev模式,自动向数据库里添加数据
|
||||
if (this.isDev()) {
|
||||
this.autoAddWhiteList(tableName, String.join(",", queryFields));
|
||||
allowFieldStr = DictTableWhiteListHandlerImpl.whiteTablesRuleMap.get(tableName);
|
||||
} else {
|
||||
// prod模式下,直接抛出异常
|
||||
log.error("白名单校验:表\"{}\"未通过校验", tableName);
|
||||
this.throwException();
|
||||
}
|
||||
}
|
||||
// 2、判断“字段名”是否通过校验
|
||||
// 统一转成小写
|
||||
allowFieldStr = allowFieldStr.toLowerCase();
|
||||
Set<String> allowFields = new HashSet<>(Arrays.asList(allowFieldStr.split(",")));
|
||||
// 需要合并的字段
|
||||
Set<String> waitMergerFields = new HashSet<>();
|
||||
for (String field : queryFields) {
|
||||
if(oConvertUtils.isEmpty(field)){
|
||||
continue;
|
||||
}
|
||||
// 统一转成小写
|
||||
field = field.toLowerCase();
|
||||
// 如果允许的字段里不包含查询的字段,则直接抛出异常
|
||||
if (!allowFields.contains(field)) {
|
||||
// 如果是dev模式,记录需要合并的字段
|
||||
if (this.isDev()) {
|
||||
waitMergerFields.add(field);
|
||||
} else {
|
||||
log.error("白名单校验:字段 {} 不在 {} 范围内,拒绝访问!", field, allowFields);
|
||||
this.throwException();
|
||||
}
|
||||
}
|
||||
}
|
||||
// 自动向数据库中合并未通过的字段
|
||||
if (!waitMergerFields.isEmpty()) {
|
||||
this.autoAddWhiteList(tableName, String.join(",", waitMergerFields));
|
||||
}
|
||||
log.info("白名单校验:查询表\"{}\",查询字段 {} 通过校验", tableName, queryFields);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动添加白名单,如果数据库已有,则字段会自动合并
|
||||
*
|
||||
* @param tableName
|
||||
* @param allowFieldStr
|
||||
*/
|
||||
private void autoAddWhiteList(String tableName, String allowFieldStr) {
|
||||
try {
|
||||
SysTableWhiteList entity = sysTableWhiteListService.autoAdd(tableName, allowFieldStr);
|
||||
DictTableWhiteListHandlerImpl.whiteTablesRuleMap.put(tableName, entity.getFieldName());
|
||||
log.warn("表\"{}\"未通过校验,且当前为 dev 模式,已自动向数据库中增加白名单数据。查询字段:{}", tableName, allowFieldStr);
|
||||
} catch (Exception e) {
|
||||
log.error("表\"{}\"未通过校验,且当前为 dev 模式,但自动向数据库中增加白名单数据失败,请排查后重试。错误原因:{}", tableName, e.getMessage(), e);
|
||||
this.throwException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前 LowCode 是否为 dev 模式
|
||||
*/
|
||||
private boolean isDev() {
|
||||
if (DictTableWhiteListHandlerImpl.LOW_CODE_IS_DEV == null) {
|
||||
if (this.jeecgBaseConfig.getFirewall() != null) {
|
||||
String lowCodeMode = this.jeecgBaseConfig.getFirewall().getLowCodeMode();
|
||||
DictTableWhiteListHandlerImpl.LOW_CODE_IS_DEV = LowCodeModeInterceptor.LOW_CODE_MODE_DEV.equals(lowCodeMode);
|
||||
} else {
|
||||
// 如果没有 firewall 配置,则默认为 false
|
||||
DictTableWhiteListHandlerImpl.LOW_CODE_IS_DEV = false;
|
||||
}
|
||||
}
|
||||
return DictTableWhiteListHandlerImpl.LOW_CODE_IS_DEV;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clear() {
|
||||
DictTableWhiteListHandlerImpl.whiteTablesRuleMap.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取where前面的为:table name
|
||||
*
|
||||
* @param str
|
||||
* @see DictQueryBlackListHandler#getTableName(String)
|
||||
*/
|
||||
@SuppressWarnings("JavadocReference")
|
||||
private String getTableName(String str) {
|
||||
String[] arr = str.split("\\s+(?i)where\\s+");
|
||||
String tableName = arr[0].trim();
|
||||
//【20230814】解决使用参数tableName=sys_user t&复测,漏洞仍然存在
|
||||
if (tableName.contains(".")) {
|
||||
tableName = tableName.substring(tableName.indexOf(".") + 1, tableName.length()).trim();
|
||||
}
|
||||
if (tableName.contains(" ")) {
|
||||
tableName = tableName.substring(0, tableName.indexOf(" ")).trim();
|
||||
}
|
||||
|
||||
//【issues/4393】 sys_user , (sys_user), sys_user%20, %60sys_user%60
|
||||
String reg = "\\s+|\\(|\\)|`";
|
||||
return tableName.replaceAll(reg, "");
|
||||
}
|
||||
|
||||
private void throwException() throws JeecgSqlInjectionException {
|
||||
this.throwException(this.getErrorMsg());
|
||||
}
|
||||
|
||||
private void throwException(String message) throws JeecgSqlInjectionException {
|
||||
if (oConvertUtils.isEmpty(message)) {
|
||||
message = this.getErrorMsg();
|
||||
}
|
||||
log.error(message);
|
||||
throw new JeecgSqlInjectionException(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMsg() {
|
||||
return "白名单校验未通过!";
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package org.jeecg.config.init;
|
||||
|
||||
import com.alibaba.druid.filter.config.ConfigTools;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecgframework.codegenerate.database.CodegenDatasourceConfig;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @Description: 代码生成器,自定义DB配置
|
||||
* 【加了此类,则online模式DB连接,使用平台的配置,jeecg_database.properties配置无效;
|
||||
* 但是使用GUI模式代码生成,还是走jeecg_database.properties配置】
|
||||
* 提醒: 达梦数据库需要修改下面的参数${spring.datasource.dynamic.datasource.master.url:}配置
|
||||
* @author: scott
|
||||
* @date: 2021年02月18日 16:30
|
||||
*
|
||||
* 重要说明:此类改路径或者名称,需要同步修改
|
||||
* org/jeecg/interceptor/OnlineRepairCodeGenerateDbConfig.java里面的注解
|
||||
* @ConditionalOnMissingClass("org.jeecg.config.init.CodeGenerateDbConfig")
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class CodeGenerateDbConfig {
|
||||
@Value("${spring.datasource.dynamic.datasource.master.url:}")
|
||||
private String url;
|
||||
@Value("${spring.datasource.dynamic.datasource.master.username:}")
|
||||
private String username;
|
||||
@Value("${spring.datasource.dynamic.datasource.master.password:}")
|
||||
private String password;
|
||||
@Value("${spring.datasource.dynamic.datasource.master.driver-class-name:}")
|
||||
private String driverClassName;
|
||||
@Value("${spring.datasource.dynamic.datasource.master.druid.public-key:}")
|
||||
private String publicKey;
|
||||
|
||||
|
||||
@Bean
|
||||
public CodeGenerateDbConfig initCodeGenerateDbConfig() {
|
||||
if(StringUtils.isNotBlank(url)){
|
||||
if(StringUtils.isNotBlank(publicKey)){
|
||||
try {
|
||||
password = ConfigTools.decrypt(publicKey, password);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error(" 代码生成器数据库连接,数据库密码解密失败!");
|
||||
}
|
||||
}
|
||||
CodegenDatasourceConfig.initDbConfig(driverClassName,url, username, password);
|
||||
log.info(" Init CodeGenerate Config [ Get Db Config From application.yml ] ");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
package org.jeecg.config.init;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 自动初始化代码生成器模板
|
||||
* <p>
|
||||
* 解决JAR发布需要手工配置代码生成器模板问题
|
||||
* @author zhang
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CodeTemplateInitListener implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
try {
|
||||
log.info(" Init Code Generate Template [ 检测如果是JAR启动环境,Copy模板到config目录 ] ");
|
||||
this.initJarConfigCodeGeneratorTemplate();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ::Jar包启动模式下::
|
||||
* 初始化代码生成器模板文件
|
||||
*/
|
||||
private void initJarConfigCodeGeneratorTemplate() throws Exception {
|
||||
//1.获取jar同级下的config路径
|
||||
String configPath = System.getProperty("user.dir") + File.separator + "config" + File.separator;
|
||||
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||
Resource[] resources = resolver.getResources("classpath*:jeecg/code-template-online/**/*");
|
||||
for (Resource re : resources) {
|
||||
URL url = re.getURL();
|
||||
String filepath = url.getPath();
|
||||
//System.out.println("native url= " + filepath);
|
||||
filepath = java.net.URLDecoder.decode(filepath, "utf-8");
|
||||
//System.out.println("decode url= " + filepath);
|
||||
|
||||
//2.在config下,创建jeecg/code-template-online/*模板
|
||||
String createFilePath = configPath + filepath.substring(filepath.indexOf("jeecg/code-template-online"));
|
||||
|
||||
// 非jar模式不生成模板
|
||||
// 不生成目录,只生成具体模板文件
|
||||
if (!filepath.contains(".jar!/BOOT-INF/lib/") || !createFilePath.contains(".")) {
|
||||
continue;
|
||||
}
|
||||
if (!FileUtil.exist(createFilePath)) {
|
||||
log.info("create file codeTemplate = " + createFilePath);
|
||||
FileUtil.writeString(IOUtils.toString(url, StandardCharsets.UTF_8), createFilePath, "UTF-8");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package org.jeecg.config.init;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.config.JeecgCloudCondition;
|
||||
import org.jeecg.modules.system.service.ISysGatewayRouteService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @desc: 启动程序,初始化路由配置
|
||||
* @author: flyme
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@Conditional(JeecgCloudCondition.class)
|
||||
public class SystemInitListener implements ApplicationListener<ApplicationReadyEvent>, Ordered {
|
||||
|
||||
|
||||
@Autowired
|
||||
private ISysGatewayRouteService sysGatewayRouteService;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
|
||||
|
||||
log.info(" 服务已启动,初始化路由配置 ###################");
|
||||
String context = "AnnotationConfigServletWebServerApplicationContext";
|
||||
if (applicationReadyEvent.getApplicationContext().getDisplayName().indexOf(context) > -1) {
|
||||
sysGatewayRouteService.addRoute2Redis(CacheConstant.GATEWAY_ROUTES);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
//package org.jeecg.config.init;
|
||||
//
|
||||
//import org.apache.catalina.Context;
|
||||
//import org.apache.tomcat.util.scan.StandardJarScanner;
|
||||
//import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//
|
||||
///**
|
||||
// * @Description: TomcatFactoryConfig
|
||||
// * @author: scott
|
||||
// * @date: 2021年01月25日 11:40
|
||||
// */
|
||||
//@Configuration
|
||||
//public class TomcatFactoryConfig {
|
||||
// /**
|
||||
// * tomcat-embed-jasper引用后提示jar找不到的问题
|
||||
// */
|
||||
// @Bean
|
||||
// public TomcatServletWebServerFactory tomcatFactory() {
|
||||
// TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory() {
|
||||
// @Override
|
||||
// protected void postProcessContext(Context context) {
|
||||
// ((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
|
||||
// }
|
||||
// };
|
||||
// factory.addConnectorCustomizers(connector -> {
|
||||
// connector.setProperty("relaxedPathChars", "[]{}");
|
||||
// connector.setProperty("relaxedQueryChars", "[]{}");
|
||||
// });
|
||||
// return factory;
|
||||
// }
|
||||
//}
|
||||
@ -0,0 +1,102 @@
|
||||
//package org.jeecg.config.jimureport;
|
||||
//
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.jeecg.common.api.dto.LogDTO;
|
||||
//import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
//import org.jeecg.common.system.vo.DictModel;
|
||||
//import org.jeecg.common.util.oConvertUtils;
|
||||
//import org.jeecg.modules.base.service.BaseCommonService;
|
||||
//import org.jeecg.modules.drag.service.IOnlDragExternalService;
|
||||
//import org.jeecg.modules.drag.vo.DragDictModel;
|
||||
//import org.jeecg.modules.drag.vo.DragLogDTO;
|
||||
//import org.springframework.beans.BeanUtils;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.context.annotation.Lazy;
|
||||
//import org.springframework.stereotype.Service;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.HashMap;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//
|
||||
///**
|
||||
// * @Description: 字典处理
|
||||
// * @Author: lsq
|
||||
// * @Date:2023-01-09
|
||||
// * @Version:V1.0
|
||||
// */
|
||||
//@Slf4j
|
||||
//@Service("onlDragExternalServiceImpl")
|
||||
//public class JimuDragExternalServiceImpl implements IOnlDragExternalService {
|
||||
//
|
||||
// @Autowired
|
||||
// @Lazy
|
||||
// private BaseCommonService baseCommonService;
|
||||
//
|
||||
// @Autowired
|
||||
// @Lazy
|
||||
// private ISysBaseAPI sysBaseApi;
|
||||
// /**
|
||||
// * 根据多个字典code查询多个字典项
|
||||
// * @param codeList
|
||||
// * @return key = dictCode ; value=对应的字典项
|
||||
// */
|
||||
// @Override
|
||||
// public Map<String, List<DragDictModel>> getManyDictItems(List<String> codeList) {
|
||||
// Map<String, List<DragDictModel>> manyDragDictItems = new HashMap<>();
|
||||
// Map<String, List<DictModel>> dictItemsMap = sysBaseApi.getManyDictItems(codeList);
|
||||
// dictItemsMap.forEach((k,v)->{
|
||||
// List<DragDictModel> dictItems = new ArrayList<>();
|
||||
// v.forEach(dictItem->{
|
||||
// DragDictModel dictModel = new DragDictModel();
|
||||
// BeanUtils.copyProperties(dictItem,dictModel);
|
||||
// dictItems.add(dictModel);
|
||||
// });
|
||||
// manyDragDictItems.put(k,dictItems);
|
||||
// });
|
||||
// return manyDragDictItems;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// *
|
||||
// * @param dictCode
|
||||
// * @return
|
||||
// */
|
||||
// @Override
|
||||
// public List<DragDictModel> getDictItems(String dictCode) {
|
||||
// List<DragDictModel> dictItems = new ArrayList<>();
|
||||
// if(oConvertUtils.isNotEmpty(dictCode)){
|
||||
// List<DictModel> dictItemsList = sysBaseApi.getDictItems(dictCode);
|
||||
// dictItemsList.forEach(dictItem->{
|
||||
// DragDictModel dictModel = new DragDictModel();
|
||||
// BeanUtils.copyProperties(dictItem,dictModel);
|
||||
// dictItems.add(dictModel);
|
||||
// });
|
||||
// }
|
||||
// return dictItems;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 添加日志
|
||||
// * @param dragLogDTO
|
||||
// */
|
||||
// @Override
|
||||
// public void addLog(DragLogDTO dragLogDTO) {
|
||||
// if(oConvertUtils.isNotEmpty(dragLogDTO)){
|
||||
// LogDTO dto = new LogDTO();
|
||||
// BeanUtils.copyProperties(dragLogDTO,dto);
|
||||
// baseCommonService.addLog(dto);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 保存日志
|
||||
// * @param logMsg
|
||||
// * @param logType
|
||||
// * @param operateType
|
||||
// */
|
||||
// @Override
|
||||
// public void addLog(String logMsg, int logType, int operateType) {
|
||||
// baseCommonService.addLog(logMsg,logType,operateType);
|
||||
// }
|
||||
//}
|
||||
@ -0,0 +1,81 @@
|
||||
//package org.jeecg.config.jimureport;
|
||||
//
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.jeecg.common.system.util.JwtUtil;
|
||||
//import org.jeecg.common.system.vo.SysUserCacheInfo;
|
||||
//import org.jeecg.common.util.RedisUtil;
|
||||
//import org.jeecg.common.util.TokenUtils;
|
||||
//import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
|
||||
//import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.context.annotation.Lazy;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//import org.springframework.util.CollectionUtils;
|
||||
//
|
||||
//import jakarta.servlet.http.HttpServletRequest;
|
||||
//import java.util.HashMap;
|
||||
//import java.util.Map;
|
||||
//import java.util.Set;
|
||||
//
|
||||
///**
|
||||
// * 自定义积木报表鉴权(如果不进行自定义,则所有请求不做权限控制)
|
||||
// * * 1.自定义获取登录token
|
||||
// * * 2.自定义获取登录用户
|
||||
// * @author: jeecg-boot
|
||||
// */
|
||||
//
|
||||
//
|
||||
//@Slf4j
|
||||
//@Component
|
||||
//public class JimuReportTokenService implements JmReportTokenServiceI {
|
||||
// @Autowired
|
||||
// private SysBaseApiImpl sysBaseApi;
|
||||
// @Autowired
|
||||
// @Lazy
|
||||
// private RedisUtil redisUtil;
|
||||
//
|
||||
// @Override
|
||||
// public String getToken(HttpServletRequest request) {
|
||||
// return TokenUtils.getTokenByRequest(request);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getUsername(String token) {
|
||||
// return JwtUtil.getUsername(token);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String[] getRoles(String token) {
|
||||
// String username = JwtUtil.getUsername(token);
|
||||
// Set roles = sysBaseApi.getUserRoleSet(username);
|
||||
// if(CollectionUtils.isEmpty(roles)){
|
||||
// return null;
|
||||
// }
|
||||
// return (String[]) roles.toArray(new String[roles.size()]);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Boolean verifyToken(String token) {
|
||||
// return TokenUtils.verifyToken(token, sysBaseApi, redisUtil);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Map<String, Object> getUserInfo(String token) {
|
||||
// Map<String, Object> map = new HashMap(5);
|
||||
// String username = JwtUtil.getUsername(token);
|
||||
// //此处通过token只能拿到一个信息 用户账号 后面的就是根据账号获取其他信息 查询数据或是走redis 用户根据自身业务可自定义
|
||||
// SysUserCacheInfo userInfo = null;
|
||||
// try {
|
||||
// userInfo = sysBaseApi.getCacheUser(username);
|
||||
// } catch (Exception e) {
|
||||
// log.error("获取用户信息异常:"+ e.getMessage());
|
||||
// return map;
|
||||
// }
|
||||
// //设置账号名
|
||||
// map.put(SYS_USER_CODE, userInfo.getSysUserCode());
|
||||
// //设置部门编码
|
||||
// map.put(SYS_ORG_CODE, userInfo.getSysOrgCode());
|
||||
// // 将所有信息存放至map 解析sql/api会根据map的键值解析
|
||||
// return map;
|
||||
// }
|
||||
//}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.jeecg.modules.aop;
|
||||
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.enums.ModuleType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 系统日志注解
|
||||
*
|
||||
* @Author scott
|
||||
* @email jeecgos@163.com
|
||||
* @Date 2019年1月14日
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface TenantLog {
|
||||
|
||||
/**
|
||||
* 操作日志类型(1查询,2添加,3修改,4删除)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int value() default 0;
|
||||
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
package org.jeecg.modules.aop;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.AfterThrowing;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.jeecg.common.api.dto.LogDTO;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.entity.SysTenantPack;
|
||||
import org.jeecg.modules.system.entity.SysTenantPackUser;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author taoYan
|
||||
* @Date 2023/2/16 14:27
|
||||
**/
|
||||
@Aspect
|
||||
@Component
|
||||
public class TenantPackUserLogAspect {
|
||||
|
||||
@Resource
|
||||
private BaseCommonService baseCommonService;
|
||||
|
||||
@Pointcut("@annotation(org.jeecg.modules.aop.TenantLog)")
|
||||
public void tenantLogPointCut() {
|
||||
|
||||
}
|
||||
|
||||
@Around("tenantLogPointCut()")
|
||||
public Object aroundMethod(ProceedingJoinPoint joinPoint)throws Throwable {
|
||||
//System.out.println("环绕通知>>>>>>>>>");
|
||||
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
TenantLog log = method.getAnnotation(TenantLog.class);
|
||||
if(log != null){
|
||||
int opType = log.value();
|
||||
Integer logType = null;
|
||||
String content = null;
|
||||
Integer tenantId = null;
|
||||
//获取参数
|
||||
Object[] args = joinPoint.getArgs();
|
||||
if(args.length>0){
|
||||
for(Object obj: args){
|
||||
if(obj instanceof SysTenantPack){
|
||||
// logType=3 租户操作日志
|
||||
logType = CommonConstant.LOG_TYPE_3;
|
||||
SysTenantPack pack = (SysTenantPack)obj;
|
||||
if(opType==2){
|
||||
content = "创建了角色权限 "+ pack.getPackName();
|
||||
}
|
||||
tenantId = pack.getTenantId();
|
||||
break;
|
||||
}else if(obj instanceof SysTenantPackUser){
|
||||
logType = CommonConstant.LOG_TYPE_3;
|
||||
SysTenantPackUser packUser = (SysTenantPackUser)obj;
|
||||
if(opType==2){
|
||||
content = "将 "+packUser.getRealname()+" 添加到角色 "+ packUser.getPackName();
|
||||
}else if(opType==4){
|
||||
content = "移除了 "+packUser.getPackName()+" 成员 "+ packUser.getRealname();
|
||||
}
|
||||
tenantId = packUser.getTenantId();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(logType!=null){
|
||||
LogDTO dto = new LogDTO();
|
||||
dto.setLogType(logType);
|
||||
dto.setLogContent(content);
|
||||
dto.setOperateType(opType);
|
||||
dto.setTenantId(tenantId);
|
||||
//获取登录用户信息
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
if(sysUser!=null){
|
||||
dto.setUserid(sysUser.getUsername());
|
||||
dto.setUsername(sysUser.getRealname());
|
||||
|
||||
}
|
||||
dto.setCreateTime(new Date());
|
||||
//保存系统日志
|
||||
baseCommonService.addLog(dto);
|
||||
}
|
||||
}
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
|
||||
@AfterThrowing("tenantLogPointCut()")
|
||||
public void afterThrowing()throws Throwable{
|
||||
System.out.println("异常通知");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,977 @@
|
||||
package org.jeecg.modules.api.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.DataLogDTO;
|
||||
import org.jeecg.common.api.dto.OnlineAuthDTO;
|
||||
import org.jeecg.common.api.dto.message.*;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
|
||||
import org.jeecg.common.system.vo.*;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* 服务化 system模块 对外接口请求类
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/api")
|
||||
public class SystemApiController {
|
||||
|
||||
@Autowired
|
||||
private SysBaseApiImpl sysBaseApi;
|
||||
@Autowired
|
||||
private ISysUserService sysUserService;
|
||||
|
||||
/**
|
||||
* 发送系统消息
|
||||
* @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息
|
||||
*/
|
||||
@PostMapping("/sendSysAnnouncement")
|
||||
public void sendSysAnnouncement(@RequestBody MessageDTO message){
|
||||
sysBaseApi.sendSysAnnouncement(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息 附带业务参数
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
@PostMapping("/sendBusAnnouncement")
|
||||
public void sendBusAnnouncement(@RequestBody BusMessageDTO message){
|
||||
sysBaseApi.sendBusAnnouncement(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过模板发送消息
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
@PostMapping("/sendTemplateAnnouncement")
|
||||
public void sendTemplateAnnouncement(@RequestBody TemplateMessageDTO message){
|
||||
sysBaseApi.sendTemplateAnnouncement(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过模板发送消息 附带业务参数
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
@PostMapping("/sendBusTemplateAnnouncement")
|
||||
public void sendBusTemplateAnnouncement(@RequestBody BusTemplateMessageDTO message){
|
||||
sysBaseApi.sendBusTemplateAnnouncement(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过消息中心模板,生成推送内容
|
||||
* @param templateDTO 使用构造器赋值参数
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/parseTemplateByCode")
|
||||
public String parseTemplateByCode(@RequestBody TemplateDTO templateDTO){
|
||||
return sysBaseApi.parseTemplateByCode(templateDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据业务类型busType及业务busId修改消息已读
|
||||
*/
|
||||
@GetMapping("/updateSysAnnounReadFlag")
|
||||
public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId")String busId){
|
||||
sysBaseApi.updateSysAnnounReadFlag(busType, busId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户账号查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserByName")
|
||||
public LoginUser getUserByName(@RequestParam("username") String username){
|
||||
LoginUser loginUser = sysBaseApi.getUserByName(username);
|
||||
//用户信息加密
|
||||
try {
|
||||
SensitiveInfoUtil.handlerObject(loginUser, true);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户账号查询用户ID
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserIdByName")
|
||||
public String getUserIdByName(@RequestParam("username") String username){
|
||||
String userId = sysBaseApi.getUserIdByName(username);
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id查询用户信息
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserById")
|
||||
LoginUser getUserById(@RequestParam("id") String id){
|
||||
LoginUser loginUser = sysBaseApi.getUserById(id);
|
||||
//用户信息加密
|
||||
try {
|
||||
SensitiveInfoUtil.handlerObject(loginUser, true);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询角色集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getRolesByUsername")
|
||||
List<String> getRolesByUsername(@RequestParam("username") String username){
|
||||
return sysBaseApi.getRolesByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询角色集合
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getRolesByUserId")
|
||||
List<String> getRolesByUserId(@RequestParam("userId") String userId){
|
||||
return sysBaseApi.getRolesByUserId(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门集合
|
||||
* @param username
|
||||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/getDepartIdsByUsername")
|
||||
List<String> getDepartIdsByUsername(@RequestParam("username") String username){
|
||||
return sysBaseApi.getDepartIdsByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门集合
|
||||
* @param userId
|
||||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/getDepartIdsByUserId")
|
||||
List<String> getDepartIdsByUserId(@RequestParam("userId") String userId){
|
||||
return sysBaseApi.getDepartIdsByUserId(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门父ID集合
|
||||
* @param username
|
||||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/getDepartParentIdsByUsername")
|
||||
Set<String> getDepartParentIdsByUsername(@RequestParam("username") String username){
|
||||
return sysBaseApi.getDepartParentIdsByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询部门父ID集合
|
||||
* @param depIds
|
||||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/getDepartParentIdsByDepIds")
|
||||
Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set<String> depIds){
|
||||
return sysBaseApi.getDepartParentIdsByDepIds(depIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门 name
|
||||
* @param username
|
||||
* @return 部门 name
|
||||
*/
|
||||
@GetMapping("/getDepartNamesByUsername")
|
||||
List<String> getDepartNamesByUsername(@RequestParam("username") String username){
|
||||
return sysBaseApi.getDepartNamesByUsername(username);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取数据字典
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDictItemsByCode")
|
||||
List<DictModel> queryDictItemsByCode(@RequestParam("code") String code){
|
||||
return sysBaseApi.queryDictItemsByCode(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取有效的数据字典
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryEnableDictItemsByCode")
|
||||
List<DictModel> queryEnableDictItemsByCode(@RequestParam("code") String code){
|
||||
return sysBaseApi.queryEnableDictItemsByCode(code);
|
||||
}
|
||||
|
||||
|
||||
/** 查询所有的父级字典,按照create_time排序 */
|
||||
@GetMapping("/queryAllDict")
|
||||
List<DictModel> queryAllDict(){
|
||||
// try{
|
||||
// //睡10秒,gateway网关5秒超时,会触发熔断降级操作
|
||||
// Thread.sleep(10000);
|
||||
// }catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
log.info("--我是jeecg-system服务节点,微服务接口queryAllDict被调用--");
|
||||
return sysBaseApi.queryAllDict();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有分类字典
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllSysCategory")
|
||||
List<SysCategoryModel> queryAllSysCategory(){
|
||||
return sysBaseApi.queryAllSysCategory();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有部门 作为字典信息 id -->value,departName -->text
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllDepartBackDictModel")
|
||||
List<DictModel> queryAllDepartBackDictModel(){
|
||||
return sysBaseApi.queryAllDepartBackDictModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有角色 带参
|
||||
* roleIds 默认选中角色
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllRole")
|
||||
public List<ComboModel> queryAllRole(@RequestParam(name = "roleIds",required = false)String[] roleIds){
|
||||
if(roleIds==null || roleIds.length==0){
|
||||
return sysBaseApi.queryAllRole();
|
||||
}else{
|
||||
return sysBaseApi.queryAllRole(roleIds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询角色Id集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getRoleIdsByUsername")
|
||||
public List<String> getRoleIdsByUsername(@RequestParam("username")String username){
|
||||
return sysBaseApi.getRoleIdsByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过部门编号查询部门id
|
||||
* @param orgCode
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDepartIdsByOrgCode")
|
||||
public String getDepartIdsByOrgCode(@RequestParam("orgCode")String orgCode){
|
||||
return sysBaseApi.getDepartIdsByOrgCode(orgCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有部门
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getAllSysDepart")
|
||||
public List<SysDepartModel> getAllSysDepart(){
|
||||
return sysBaseApi.getAllSysDepart();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 id 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDynamicDbSourceById")
|
||||
DynamicDataSourceModel getDynamicDbSourceById(@RequestParam("dbSourceId")String dbSourceId){
|
||||
return sysBaseApi.getDynamicDbSourceById(dbSourceId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据部门Id获取部门负责人
|
||||
* @param deptId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDeptHeadByDepId")
|
||||
public List<String> getDeptHeadByDepId(@RequestParam("deptId") String deptId){
|
||||
return sysBaseApi.getDeptHeadByDepId(deptId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找父级部门
|
||||
* @param departId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getParentDepartId")
|
||||
public DictModel getParentDepartId(@RequestParam("departId")String departId){
|
||||
return sysBaseApi.getParentDepartId(departId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 code 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceCode
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDynamicDbSourceByCode")
|
||||
public DynamicDataSourceModel getDynamicDbSourceByCode(@RequestParam("dbSourceCode") String dbSourceCode){
|
||||
return sysBaseApi.getDynamicDbSourceByCode(dbSourceCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给指定用户发消息
|
||||
* @param userIds
|
||||
* @param cmd
|
||||
*/
|
||||
@GetMapping("/sendWebSocketMsg")
|
||||
public void sendWebSocketMsg(String[] userIds, String cmd){
|
||||
sysBaseApi.sendWebSocketMsg(userIds, cmd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据id获取所有参与用户
|
||||
* userIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllUserByIds")
|
||||
public List<UserAccountInfo> queryAllUserByIds(@RequestParam("userIds") String[] userIds){
|
||||
return sysBaseApi.queryAllUserByIds(userIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有用户 返回ComboModel
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllUserBackCombo")
|
||||
public List<ComboModel> queryAllUserBackCombo(){
|
||||
return sysBaseApi.queryAllUserBackCombo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询用户 返回JSONObject
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllUser")
|
||||
public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) Integer pageSize){
|
||||
return sysBaseApi.queryAllUser(userIds, pageNo, pageSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 将会议签到信息推动到预览
|
||||
* userIds
|
||||
* @return
|
||||
* @param userId
|
||||
*/
|
||||
@GetMapping("/meetingSignWebsocket")
|
||||
public void meetingSignWebsocket(@RequestParam("userId")String userId){
|
||||
sysBaseApi.meetingSignWebsocket(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据name获取所有参与用户
|
||||
* userNames
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserByNames")
|
||||
public List<UserAccountInfo> queryUserByNames(@RequestParam("userNames")String[] userNames){
|
||||
return sysBaseApi.queryUserByNames(userNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的角色集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserRoleSet")
|
||||
public Set<String> getUserRoleSet(@RequestParam("username")String username){
|
||||
return sysBaseApi.getUserRoleSet(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的角色集合
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserRoleSetById")
|
||||
public Set<String> getUserRoleSetById(@RequestParam("userId")String userId){
|
||||
return sysBaseApi.getUserRoleSetById(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的权限集合
|
||||
* @param userId 用户表ID
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserPermissionSet")
|
||||
public Set<String> getUserPermissionSet(@RequestParam("userId") String userId){
|
||||
return sysBaseApi.getUserPermissionSet(userId);
|
||||
}
|
||||
|
||||
//-----
|
||||
|
||||
/**
|
||||
* 判断是否有online访问的权限
|
||||
* @param onlineAuthDTO
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/hasOnlineAuth")
|
||||
public boolean hasOnlineAuth(@RequestBody OnlineAuthDTO onlineAuthDTO){
|
||||
return sysBaseApi.hasOnlineAuth(onlineAuthDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户角色信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserRoles")
|
||||
public Set<String> queryUserRoles(@RequestParam("username") String username){
|
||||
return sysUserService.getUserRolesSet(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户角色信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserRolesById")
|
||||
public Set<String> queryUserRolesById(@RequestParam("userId") String userId){
|
||||
return sysUserService.getUserRoleSetById(userId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询用户权限信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserAuths")
|
||||
public Set<String> queryUserAuths(@RequestParam("userId") String userId){
|
||||
return sysUserService.getUserPermissionsSet(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过部门id获取部门全部信息
|
||||
*/
|
||||
@GetMapping("/selectAllById")
|
||||
public SysDepartModel selectAllById(@RequestParam("id") String id){
|
||||
return sysBaseApi.selectAllById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id查询用户所属公司下所有用户ids
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDeptUsersByUserId")
|
||||
public List<String> queryDeptUsersByUserId(@RequestParam("userId") String userId){
|
||||
return sysBaseApi.queryDeptUsersByUserId(userId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询数据权限
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryPermissionDataRule")
|
||||
public List<SysPermissionDataRuleModel> queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath")String requestPath, @RequestParam("username") String username){
|
||||
return sysBaseApi.queryPermissionDataRule(component, requestPath, username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getCacheUser")
|
||||
public SysUserCacheInfo getCacheUser(@RequestParam("username") String username){
|
||||
return sysBaseApi.getCacheUser(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通字典的翻译
|
||||
* @param code
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/translateDict")
|
||||
public String translateDict(@RequestParam("code") String code, @RequestParam("key") String key){
|
||||
return sysBaseApi.translateDict(code, key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 36根据多个用户账号(逗号分隔),查询返回多个用户信息
|
||||
* @param usernames
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/queryUsersByUsernames")
|
||||
List<JSONObject> queryUsersByUsernames(@RequestParam("usernames") String usernames){
|
||||
return this.sysBaseApi.queryUsersByUsernames(usernames);
|
||||
}
|
||||
|
||||
/**
|
||||
* 37根据多个用户id(逗号分隔),查询返回多个用户信息
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/queryUsersByIds")
|
||||
List<JSONObject> queryUsersByIds(@RequestParam("ids") String ids){
|
||||
return this.sysBaseApi.queryUsersByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 38根据多个部门编码(逗号分隔),查询返回多个部门信息
|
||||
* @param orgCodes
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDepartsByOrgcodes")
|
||||
List<JSONObject> queryDepartsByOrgcodes(@RequestParam("orgCodes") String orgCodes){
|
||||
return this.sysBaseApi.queryDepartsByOrgcodes(orgCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 39根据多个部门ID(逗号分隔),查询返回多个部门信息
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDepartsByIds")
|
||||
List<JSONObject> queryDepartsByIds(@RequestParam("ids") String ids){
|
||||
return this.sysBaseApi.queryDepartsByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 40发送邮件消息
|
||||
* @param email
|
||||
* @param title
|
||||
* @param content
|
||||
*/
|
||||
@GetMapping("/sendEmailMsg")
|
||||
public void sendEmailMsg(@RequestParam("email")String email,@RequestParam("title")String title,@RequestParam("content")String content){
|
||||
this.sysBaseApi.sendEmailMsg(email,title,content);
|
||||
};
|
||||
/**
|
||||
* 41 获取公司下级部门和公司下所有用户信息
|
||||
* @param orgCode
|
||||
*/
|
||||
@GetMapping("/getDeptUserByOrgCode")
|
||||
List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode){
|
||||
return this.sysBaseApi.getDeptUserByOrgCode(orgCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分类字典翻译
|
||||
*
|
||||
* @param ids 分类字典表id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/loadCategoryDictItem")
|
||||
public List<String> loadCategoryDictItem(@RequestParam("ids") String ids) {
|
||||
return sysBaseApi.loadCategoryDictItem(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 反向翻译分类字典,用于导入
|
||||
*
|
||||
* @param names 名称,逗号分割
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/loadCategoryDictItemByNames")
|
||||
List<String> loadCategoryDictItemByNames(@RequestParam("names") String names, @RequestParam("delNotExist") boolean delNotExist) {
|
||||
return sysBaseApi.loadCategoryDictItemByNames(names, delNotExist);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典code加载字典text
|
||||
*
|
||||
* @param dictCode 顺序:tableName,text,code
|
||||
* @param keys 要查询的key
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/loadDictItem")
|
||||
public List<String> loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys) {
|
||||
return sysBaseApi.loadDictItem(dictCode, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制应用下的所有字典配置到新的租户下
|
||||
*
|
||||
* @param originalAppId 原始低代码应用ID
|
||||
* @param appId 新的低代码应用ID
|
||||
* @param tenantId 新的租户ID
|
||||
* @return Map<String, String> Map<原字典编码, 新字典编码>
|
||||
*/
|
||||
@GetMapping("/copyLowAppDict")
|
||||
Map<String, String> copyLowAppDict(@RequestParam("originalAppId") String originalAppId, @RequestParam("appId") String appId, @RequestParam("tenantId") String tenantId) {
|
||||
return sysBaseApi.copyLowAppDict(originalAppId, appId, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典code查询字典项
|
||||
*
|
||||
* @param dictCode 顺序:tableName,text,code
|
||||
* @param dictCode 要查询的key
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDictItems")
|
||||
public List<DictModel> getDictItems(@RequestParam("dictCode") String dictCode) {
|
||||
return sysBaseApi.getDictItems(dictCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据多个字典code查询多个字典项
|
||||
*
|
||||
* @param dictCodeList
|
||||
* @return key = dictCode ; value=对应的字典项
|
||||
*/
|
||||
@RequestMapping("/getManyDictItems")
|
||||
public Map<String, List<DictModel>> getManyDictItems(@RequestParam("dictCodeList") List<String> dictCodeList) {
|
||||
return sysBaseApi.getManyDictItems(dictCodeList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【下拉搜索】
|
||||
* 大数据量的字典表 走异步加载,即前端输入内容过滤数据
|
||||
*
|
||||
* @param dictCode 字典code格式:table,text,code
|
||||
* @param keyword 过滤关键字
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/loadDictItemByKeyword")
|
||||
public List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
||||
return sysBaseApi.loadDictItemByKeyword(dictCode, keyword, pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 48 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割
|
||||
* @param dictCodes
|
||||
* @param keys
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/translateManyDict")
|
||||
public Map<String, List<DictModel>> translateManyDict(@RequestParam("dictCodes") String dictCodes, @RequestParam("keys") String keys){
|
||||
return this.sysBaseApi.translateManyDict(dictCodes, keys);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取表数据字典 【接口签名验证】
|
||||
* @param tableFilterSql 表名可以带where条件
|
||||
* @param text
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryTableDictItemsByCode")
|
||||
List<DictModel> queryTableDictItemsByCode(@RequestParam("tableFilterSql") String tableFilterSql, @RequestParam("text") String text, @RequestParam("code") String code){
|
||||
return sysBaseApi.queryTableDictItemsByCode(tableFilterSql, text, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询表字典 支持过滤数据 【接口签名验证】
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param filterSql
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryFilterTableDictInfo")
|
||||
List<DictModel> queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql){
|
||||
return sysBaseApi.queryFilterTableDictInfo(table, text, code, filterSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【接口签名验证】
|
||||
* 查询指定table的 text code 获取字典,包含text和value
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keyArray
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
@GetMapping("/queryTableDictByKeys")
|
||||
public List<String> queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray){
|
||||
return sysBaseApi.queryTableDictByKeys(table, text, code, keyArray);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字典表的 翻译【接口签名验证】
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/translateDictFromTable")
|
||||
public String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key){
|
||||
return sysBaseApi.translateDictFromTable(table, text, code, key);
|
||||
}
|
||||
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 【接口签名验证】
|
||||
* 49 字典表的 翻译,可批量
|
||||
*
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys 多个用逗号分割
|
||||
* @param ds 数据源
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/translateDictFromTableByKeys")
|
||||
public List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys, @RequestParam("ds") String ds) {
|
||||
return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys, ds);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
/**
|
||||
* 发送模板信息
|
||||
* @param message
|
||||
*/
|
||||
@PostMapping("/sendTemplateMessage")
|
||||
public void sendTemplateMessage(@RequestBody MessageDTO message){
|
||||
sysBaseApi.sendTemplateMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息模板内容
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getTemplateContent")
|
||||
public String getTemplateContent(@RequestParam("code") String code){
|
||||
return this.sysBaseApi.getTemplateContent(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据日志
|
||||
* @param dataLogDto
|
||||
*/
|
||||
@PostMapping("/saveDataLog")
|
||||
public void saveDataLog(@RequestBody DataLogDTO dataLogDto){
|
||||
this.sysBaseApi.saveDataLog(dataLogDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新头像
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/updateAvatar")
|
||||
public void updateAvatar(@RequestBody LoginUser loginUser){
|
||||
this.sysBaseApi.updateAvatar(loginUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向app端 websocket推送聊天刷新消息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sendAppChatSocket")
|
||||
public void sendAppChatSocket(@RequestParam(name="userId") String userId){
|
||||
this.sysBaseApi.sendAppChatSocket(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据roleCode查询角色信息,可逗号分隔多个
|
||||
*
|
||||
* @param roleCodes
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryRoleDictByCode")
|
||||
public List<DictModel> queryRoleDictByCode(@RequestParam(name = "roleCodes") String roleCodes) {
|
||||
return this.sysBaseApi.queryRoleDictByCode(roleCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息模板内容
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getRoleCode")
|
||||
public String getRoleCode(@RequestParam("id") String id){
|
||||
return this.sysBaseApi.getRoleCodeById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* VUEN-2584【issue】平台sql注入漏洞几个问题
|
||||
* 部分特殊函数 可以将查询结果混夹在错误信息中,导致数据库的信息暴露
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler(java.sql.SQLException.class)
|
||||
public Result<?> handleSQLException(Exception e){
|
||||
String msg = e.getMessage();
|
||||
String extractvalue = "extractvalue";
|
||||
String updatexml = "updatexml";
|
||||
if(msg!=null && (msg.toLowerCase().indexOf(extractvalue)>=0 || msg.toLowerCase().indexOf(updatexml)>=0)){
|
||||
return Result.error("校验失败,sql解析异常!");
|
||||
}
|
||||
return Result.error("校验失败,sql解析异常!" + msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据高级查询条件查询用户
|
||||
* @param superQuery
|
||||
* @param matchType
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserBySuperQuery")
|
||||
public List<JSONObject> queryUserBySuperQuery(@RequestParam("superQuery") String superQuery, @RequestParam("matchType") String matchType) {
|
||||
return sysBaseApi.queryUserBySuperQuery(superQuery,matchType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id条件查询用户
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserById")
|
||||
public JSONObject queryUserById(@RequestParam("id") String id) {
|
||||
return sysBaseApi.queryUserById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据高级查询条件查询部门
|
||||
* @param superQuery
|
||||
* @param matchType
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDeptBySuperQuery")
|
||||
public List<JSONObject> queryDeptBySuperQuery(@RequestParam("superQuery") String superQuery, @RequestParam("matchType") String matchType) {
|
||||
return sysBaseApi.queryDeptBySuperQuery(superQuery,matchType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据高级查询条件查询角色
|
||||
* @param superQuery
|
||||
* @param matchType
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryRoleBySuperQuery")
|
||||
public List<JSONObject> queryRoleBySuperQuery(@RequestParam("superQuery") String superQuery, @RequestParam("matchType") String matchType) {
|
||||
return sysBaseApi.queryRoleBySuperQuery(superQuery,matchType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据租户ID查询用户ID
|
||||
* @param tenantId 租户ID
|
||||
* @return List<String>
|
||||
*/
|
||||
@GetMapping("/selectUserIdByTenantId")
|
||||
public List<String> selectUserIdByTenantId(@RequestParam("tenantId") String tenantId) {
|
||||
return sysBaseApi.selectUserIdByTenantId(tenantId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据部门ID查询用户ID
|
||||
* @param deptIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserIdsByDeptIds")
|
||||
public List<String> queryUserIdsByDeptIds(@RequestParam("deptIds") List<String> deptIds){
|
||||
return sysBaseApi.queryUserIdsByDeptIds(deptIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门ID查询用户ID
|
||||
* @param deptIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserAccountsByDeptIds")
|
||||
public List<String> queryUserAccountsByDeptIds(@RequestParam("deptIds") List<String> deptIds){
|
||||
return sysBaseApi.queryUserAccountsByDeptIds(deptIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色编码 查询用户ID
|
||||
* @param roleCodes
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserIdsByRoleds")
|
||||
public List<String> queryUserIdsByRoleds(@RequestParam("roleCodes") List<String> roleCodes){
|
||||
return sysBaseApi.queryUserIdsByRoleds(roleCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据职务ID查询用户ID
|
||||
* @param positionIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserIdsByPositionIds")
|
||||
public List<String> queryUserIdsByPositionIds(@RequestParam("positionIds") List<String> positionIds){
|
||||
return sysBaseApi.queryUserIdsByPositionIds(positionIds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据部门和子部门下的所有用户账号
|
||||
*
|
||||
* @param orgCode 部门编码
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserAccountsByDepCode")
|
||||
public List<String> getUserAccountsByDepCode(@RequestParam("orgCode") String orgCode){
|
||||
return sysBaseApi.getUserAccountsByDepCode(orgCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查查询sql的表和字段是否在白名单中
|
||||
*
|
||||
* @param selectSql
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/dictTableWhiteListCheckBySql")
|
||||
public boolean dictTableWhiteListCheckBySql(@RequestParam("selectSql") String selectSql) {
|
||||
return sysBaseApi.dictTableWhiteListCheckBySql(selectSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典表或者字典编码,校验是否在白名单中
|
||||
*
|
||||
* @param tableOrDictCode 表名或dictCode
|
||||
* @param fields 如果传的是dictCode,则该参数必须传null
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/dictTableWhiteListCheckByDict")
|
||||
public boolean dictTableWhiteListCheckByDict(
|
||||
@RequestParam("tableOrDictCode") String tableOrDictCode,
|
||||
@RequestParam(value = "fields", required = false) String... fields
|
||||
) {
|
||||
return sysBaseApi.dictTableWhiteListCheckByDict(tableOrDictCode, fields);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
package org.jeecg.modules.cas.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.modules.cas.util.CasServiceUtil;
|
||||
import org.jeecg.modules.cas.util.XmlUtils;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.service.ISysDepartService;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* CAS单点登录客户端登录认证
|
||||
* </p>
|
||||
*
|
||||
* @Author zhoujf
|
||||
* @since 2018-12-20
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/cas/client")
|
||||
public class CasClientController {
|
||||
|
||||
@Autowired
|
||||
private ISysUserService sysUserService;
|
||||
@Autowired
|
||||
private ISysDepartService sysDepartService;
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Value("${cas.prefixUrl}")
|
||||
private String prefixUrl;
|
||||
|
||||
|
||||
@GetMapping("/validateLogin")
|
||||
public Object validateLogin(@RequestParam(name="ticket") String ticket,
|
||||
@RequestParam(name="service") String service,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
log.info("Rest api login.");
|
||||
try {
|
||||
String validateUrl = prefixUrl+"/p3/serviceValidate";
|
||||
String res = CasServiceUtil.getStValidate(validateUrl, ticket, service);
|
||||
log.info("res."+res);
|
||||
final String error = XmlUtils.getTextForElement(res, "authenticationFailure");
|
||||
if(StringUtils.isNotEmpty(error)) {
|
||||
throw new Exception(error);
|
||||
}
|
||||
final String principal = XmlUtils.getTextForElement(res, "user");
|
||||
if (StringUtils.isEmpty(principal)) {
|
||||
throw new Exception("No principal was found in the response from the CAS server.");
|
||||
}
|
||||
log.info("-------token----username---"+principal);
|
||||
//1. 校验用户是否有效
|
||||
SysUser sysUser = sysUserService.getUserByName(principal);
|
||||
result = sysUserService.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
String token = JwtUtil.sign(sysUser.getUsername(), sysUser.getPassword());
|
||||
// 设置超时时间
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
|
||||
|
||||
//获取用户部门信息
|
||||
JSONObject obj = new JSONObject();
|
||||
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
|
||||
obj.put("departs", departs);
|
||||
if (departs == null || departs.size() == 0) {
|
||||
obj.put("multi_depart", 0);
|
||||
} else if (departs.size() == 1) {
|
||||
sysUserService.updateUserDepart(principal, departs.get(0).getOrgCode(),null);
|
||||
obj.put("multi_depart", 1);
|
||||
} else {
|
||||
obj.put("multi_depart", 2);
|
||||
}
|
||||
obj.put("token", token);
|
||||
obj.put("userInfo", sysUser);
|
||||
result.setResult(obj);
|
||||
result.success("登录成功");
|
||||
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
result.error500(e.getMessage());
|
||||
}
|
||||
return new HttpEntity<>(result);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,107 @@
|
||||
package org.jeecg.modules.cas.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
|
||||
/**
|
||||
* @Description: CasServiceUtil
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class CasServiceUtil {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String serviceUrl = "https://cas.8f8.com.cn:8443/cas/p3/serviceValidate";
|
||||
String service = "http://localhost:3003/user/login";
|
||||
String ticket = "ST-5-1g-9cNES6KXNRwq-GuRET103sm0-DESKTOP-VKLS8B3";
|
||||
String res = getStValidate(serviceUrl,ticket, service);
|
||||
|
||||
System.out.println("---------res-----"+res);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证ST
|
||||
*/
|
||||
public static String getStValidate(String url, String st, String service){
|
||||
try {
|
||||
url = url+"?service="+service+"&ticket="+st;
|
||||
CloseableHttpClient httpclient = createHttpClientWithNoSsl();
|
||||
HttpGet httpget = new HttpGet(url);
|
||||
HttpResponse response = httpclient.execute(httpget);
|
||||
String res = readResponse(response);
|
||||
return res == null ? null : (res == "" ? null : res);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读取 response body 内容为字符串
|
||||
*
|
||||
* @param response
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private static String readResponse(HttpResponse response) throws IOException {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
|
||||
String result = new String();
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建模拟客户端(针对 https 客户端禁用 SSL 验证)
|
||||
*
|
||||
* @param cookieStore 缓存的 Cookies 信息
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static CloseableHttpClient createHttpClientWithNoSsl() throws Exception {
|
||||
// Create a trust manager that does not validate certificate chains
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new X509TrustManager() {
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] certs, String authType) {
|
||||
// don't check
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] certs, String authType) {
|
||||
// don't check
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SSLContext ctx = SSLContext.getInstance("TLS");
|
||||
ctx.init(null, trustAllCerts, null);
|
||||
LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(ctx);
|
||||
return HttpClients.custom()
|
||||
.setSSLSocketFactory(sslSocketFactory)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,304 @@
|
||||
package org.jeecg.modules.cas.util;
|
||||
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 解析cas,ST验证后的xml
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
public final class XmlUtils {
|
||||
|
||||
/**
|
||||
* attributes
|
||||
*/
|
||||
private static final String ATTRIBUTES = "attributes";
|
||||
|
||||
/**
|
||||
* Creates a new namespace-aware DOM document object by parsing the given XML.
|
||||
*
|
||||
* @param xml XML content.
|
||||
*
|
||||
* @return DOM document.
|
||||
*/
|
||||
public static Document newDocument(final String xml) {
|
||||
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
final Map<String, Boolean> features = new HashMap(5);
|
||||
features.put(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||
features.put("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
for (final Map.Entry<String, Boolean> entry : features.entrySet()) {
|
||||
try {
|
||||
factory.setFeature(entry.getKey(), entry.getValue());
|
||||
} catch (ParserConfigurationException e) {
|
||||
log.warn("Failed setting XML feature {}: {}", entry.getKey(), e);
|
||||
}
|
||||
}
|
||||
factory.setNamespaceAware(true);
|
||||
try {
|
||||
return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("XML parsing error: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of an XML reader from the XMLReaderFactory.
|
||||
*
|
||||
* @return the XMLReader.
|
||||
*/
|
||||
public static XMLReader getXmlReader() {
|
||||
try {
|
||||
final XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
||||
reader.setFeature("http://xml.org/sax/features/namespaces", true);
|
||||
reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
|
||||
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
return reader;
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Unable to create XMLReader", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the text for a group of elements. Each text element is an entry
|
||||
* in a list.
|
||||
* <p>This method is currently optimized for the use case of two elements in a list.
|
||||
*
|
||||
* @param xmlAsString the xml response
|
||||
* @param element the element to look for
|
||||
* @return the list of text from the elements.
|
||||
*/
|
||||
public static List<String> getTextForElements(final String xmlAsString, final String element) {
|
||||
final List<String> elements = new ArrayList<String>(2);
|
||||
final XMLReader reader = getXmlReader();
|
||||
|
||||
final DefaultHandler handler = new DefaultHandler() {
|
||||
|
||||
private boolean foundElement = false;
|
||||
|
||||
private StringBuilder buffer = new StringBuilder();
|
||||
|
||||
@Override
|
||||
public void startElement(final String uri, final String localName, final String qName,
|
||||
final Attributes attributes) throws SAXException {
|
||||
if (localName.equals(element)) {
|
||||
this.foundElement = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(final String uri, final String localName, final String qName) throws SAXException {
|
||||
if (localName.equals(element)) {
|
||||
this.foundElement = false;
|
||||
elements.add(this.buffer.toString());
|
||||
this.buffer = new StringBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
if (this.foundElement) {
|
||||
this.buffer.append(ch, start, length);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
reader.setContentHandler(handler);
|
||||
reader.setErrorHandler(handler);
|
||||
|
||||
try {
|
||||
reader.parse(new InputSource(new StringReader(xmlAsString)));
|
||||
} catch (final Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the text for a specific element (when we know there is only
|
||||
* one).
|
||||
*
|
||||
* @param xmlAsString the xml response
|
||||
* @param element the element to look for
|
||||
* @return the text value of the element.
|
||||
*/
|
||||
public static String getTextForElement(final String xmlAsString, final String element) {
|
||||
final XMLReader reader = getXmlReader();
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
final DefaultHandler handler = new DefaultHandler() {
|
||||
|
||||
private boolean foundElement = false;
|
||||
|
||||
@Override
|
||||
public void startElement(final String uri, final String localName, final String qName,
|
||||
final Attributes attributes) throws SAXException {
|
||||
if (localName.equals(element)) {
|
||||
this.foundElement = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(final String uri, final String localName, final String qName) throws SAXException {
|
||||
if (localName.equals(element)) {
|
||||
this.foundElement = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
if (this.foundElement) {
|
||||
builder.append(ch, start, length);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
reader.setContentHandler(handler);
|
||||
reader.setErrorHandler(handler);
|
||||
|
||||
try {
|
||||
reader.parse(new InputSource(new StringReader(xmlAsString)));
|
||||
} catch (final Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, Object> extractCustomAttributes(final String xml) {
|
||||
final SAXParserFactory spf = SAXParserFactory.newInstance();
|
||||
spf.setNamespaceAware(true);
|
||||
spf.setValidating(false);
|
||||
try {
|
||||
final SAXParser saxParser = spf.newSAXParser();
|
||||
final XMLReader xmlReader = saxParser.getXMLReader();
|
||||
final CustomAttributeHandler handler = new CustomAttributeHandler();
|
||||
xmlReader.setContentHandler(handler);
|
||||
xmlReader.parse(new InputSource(new StringReader(xml)));
|
||||
return handler.getAttributes();
|
||||
} catch (final Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
private static class CustomAttributeHandler extends DefaultHandler {
|
||||
|
||||
private Map<String, Object> attributes;
|
||||
|
||||
private boolean foundAttributes;
|
||||
|
||||
private String currentAttribute;
|
||||
|
||||
private StringBuilder value;
|
||||
|
||||
@Override
|
||||
public void startDocument() throws SAXException {
|
||||
this.attributes = new HashMap(5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(final String nameSpaceUri, final String localName, final String qName,
|
||||
final Attributes attributes) throws SAXException {
|
||||
if (ATTRIBUTES.equals(localName)) {
|
||||
this.foundAttributes = true;
|
||||
} else if (this.foundAttributes) {
|
||||
this.value = new StringBuilder();
|
||||
this.currentAttribute = localName;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(final char[] chars, final int start, final int length) throws SAXException {
|
||||
if (this.currentAttribute != null) {
|
||||
value.append(chars, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(final String nameSpaceUri, final String localName, final String qName)
|
||||
throws SAXException {
|
||||
if (ATTRIBUTES.equals(localName)) {
|
||||
this.foundAttributes = false;
|
||||
this.currentAttribute = null;
|
||||
} else if (this.foundAttributes) {
|
||||
final Object o = this.attributes.get(this.currentAttribute);
|
||||
|
||||
if (o == null) {
|
||||
this.attributes.put(this.currentAttribute, this.value.toString());
|
||||
} else {
|
||||
final List<Object> items;
|
||||
if (o instanceof List) {
|
||||
items = (List<Object>) o;
|
||||
} else {
|
||||
items = new LinkedList<Object>();
|
||||
items.add(o);
|
||||
this.attributes.put(this.currentAttribute, items);
|
||||
}
|
||||
items.add(this.value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> getAttributes() {
|
||||
return this.attributes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
String result = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\r\n" +
|
||||
" <cas:authenticationSuccess>\r\n" +
|
||||
" <cas:user>admin</cas:user>\r\n" +
|
||||
" <cas:attributes>\r\n" +
|
||||
" <cas:credentialType>UsernamePasswordCredential</cas:credentialType>\r\n" +
|
||||
" <cas:isFromNewLogin>true</cas:isFromNewLogin>\r\n" +
|
||||
" <cas:authenticationDate>2019-08-01T19:33:21.527+08:00[Asia/Shanghai]</cas:authenticationDate>\r\n" +
|
||||
" <cas:authenticationMethod>RestAuthenticationHandler</cas:authenticationMethod>\r\n" +
|
||||
" <cas:successfulAuthenticationHandlers>RestAuthenticationHandler</cas:successfulAuthenticationHandlers>\r\n" +
|
||||
" <cas:longTermAuthenticationRequestTokenUsed>false</cas:longTermAuthenticationRequestTokenUsed>\r\n" +
|
||||
" </cas:attributes>\r\n" +
|
||||
" </cas:authenticationSuccess>\r\n" +
|
||||
"</cas:serviceResponse>";
|
||||
|
||||
String errorRes = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\r\n" +
|
||||
" <cas:authenticationFailure code=\"INVALID_TICKET\">未能够识别出目标 'ST-5-1g-9cNES6KXNRwq-GuRET103sm0-DESKTOP-VKLS8B3'票根</cas:authenticationFailure>\r\n" +
|
||||
"</cas:serviceResponse>";
|
||||
|
||||
String error = XmlUtils.getTextForElement(errorRes, "authenticationFailure");
|
||||
System.out.println("------"+error);
|
||||
|
||||
String error2 = XmlUtils.getTextForElement(result, "authenticationFailure");
|
||||
System.out.println("------"+error2);
|
||||
String principal = XmlUtils.getTextForElement(result, "user");
|
||||
System.out.println("---principal---"+principal);
|
||||
Map<String, Object> attributes = XmlUtils.extractCustomAttributes(result);
|
||||
System.out.println("---attributes---"+attributes);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,145 @@
|
||||
package org.jeecg.modules.message.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.message.entity.SysMessage;
|
||||
import org.jeecg.modules.message.service.ISysMessageService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @Description: 消息
|
||||
* @author: jeecg-boot
|
||||
* @date: 2019-04-09
|
||||
* @version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/message/sysMessage")
|
||||
public class SysMessageController extends JeecgController<SysMessage, ISysMessageService> {
|
||||
@Autowired
|
||||
private ISysMessageService sysMessageService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysMessage
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(SysMessage sysMessage, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
QueryWrapper<SysMessage> queryWrapper = QueryGenerator.initQueryWrapper(sysMessage, req.getParameterMap());
|
||||
Page<SysMessage> page = new Page<SysMessage>(pageNo, pageSize);
|
||||
IPage<SysMessage> pageList = sysMessageService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysMessage
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysMessage sysMessage) {
|
||||
sysMessageService.save(sysMessage);
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysMessage
|
||||
* @return
|
||||
*/
|
||||
@PutMapping(value = "/edit")
|
||||
public Result<?> edit(@RequestBody SysMessage sysMessage) {
|
||||
sysMessageService.updateById(sysMessage);
|
||||
return Result.ok("修改成功!");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
sysMessageService.removeById(id);
|
||||
return Result.ok("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
|
||||
this.sysMessageService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
SysMessage sysMessage = sysMessageService.getById(id);
|
||||
return Result.ok(sysMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
@GetMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysMessage sysMessage) {
|
||||
return super.exportXls(request,sysMessage,SysMessage.class, "推送消息模板");
|
||||
}
|
||||
|
||||
/**
|
||||
* excel导入
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/importExcel")
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysMessage.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,180 @@
|
||||
package org.jeecg.modules.message.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.message.entity.MsgParams;
|
||||
import org.jeecg.modules.message.entity.SysMessageTemplate;
|
||||
import org.jeecg.modules.message.service.ISysMessageTemplateService;
|
||||
import org.jeecg.modules.message.util.PushMsgUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @Description: 消息模板
|
||||
* @Author: jeecg-boot
|
||||
* @Sate: 2019-04-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/message/sysMessageTemplate")
|
||||
public class SysMessageTemplateController extends JeecgController<SysMessageTemplate, ISysMessageTemplateService> {
|
||||
@Autowired
|
||||
private ISysMessageTemplateService sysMessageTemplateService;
|
||||
@Autowired
|
||||
private PushMsgUtil pushMsgUtil;
|
||||
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseApi;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysMessageTemplate
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(SysMessageTemplate sysMessageTemplate, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
QueryWrapper<SysMessageTemplate> queryWrapper = QueryGenerator.initQueryWrapper(sysMessageTemplate, req.getParameterMap());
|
||||
Page<SysMessageTemplate> page = new Page<SysMessageTemplate>(pageNo, pageSize);
|
||||
IPage<SysMessageTemplate> pageList = sysMessageTemplateService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysMessageTemplate
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysMessageTemplate sysMessageTemplate) {
|
||||
sysMessageTemplateService.save(sysMessageTemplate);
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysMessageTemplate
|
||||
* @return
|
||||
*/
|
||||
@PutMapping(value = "/edit")
|
||||
public Result<?> edit(@RequestBody SysMessageTemplate sysMessageTemplate) {
|
||||
sysMessageTemplateService.updateById(sysMessageTemplate);
|
||||
return Result.ok("更新成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
sysMessageTemplateService.removeById(id);
|
||||
return Result.ok("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
this.sysMessageTemplateService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
SysMessageTemplate sysMessageTemplate = sysMessageTemplateService.getById(id);
|
||||
return Result.ok(sysMessageTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
@GetMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request,SysMessageTemplate sysMessageTemplate) {
|
||||
return super.exportXls(request, sysMessageTemplate, SysMessageTemplate.class,"推送消息模板");
|
||||
}
|
||||
|
||||
/**
|
||||
* excel导入
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/importExcel")
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysMessageTemplate.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*/
|
||||
@PostMapping(value = "/sendMsg")
|
||||
public Result<SysMessageTemplate> sendMessage(@RequestBody MsgParams msgParams) {
|
||||
Result<SysMessageTemplate> result = new Result<SysMessageTemplate>();
|
||||
try {
|
||||
MessageDTO md = new MessageDTO();
|
||||
md.setToAll(false);
|
||||
md.setTitle("消息发送测试");
|
||||
md.setTemplateCode(msgParams.getTemplateCode());
|
||||
md.setToUser(msgParams.getReceiver());
|
||||
md.setType(msgParams.getMsgType());
|
||||
String testData = msgParams.getTestData();
|
||||
if(oConvertUtils.isNotEmpty(testData)){
|
||||
Map<String, Object> data = JSON.parseObject(testData, Map.class);
|
||||
md.setData(data);
|
||||
}
|
||||
sysBaseApi.sendTemplateMessage(md);
|
||||
return result.success("消息发送成功!");
|
||||
} catch (Exception e) {
|
||||
log.error("发送消息出错:" + e.getMessage(), e);
|
||||
return result.error500("发送消息出错!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package org.jeecg.modules.message.controller;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.modules.message.websocket.WebSocket;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
* @Description: TestSocketController
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/socketTest")
|
||||
public class TestSocketController {
|
||||
|
||||
@Autowired
|
||||
private WebSocket webSocket;
|
||||
|
||||
@PostMapping("/sendAll")
|
||||
public Result<String> sendAll(@RequestBody JSONObject jsonObject) {
|
||||
Result<String> result = new Result<String>();
|
||||
String message = jsonObject.getString("message");
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
|
||||
obj.put(WebsocketConst.MSG_ID, "M0001");
|
||||
obj.put(WebsocketConst.MSG_TXT, message);
|
||||
webSocket.sendMessage(obj.toJSONString());
|
||||
result.setResult("群发!");
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/sendUser")
|
||||
public Result<String> sendUser(@RequestBody JSONObject jsonObject) {
|
||||
Result<String> result = new Result<String>();
|
||||
String userId = jsonObject.getString("userId");
|
||||
String message = jsonObject.getString("message");
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
|
||||
obj.put(WebsocketConst.MSG_USER_ID, userId);
|
||||
obj.put(WebsocketConst.MSG_ID, "M0001");
|
||||
obj.put(WebsocketConst.MSG_TXT, message);
|
||||
webSocket.sendMessage(userId, obj.toJSONString());
|
||||
result.setResult("单发");
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package org.jeecg.modules.message.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 发送消息实体
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Data
|
||||
public class MsgParams implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
private String msgType;
|
||||
|
||||
/**
|
||||
* 消息接收方
|
||||
*/
|
||||
private String receiver;
|
||||
|
||||
/**
|
||||
* 消息模板码
|
||||
*/
|
||||
private String templateCode;
|
||||
|
||||
/**
|
||||
* 测试数据
|
||||
*/
|
||||
private String testData;
|
||||
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package org.jeecg.modules.message.entity;
|
||||
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecg.common.system.base.entity.JeecgEntity;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 消息
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_sms")
|
||||
public class SysMessage extends JeecgEntity {
|
||||
/**推送内容*/
|
||||
@Excel(name = "推送内容", width = 15)
|
||||
private java.lang.String esContent;
|
||||
/**推送所需参数Json格式*/
|
||||
@Excel(name = "推送所需参数Json格式", width = 15)
|
||||
private java.lang.String esParam;
|
||||
/**接收人*/
|
||||
@Excel(name = "接收人", width = 15)
|
||||
private java.lang.String esReceiver;
|
||||
/**推送失败原因*/
|
||||
@Excel(name = "推送失败原因", width = 15)
|
||||
private java.lang.String esResult;
|
||||
/**发送次数*/
|
||||
@Excel(name = "发送次数", width = 15)
|
||||
private java.lang.Integer esSendNum;
|
||||
/**推送状态 0未推送 1推送成功 2推送失败*/
|
||||
@Excel(name = "推送状态 0未推送 1推送成功 2推送失败", width = 15)
|
||||
@Dict(dicCode = "msgSendStatus")
|
||||
private java.lang.String esSendStatus;
|
||||
/**推送时间*/
|
||||
@Excel(name = "推送时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
private java.util.Date esSendTime;
|
||||
/**消息标题*/
|
||||
@Excel(name = "消息标题", width = 15)
|
||||
private java.lang.String esTitle;
|
||||
/**
|
||||
* 推送方式:参考枚举类MessageTypeEnum
|
||||
*/
|
||||
@Excel(name = "推送方式", width = 15)
|
||||
@Dict(dicCode = "messageType")
|
||||
private java.lang.String esType;
|
||||
/**备注*/
|
||||
@Excel(name = "备注", width = 15)
|
||||
private java.lang.String remark;
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package org.jeecg.modules.message.entity;
|
||||
|
||||
import org.jeecg.common.system.base.entity.JeecgEntity;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 消息模板
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_sms_template")
|
||||
public class SysMessageTemplate extends JeecgEntity{
|
||||
/**模板CODE*/
|
||||
@Excel(name = "模板CODE", width = 15)
|
||||
private java.lang.String templateCode;
|
||||
/**模板标题*/
|
||||
@Excel(name = "模板标题", width = 30)
|
||||
private java.lang.String templateName;
|
||||
/**模板内容*/
|
||||
@Excel(name = "模板内容", width = 50)
|
||||
private java.lang.String templateContent;
|
||||
/**模板测试json*/
|
||||
@Excel(name = "模板测试json", width = 15)
|
||||
private java.lang.String templateTestJson;
|
||||
/**模板类型*/
|
||||
@Excel(name = "模板类型", width = 15)
|
||||
private java.lang.String templateType;
|
||||
|
||||
/**已经应用/未应用 1是0否*/
|
||||
@Excel(name = "应用状态", width = 15)
|
||||
private String useStatus;
|
||||
|
||||
}
|
||||
@ -0,0 +1,135 @@
|
||||
package org.jeecg.modules.message.enums;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
||||
import org.jeecg.common.system.annotation.EnumDict;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用于消息数据查询【vue3】
|
||||
* 新版系统通知查询条件
|
||||
* @Author taoYan
|
||||
* @Date 2022/8/19 20:41
|
||||
**/
|
||||
@Slf4j
|
||||
@EnumDict("rangeDate")
|
||||
public enum RangeDateEnum {
|
||||
|
||||
JT("jt", "今天"),
|
||||
ZT("zt", "昨天"),
|
||||
QT("qt", "前天"),
|
||||
BZ("bz","本周"),
|
||||
SZ("sz", "上周"),
|
||||
BY("by", "本月"),
|
||||
SY("sy", "上月"),
|
||||
SEVENDAYS("7day", "7日"),
|
||||
ZDY("zdy", "自定义日期");
|
||||
|
||||
String key;
|
||||
|
||||
String title;
|
||||
|
||||
RangeDateEnum(String key, String title){
|
||||
this.key = key;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典数据
|
||||
* @return
|
||||
*/
|
||||
public static List<DictModel> getDictList(){
|
||||
List<DictModel> list = new ArrayList<>();
|
||||
DictModel dictModel = null;
|
||||
for(RangeDateEnum e: RangeDateEnum.values()){
|
||||
dictModel = new DictModel();
|
||||
dictModel.setValue(e.key);
|
||||
dictModel.setText(e.title);
|
||||
list.add(dictModel);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据key 获取范围时间值
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static Date[] getRangeArray(String key){
|
||||
Calendar calendar1 = Calendar.getInstance();
|
||||
Calendar calendar2 = Calendar.getInstance();
|
||||
Date[] array = new Date[2];
|
||||
boolean flag = false;
|
||||
if(JT.key.equals(key)){
|
||||
//今天
|
||||
} else if(ZT.key.equals(key)){
|
||||
//昨天
|
||||
calendar1.add(Calendar.DAY_OF_YEAR, -1);
|
||||
calendar2.add(Calendar.DAY_OF_YEAR, -1);
|
||||
} else if(QT.key.equals(key)){
|
||||
//前天
|
||||
calendar1.add(Calendar.DAY_OF_YEAR, -2);
|
||||
calendar2.add(Calendar.DAY_OF_YEAR, -2);
|
||||
} else if(BZ.key.equals(key)){
|
||||
//本周
|
||||
calendar1.set(Calendar.DAY_OF_WEEK, 2);
|
||||
|
||||
calendar2.add(Calendar.WEEK_OF_MONTH,1);
|
||||
calendar2.add(Calendar.DAY_OF_WEEK,-1);
|
||||
} else if(SZ.key.equals(key)){
|
||||
//本周一减一周
|
||||
calendar1.set(Calendar.DAY_OF_WEEK, 2);
|
||||
calendar1.add(Calendar.WEEK_OF_MONTH, -1);
|
||||
|
||||
// 本周一减一天
|
||||
calendar2.set(Calendar.DAY_OF_WEEK, 2);
|
||||
calendar2.add(Calendar.DAY_OF_WEEK,-1);
|
||||
} else if(BY.key.equals(key)){
|
||||
//本月
|
||||
calendar1.set(Calendar.DAY_OF_MONTH, 1);
|
||||
|
||||
calendar2.set(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar2.add(Calendar.MONTH, 1);
|
||||
calendar2.add(Calendar.DAY_OF_MONTH, -1);
|
||||
} else if(SY.key.equals(key)){
|
||||
//本月第一天减一月
|
||||
calendar1.set(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar1.add(Calendar.MONTH, -1);
|
||||
|
||||
//本月第一天减一天
|
||||
calendar2.set(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar2.add(Calendar.DAY_OF_MONTH, -1);
|
||||
} else if (SEVENDAYS.key.equals(key)){
|
||||
//七日第一天
|
||||
calendar1.setTime(new Date());
|
||||
calendar1.add(Calendar.DATE, -7);
|
||||
}else{
|
||||
flag = true;
|
||||
}
|
||||
if(flag){
|
||||
return null;
|
||||
}
|
||||
// 开始时间00:00:00 结束时间23:59:59
|
||||
calendar1.set(Calendar.HOUR, 0);
|
||||
calendar1.set(Calendar.MINUTE, 0);
|
||||
calendar1.set(Calendar.SECOND, 0);
|
||||
calendar1.set(Calendar.MILLISECOND, 0);
|
||||
calendar2.set(Calendar.HOUR, 23);
|
||||
calendar2.set(Calendar.MINUTE, 59);
|
||||
calendar2.set(Calendar.SECOND, 59);
|
||||
calendar2.set(Calendar.MILLISECOND, 999);
|
||||
array[0] = calendar1.getTime();
|
||||
array[1] = calendar2.getTime();
|
||||
return array;
|
||||
}
|
||||
|
||||
public String getKey(){
|
||||
return this.key;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package org.jeecg.modules.message.handle;
|
||||
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
|
||||
/**
|
||||
* @Description: 发送信息接口
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public interface ISendMsgHandle {
|
||||
|
||||
/**
|
||||
* 发送信息
|
||||
* @param esReceiver 接受人
|
||||
* @param esTitle 标题
|
||||
* @param esContent 内容
|
||||
*/
|
||||
void sendMsg(String esReceiver, String esTitle, String esContent);
|
||||
|
||||
/**
|
||||
* 发送信息
|
||||
* @param messageDTO
|
||||
*/
|
||||
default void sendMessage(MessageDTO messageDTO){
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package org.jeecg.modules.message.handle.enums;
|
||||
|
||||
/**
|
||||
* 推送状态枚举
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public enum SendMsgStatusEnum {
|
||||
|
||||
//推送状态 0未推送 1推送成功 2推送失败
|
||||
WAIT("0"), SUCCESS("1"), FAIL("2");
|
||||
|
||||
private String code;
|
||||
|
||||
private SendMsgStatusEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setStatusCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package org.jeecg.modules.message.handle.enums;
|
||||
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
|
||||
/**
|
||||
* 发送消息类型枚举
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public enum SendMsgTypeEnum {
|
||||
|
||||
/**
|
||||
* 短信
|
||||
*/
|
||||
SMS("1", "org.jeecg.modules.message.handle.impl.SmsSendMsgHandle"),
|
||||
/**
|
||||
* 邮件
|
||||
*/
|
||||
EMAIL("2", "org.jeecg.modules.message.handle.impl.EmailSendMsgHandle"),
|
||||
/**
|
||||
* 微信
|
||||
*/
|
||||
WX("3","org.jeecg.modules.message.handle.impl.WxSendMsgHandle"),
|
||||
/**
|
||||
* 系统消息
|
||||
*/
|
||||
SYSTEM_MESSAGE("4","org.jeecg.modules.message.handle.impl.SystemSendMsgHandle");
|
||||
|
||||
private String type;
|
||||
|
||||
private String implClass;
|
||||
|
||||
private SendMsgTypeEnum(String type, String implClass) {
|
||||
this.type = type;
|
||||
this.implClass = implClass;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getImplClass() {
|
||||
return implClass;
|
||||
}
|
||||
|
||||
public void setImplClass(String implClass) {
|
||||
this.implClass = implClass;
|
||||
}
|
||||
|
||||
public static SendMsgTypeEnum getByType(String type) {
|
||||
if (oConvertUtils.isEmpty(type)) {
|
||||
return null;
|
||||
}
|
||||
for (SendMsgTypeEnum val : values()) {
|
||||
if (val.getType().equals(type)) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Description: 发钉钉消息模板
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("ddSendMsgHandle")
|
||||
public class DdSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Autowired
|
||||
private ThirdAppDingtalkServiceImpl dingtalkService;
|
||||
|
||||
@Override
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
log.info("发微信消息模板");
|
||||
MessageDTO messageDTO = new MessageDTO();
|
||||
messageDTO.setToUser(esReceiver);
|
||||
messageDTO.setTitle(esTitle);
|
||||
messageDTO.setContent(esContent);
|
||||
messageDTO.setToAll(false);
|
||||
sendMessage(messageDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
dingtalkService.sendMessage(messageDTO, true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,216 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.StaticConfig;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.mail.MessagingException;
|
||||
import jakarta.mail.internet.MimeMessage;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Description: 邮箱发送信息
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("emailSendMsgHandle")
|
||||
public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
static String emailFrom;
|
||||
|
||||
public static void setEmailFrom(String emailFrom) {
|
||||
EmailSendMsgHandle.emailFrom = emailFrom;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
SysUserMapper sysUserMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
/**
|
||||
* 真实姓名变量
|
||||
*/
|
||||
private static final String realNameExp = "{REALNAME}";
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender");
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = null;
|
||||
//update-begin-author:taoyan date:20200811 for:配置类数据获取
|
||||
if(oConvertUtils.isEmpty(emailFrom)){
|
||||
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
|
||||
setEmailFrom(staticConfig.getEmailFrom());
|
||||
}
|
||||
//update-end-author:taoyan date:20200811 for:配置类数据获取
|
||||
try {
|
||||
helper = new MimeMessageHelper(message, true);
|
||||
// 设置发送方邮箱地址
|
||||
helper.setFrom(emailFrom);
|
||||
helper.setTo(esReceiver);
|
||||
helper.setSubject(esTitle);
|
||||
helper.setText(esContent, true);
|
||||
mailSender.send(message);
|
||||
} catch (MessagingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
String[] arr = messageDTO.getToUser().split(",");
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<SysUser>().in(SysUser::getUsername, arr);
|
||||
List<SysUser> list = sysUserMapper.selectList(query);
|
||||
String content = messageDTO.getContent();
|
||||
String title = messageDTO.getTitle();
|
||||
for(SysUser user: list){
|
||||
String email = user.getEmail();
|
||||
if (ObjectUtils.isEmpty(email)) {
|
||||
continue;
|
||||
}
|
||||
content=replaceContent(user,content);
|
||||
log.info("邮件内容:"+ content);
|
||||
sendMsg(email, title, content);
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
Set<String> toEmailList = messageDTO.getToEmailList();
|
||||
if(toEmailList!=null && toEmailList.size()>0){
|
||||
for(String email: toEmailList){
|
||||
if (ObjectUtils.isEmpty(email)) {
|
||||
continue;
|
||||
}
|
||||
log.info("邮件内容:"+ content);
|
||||
sendMsg(email, title, content);
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
|
||||
//发送给抄送人
|
||||
sendMessageToCopyUser(messageDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件给抄送人
|
||||
* @param messageDTO
|
||||
*/
|
||||
public void sendMessageToCopyUser(MessageDTO messageDTO) {
|
||||
String copyToUser = messageDTO.getCopyToUser();
|
||||
if(ObjectUtils.isNotEmpty(copyToUser)) {
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<SysUser>().in(SysUser::getUsername, copyToUser.split(","));
|
||||
List<SysUser> list = sysUserMapper.selectList(query);
|
||||
String content = messageDTO.getContent();
|
||||
String title = messageDTO.getTitle();
|
||||
|
||||
for (SysUser user : list) {
|
||||
String email = user.getEmail();
|
||||
if (ObjectUtils.isEmpty(email)) {
|
||||
continue;
|
||||
}
|
||||
content=replaceContent(user,content);
|
||||
log.info("邮件内容:" + content);
|
||||
|
||||
//update-begin-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
sendEmail(email, content, title);
|
||||
}
|
||||
|
||||
Set<String> ccEmailList = messageDTO.getCcEmailList();
|
||||
if(ccEmailList!=null && ccEmailList.size()>0){
|
||||
for(String email: ccEmailList){
|
||||
if (ObjectUtils.isEmpty(email)) {
|
||||
continue;
|
||||
}
|
||||
log.info("邮件内容:"+ content);
|
||||
sendEmail(email, content, title);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件给抄送人调用
|
||||
* @param email
|
||||
* @param content
|
||||
* @param title
|
||||
*/
|
||||
private void sendEmail(String email, String content, String title){
|
||||
JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender");
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = null;
|
||||
if (oConvertUtils.isEmpty(emailFrom)) {
|
||||
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
|
||||
setEmailFrom(staticConfig.getEmailFrom());
|
||||
}
|
||||
try {
|
||||
helper = new MimeMessageHelper(message, true);
|
||||
// 设置发送方邮箱地址
|
||||
helper.setFrom(emailFrom);
|
||||
helper.setTo(email);
|
||||
//设置抄送人
|
||||
helper.setCc(email);
|
||||
helper.setSubject(title);
|
||||
helper.setText(content, true);
|
||||
mailSender.send(message);
|
||||
} catch (MessagingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
|
||||
|
||||
/**
|
||||
* 替换邮件内容变量
|
||||
* @param user
|
||||
* @param content
|
||||
* @return
|
||||
*/
|
||||
private String replaceContent(SysUser user,String content){
|
||||
if (content.indexOf(realNameExp) > 0) {
|
||||
content = content.replace("$"+realNameExp,user.getRealname()).replace(realNameExp, user.getRealname());
|
||||
}
|
||||
if (content.indexOf(CommonConstant.LOGIN_TOKEN) > 0) {
|
||||
String token = getToken(user);
|
||||
try {
|
||||
content = content.replace(CommonConstant.LOGIN_TOKEN, URLEncoder.encode(token, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error("邮件消息token编码失败", e.getMessage());
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
private String getToken(SysUser user) {
|
||||
// 生成token
|
||||
String token = JwtUtil.sign(user.getUsername(), user.getPassword());
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
// 设置超时时间 1个小时
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 1 / 1000);
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Description: 发企业微信消息模板
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("qywxSendMsgHandle")
|
||||
public class QywxSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Autowired
|
||||
private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||
|
||||
@Override
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
log.info("发微信消息模板");
|
||||
MessageDTO messageDTO = new MessageDTO();
|
||||
messageDTO.setToUser(esReceiver);
|
||||
messageDTO.setTitle(esTitle);
|
||||
messageDTO.setContent(esContent);
|
||||
messageDTO.setToAll(false);
|
||||
sendMessage(messageDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
wechatEnterpriseService.sendMessage(messageDTO, true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
|
||||
/**
|
||||
* @Description: 短信发送
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
public class SmsSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Override
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
// TODO Auto-generated method stub
|
||||
log.info("发短信");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.common.constant.enums.Vue3MessageHrefEnum;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.jeecg.modules.message.websocket.WebSocket;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncement;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.mapper.SysAnnouncementMapper;
|
||||
import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 发送系统消息
|
||||
* @Author: wangshuai
|
||||
* @Date: 2022年3月22日 18:48:20
|
||||
*/
|
||||
@Component("systemSendMsgHandle")
|
||||
public class SystemSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
public static final String FROM_USER="system";
|
||||
|
||||
@Resource
|
||||
private SysAnnouncementMapper sysAnnouncementMapper;
|
||||
|
||||
@Resource
|
||||
private SysUserMapper userMapper;
|
||||
|
||||
@Resource
|
||||
private SysAnnouncementSendMapper sysAnnouncementSendMapper;
|
||||
|
||||
@Resource
|
||||
private WebSocket webSocket;
|
||||
|
||||
/**
|
||||
* 该方法会发送3种消息:系统消息、企业微信 钉钉
|
||||
* @param esReceiver 发送人
|
||||
* @param esTitle 标题
|
||||
* @param esContent 内容
|
||||
*/
|
||||
@Override
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
if(oConvertUtils.isEmpty(esReceiver)){
|
||||
throw new JeecgBootException("被发送人不能为空");
|
||||
}
|
||||
ISysBaseAPI sysBaseApi = SpringContextUtils.getBean(ISysBaseAPI.class);
|
||||
MessageDTO messageDTO = new MessageDTO(FROM_USER,esReceiver,esTitle,esContent);
|
||||
sysBaseApi.sendSysAnnouncement(messageDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅发送系统消息
|
||||
* @param messageDTO
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
//原方法不支持 sysBaseApi.sendSysAnnouncement(messageDTO); 有企业微信消息逻辑,
|
||||
String title = messageDTO.getTitle();
|
||||
String content = messageDTO.getContent();
|
||||
String fromUser = messageDTO.getFromUser();
|
||||
Map<String,Object> data = messageDTO.getData();
|
||||
String[] arr = messageDTO.getToUser().split(",");
|
||||
for(String username: arr){
|
||||
doSend(title, content, fromUser, username, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void doSend(String title, String msgContent, String fromUser, String toUser, Map<String, Object> data){
|
||||
SysAnnouncement announcement = new SysAnnouncement();
|
||||
if(data!=null){
|
||||
//摘要信息
|
||||
Object msgAbstract = data.get(CommonConstant.NOTICE_MSG_SUMMARY);
|
||||
if(msgAbstract!=null){
|
||||
announcement.setMsgAbstract(msgAbstract.toString());
|
||||
}
|
||||
// 任务节点ID
|
||||
Object taskId = data.get(CommonConstant.NOTICE_MSG_BUS_ID);
|
||||
if(taskId!=null){
|
||||
announcement.setBusId(taskId.toString());
|
||||
announcement.setBusType(Vue3MessageHrefEnum.BPM_TASK.getBusType());
|
||||
}
|
||||
|
||||
// 流程内消息节点 发消息会传一个busType
|
||||
Object busType = data.get(CommonConstant.NOTICE_MSG_BUS_TYPE);
|
||||
if(busType!=null){
|
||||
announcement.setBusType(busType.toString());
|
||||
}
|
||||
}
|
||||
announcement.setTitile(title);
|
||||
announcement.setMsgContent(msgContent);
|
||||
announcement.setSender(fromUser);
|
||||
announcement.setPriority(CommonConstant.PRIORITY_M);
|
||||
announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
|
||||
announcement.setSendStatus(CommonConstant.HAS_SEND);
|
||||
announcement.setSendTime(new Date());
|
||||
//系统消息
|
||||
announcement.setMsgCategory("2");
|
||||
announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
|
||||
sysAnnouncementMapper.insert(announcement);
|
||||
// 2.插入用户通告阅读标记表记录
|
||||
String userId = toUser;
|
||||
String[] userIds = userId.split(",");
|
||||
String anntId = announcement.getId();
|
||||
for(int i=0;i<userIds.length;i++) {
|
||||
if(oConvertUtils.isNotEmpty(userIds[i])) {
|
||||
SysUser sysUser = userMapper.getUserByName(userIds[i]);
|
||||
if(sysUser==null) {
|
||||
continue;
|
||||
}
|
||||
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
||||
announcementSend.setAnntId(anntId);
|
||||
announcementSend.setUserId(sysUser.getId());
|
||||
announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
|
||||
sysAnnouncementSendMapper.insert(announcementSend);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
|
||||
obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
|
||||
obj.put(WebsocketConst.MSG_ID, announcement.getId());
|
||||
obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
|
||||
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
|
||||
/**
|
||||
* @Description: 发微信消息模板
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
public class WxSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Override
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
// TODO Auto-generated method stub
|
||||
log.info("发微信消息模板");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package org.jeecg.modules.message.job;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.jeecg.modules.message.entity.SysMessage;
|
||||
import org.jeecg.modules.message.handle.enums.SendMsgStatusEnum;
|
||||
import org.jeecg.modules.message.service.ISysMessageService;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 发送消息任务
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class SendMsgJob implements Job {
|
||||
|
||||
@Autowired
|
||||
private ISysMessageService sysMessageService;
|
||||
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseAPI;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
|
||||
log.info(String.format(" Jeecg-Boot 发送消息任务 SendMsgJob ! 时间:" + DateUtils.getTimestamp()));
|
||||
|
||||
// 1.读取消息中心数据,只查询未发送的和发送失败不超过次数的
|
||||
QueryWrapper<SysMessage> queryWrapper = new QueryWrapper<SysMessage>();
|
||||
queryWrapper.eq("es_send_status", SendMsgStatusEnum.WAIT.getCode())
|
||||
.or(i -> i.eq("es_send_status", SendMsgStatusEnum.FAIL.getCode()).lt("es_send_num", 6));
|
||||
List<SysMessage> sysMessages = sysMessageService.list(queryWrapper);
|
||||
System.out.println(sysMessages);
|
||||
// 2.根据不同的类型走不通的发送实现类
|
||||
for (SysMessage sysMessage : sysMessages) {
|
||||
//update-begin-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改
|
||||
Integer sendNum = sysMessage.getEsSendNum();
|
||||
try {
|
||||
MessageDTO md = new MessageDTO();
|
||||
md.setTitle(sysMessage.getEsTitle());
|
||||
md.setContent(sysMessage.getEsContent());
|
||||
md.setToUser(sysMessage.getEsReceiver());
|
||||
md.setType(sysMessage.getEsType());
|
||||
md.setToAll(false);
|
||||
sysBaseAPI.sendTemplateMessage(md);
|
||||
//发送消息成功
|
||||
sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
|
||||
//update-end-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// 发送消息出现异常
|
||||
sysMessage.setEsSendStatus(SendMsgStatusEnum.FAIL.getCode());
|
||||
}
|
||||
sysMessage.setEsSendNum(++sendNum);
|
||||
// 发送结果回写到数据库
|
||||
sysMessageService.updateById(sysMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.message.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.message.entity.SysMessage;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 消息
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface SysMessageMapper extends BaseMapper<SysMessage> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package org.jeecg.modules.message.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.jeecg.modules.message.entity.SysMessageTemplate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 消息模板
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface SysMessageTemplateMapper extends BaseMapper<SysMessageTemplate> {
|
||||
|
||||
/**
|
||||
* 通过模板CODE查询消息模板
|
||||
* @param code 模板CODE
|
||||
* @return List<SysMessageTemplate>
|
||||
*/
|
||||
@Select("SELECT * FROM SYS_SMS_TEMPLATE WHERE TEMPLATE_CODE = #{code}")
|
||||
List<SysMessageTemplate> selectByCode(String code);
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.jeecg.modules.message.mapper.SysMessageMapper">
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.jeecg.modules.message.mapper.SysMessageTemplateMapper">
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.message.service;
|
||||
|
||||
import org.jeecg.common.system.base.service.JeecgService;
|
||||
import org.jeecg.modules.message.entity.SysMessage;
|
||||
|
||||
/**
|
||||
* @Description: 消息
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ISysMessageService extends JeecgService<SysMessage> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package org.jeecg.modules.message.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.common.system.base.service.JeecgService;
|
||||
import org.jeecg.modules.message.entity.SysMessageTemplate;
|
||||
|
||||
/**
|
||||
* @Description: 消息模板
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ISysMessageTemplateService extends JeecgService<SysMessageTemplate> {
|
||||
|
||||
/**
|
||||
* 通过模板CODE查询消息模板
|
||||
* @param code 模板CODE
|
||||
* @return
|
||||
*/
|
||||
List<SysMessageTemplate> selectByCode(String code);
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package org.jeecg.modules.message.service.impl;
|
||||
|
||||
import org.jeecg.common.system.base.service.impl.JeecgServiceImpl;
|
||||
import org.jeecg.modules.message.entity.SysMessage;
|
||||
import org.jeecg.modules.message.mapper.SysMessageMapper;
|
||||
import org.jeecg.modules.message.service.ISysMessageService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Description: 消息
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class SysMessageServiceImpl extends JeecgServiceImpl<SysMessageMapper, SysMessage> implements ISysMessageService {
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package org.jeecg.modules.message.service.impl;
|
||||
|
||||
import org.jeecg.common.system.base.service.impl.JeecgServiceImpl;
|
||||
import org.jeecg.modules.message.entity.SysMessageTemplate;
|
||||
import org.jeecg.modules.message.mapper.SysMessageTemplateMapper;
|
||||
import org.jeecg.modules.message.service.ISysMessageTemplateService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 消息模板
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class SysMessageTemplateServiceImpl extends JeecgServiceImpl<SysMessageTemplateMapper, SysMessageTemplate> implements ISysMessageTemplateService {
|
||||
|
||||
@Autowired
|
||||
private SysMessageTemplateMapper sysMessageTemplateMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public List<SysMessageTemplate> selectByCode(String code) {
|
||||
return sysMessageTemplateMapper.selectByCode(code);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package org.jeecg.modules.message.util;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
import org.jeecg.modules.message.entity.SysMessage;
|
||||
import org.jeecg.modules.message.entity.SysMessageTemplate;
|
||||
import org.jeecg.modules.message.handle.enums.SendMsgStatusEnum;
|
||||
import org.jeecg.modules.message.service.ISysMessageService;
|
||||
import org.jeecg.modules.message.service.ISysMessageTemplateService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 消息生成工具
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
|
||||
@Component
|
||||
public class PushMsgUtil {
|
||||
|
||||
@Autowired
|
||||
private ISysMessageService sysMessageService;
|
||||
|
||||
@Autowired
|
||||
private ISysMessageTemplateService sysMessageTemplateService;
|
||||
|
||||
@Autowired
|
||||
private Configuration freemarkerConfig;
|
||||
/**
|
||||
* @param msgType 消息类型 1短信 2邮件 3微信
|
||||
* @param templateCode 消息模板码
|
||||
* @param map 消息参数
|
||||
* @param sentTo 接收消息方
|
||||
*/
|
||||
public boolean sendMessage(String msgType, String templateCode, Map<String, String> map, String sentTo) {
|
||||
List<SysMessageTemplate> sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode);
|
||||
SysMessage sysMessage = new SysMessage();
|
||||
if (sysSmsTemplates.size() > 0) {
|
||||
SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0);
|
||||
sysMessage.setEsType(msgType);
|
||||
sysMessage.setEsReceiver(sentTo);
|
||||
//模板标题
|
||||
String title = sysSmsTemplate.getTemplateName();
|
||||
//模板内容
|
||||
String content = sysSmsTemplate.getTemplateContent();
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
Template template = null;
|
||||
try {
|
||||
template = new Template("SysMessageTemplate", content, freemarkerConfig);
|
||||
template.process(map, stringWriter);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (TemplateException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
content = stringWriter.toString();
|
||||
sysMessage.setEsTitle(title);
|
||||
sysMessage.setEsContent(content);
|
||||
sysMessage.setEsParam(JSONObject.toJSONString(map));
|
||||
sysMessage.setEsSendTime(new Date());
|
||||
sysMessage.setEsSendStatus(SendMsgStatusEnum.WAIT.getCode());
|
||||
sysMessage.setEsSendNum(0);
|
||||
if(sysMessageService.save(sysMessage)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package org.jeecg.modules.message.websocket;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.base.BaseMap;
|
||||
import org.jeecg.common.constant.CommonSendStatus;
|
||||
import org.jeecg.common.modules.redis.listener.JeecgRedisListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 监听消息(通过redis发布订阅,推送消息)
|
||||
* 此方案:解决集群部署的问题,多实例节点(也就是发送消息端先发送消息到redis中,每个服务节点收到redis消息,再触发具体的ws推送)
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@Component(WebSocket.REDIS_TOPIC_NAME)
|
||||
public class SocketHandler implements JeecgRedisListener {
|
||||
|
||||
@Autowired
|
||||
private WebSocket webSocket;
|
||||
|
||||
@Override
|
||||
public void onMessage(BaseMap map) {
|
||||
log.debug("【Redis发布订阅模式】redis Listener: {},参数:{}",WebSocket.REDIS_TOPIC_NAME, map.toString());
|
||||
|
||||
String userId = map.get("userId");
|
||||
String message = map.get("message");
|
||||
if (ObjectUtil.isNotEmpty(userId)) {
|
||||
//pc端消息推送具体人
|
||||
webSocket.pushMessage(userId, message);
|
||||
//app端消息推送具体人
|
||||
webSocket.pushMessage(userId+CommonSendStatus.APP_SESSION_SUFFIX, message);
|
||||
} else {
|
||||
//推送全部
|
||||
webSocket.pushMessage(message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,186 @@
|
||||
package org.jeecg.modules.message.websocket;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import jakarta.websocket.*;
|
||||
import jakarta.websocket.server.PathParam;
|
||||
import jakarta.websocket.server.ServerEndpoint;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.base.BaseMap;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.common.modules.redis.client.JeecgRedisClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @Author scott
|
||||
* @Date 2019/11/29 9:41
|
||||
* @Description: 此注解相当于设置访问URL
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
@ServerEndpoint("/websocket/{userId}")
|
||||
public class WebSocket {
|
||||
|
||||
/**线程安全Map*/
|
||||
private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Redis触发监听名字
|
||||
*/
|
||||
public static final String REDIS_TOPIC_NAME = "socketHandler";
|
||||
|
||||
//避免初次调用出现空指针的情况
|
||||
private static JeecgRedisClient jeecgRedisClient;
|
||||
@Autowired
|
||||
private void setJeecgRedisClient(JeecgRedisClient jeecgRedisClient){
|
||||
WebSocket.jeecgRedisClient = jeecgRedisClient;
|
||||
}
|
||||
|
||||
|
||||
//==========【websocket接受、推送消息等方法 —— 具体服务节点推送ws消息】========================================================================================
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam(value = "userId") String userId) {
|
||||
try {
|
||||
sessionPool.put(userId, session);
|
||||
log.debug("【系统 WebSocket】有新的连接,总数为:" + sessionPool.size());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(@PathParam("userId") String userId) {
|
||||
try {
|
||||
sessionPool.remove(userId);
|
||||
log.debug("【系统 WebSocket】连接断开,总数为:" + sessionPool.size());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ws推送消息
|
||||
*
|
||||
* @param userId
|
||||
* @param message
|
||||
*/
|
||||
public void pushMessage(String userId, String message) {
|
||||
for (Map.Entry<String, Session> item : sessionPool.entrySet()) {
|
||||
//userId key值= {用户id + "_"+ 登录token的md5串}
|
||||
//TODO vue2未改key新规则,暂时不影响逻辑
|
||||
if (item.getKey().contains(userId)) {
|
||||
Session session = item.getValue();
|
||||
try {
|
||||
//update-begin-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
|
||||
synchronized (session){
|
||||
log.debug("【系统 WebSocket】推送单人消息:" + message);
|
||||
session.getBasicRemote().sendText(message);
|
||||
}
|
||||
//update-end-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ws遍历群发消息
|
||||
*/
|
||||
public void pushMessage(String message) {
|
||||
try {
|
||||
for (Map.Entry<String, Session> item : sessionPool.entrySet()) {
|
||||
try {
|
||||
item.getValue().getAsyncRemote().sendText(message);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
log.debug("【系统 WebSocket】群发消息:" + message);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ws接受客户端消息
|
||||
*/
|
||||
@OnMessage
|
||||
public void onMessage(String message, @PathParam(value = "userId") String userId) {
|
||||
if(!"ping".equals(message) && !WebsocketConst.CMD_CHECK.equals(message)){
|
||||
log.debug("【系统 WebSocket】收到客户端消息:" + message);
|
||||
}else{
|
||||
log.debug("【系统 WebSocket】收到客户端消息:" + message);
|
||||
//update-begin---author:wangshuai---date:2024-05-07---for:【issues/1161】前端websocket因心跳导致监听不起作用---
|
||||
this.sendMessage(userId, "ping");
|
||||
//update-end---author:wangshuai---date:2024-05-07---for:【issues/1161】前端websocket因心跳导致监听不起作用---
|
||||
}
|
||||
|
||||
// //------------------------------------------------------------------------------
|
||||
// JSONObject obj = new JSONObject();
|
||||
// //业务类型
|
||||
// obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
|
||||
// //消息内容
|
||||
// obj.put(WebsocketConst.MSG_TXT, "心跳响应");
|
||||
// this.pushMessage(userId, obj.toJSONString());
|
||||
// //------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置错误信息处理
|
||||
*
|
||||
* @param session
|
||||
* @param t
|
||||
*/
|
||||
@OnError
|
||||
public void onError(Session session, Throwable t) {
|
||||
log.warn("【系统 WebSocket】消息出现错误");
|
||||
t.printStackTrace();
|
||||
}
|
||||
//==========【系统 WebSocket接受、推送消息等方法 —— 具体服务节点推送ws消息】========================================================================================
|
||||
|
||||
|
||||
//==========【采用redis发布订阅模式——推送消息】========================================================================================
|
||||
/**
|
||||
* 后台发送消息到redis
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
public void sendMessage(String message) {
|
||||
//log.debug("【系统 WebSocket】广播消息:" + message);
|
||||
BaseMap baseMap = new BaseMap();
|
||||
baseMap.put("userId", "");
|
||||
baseMap.put("message", message);
|
||||
jeecgRedisClient.sendMessage(WebSocket.REDIS_TOPIC_NAME, baseMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 此为单点消息 redis
|
||||
*
|
||||
* @param userId
|
||||
* @param message
|
||||
*/
|
||||
public void sendMessage(String userId, String message) {
|
||||
BaseMap baseMap = new BaseMap();
|
||||
baseMap.put("userId", userId);
|
||||
baseMap.put("message", message);
|
||||
jeecgRedisClient.sendMessage(WebSocket.REDIS_TOPIC_NAME, baseMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 此为单点消息(多人) redis
|
||||
*
|
||||
* @param userIds
|
||||
* @param message
|
||||
*/
|
||||
public void sendMessage(String[] userIds, String message) {
|
||||
for (String userId : userIds) {
|
||||
sendMessage(userId, message);
|
||||
}
|
||||
}
|
||||
//=======【采用redis发布订阅模式——推送消息】==========================================================================================
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package org.jeecg.modules.monitor.actuator;
|
||||
|
||||
import org.jeecg.modules.monitor.actuator.httptrace.CustomInMemoryHttpTraceRepository;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesProperties;
|
||||
import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 自定义健康监控配置类
|
||||
*
|
||||
* @Author: chenrui
|
||||
* @Date: 2024/5/13 17:20
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(HttpExchangesProperties.class)
|
||||
@AutoConfigureBefore(HttpExchangesAutoConfiguration.class)
|
||||
public class CustomActuatorConfig {
|
||||
|
||||
/**
|
||||
* 请求追踪
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:52
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "management.trace.http", name = "enabled", matchIfMissing = true)
|
||||
@ConditionalOnMissingBean(HttpExchangeRepository.class)
|
||||
public CustomInMemoryHttpTraceRepository traceRepository() {
|
||||
return new CustomInMemoryHttpTraceRepository();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package org.jeecg.modules.monitor.actuator.httptrace;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Selector;
|
||||
import org.springframework.boot.actuate.web.exchanges.HttpExchange;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.boot.actuate.endpoint.annotation.Selector.Match.ALL_REMAINING;
|
||||
|
||||
/**
|
||||
* @Description: ENDPOINT: 请求追踪(新),支持通过responseCode筛选
|
||||
* @Author: chenrui
|
||||
* @Date: 2024/5/13 17:02
|
||||
*/
|
||||
@Component
|
||||
@Endpoint(id = "httptrace-new")
|
||||
public class CustomHttpTraceEndpoint{
|
||||
private final CustomInMemoryHttpTraceRepository repository;
|
||||
|
||||
public CustomHttpTraceEndpoint(CustomInMemoryHttpTraceRepository repository) {
|
||||
Assert.notNull(repository, "Repository must not be null");
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public HttpTraceDescriptor traces(@Selector(match = ALL_REMAINING) String query) {
|
||||
return new HttpTraceDescriptor(this.repository.findAll(query));
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static final class HttpTraceDescriptor {
|
||||
private final List<HttpExchange> traces;
|
||||
|
||||
private HttpTraceDescriptor(List<HttpExchange> traces) {
|
||||
this.traces = traces;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
package org.jeecg.modules.monitor.actuator.httptrace;
|
||||
|
||||
import org.springframework.boot.actuate.web.exchanges.HttpExchange;
|
||||
import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @Description: 自定义内存请求追踪存储
|
||||
* @Author: chenrui
|
||||
* @Date: 2024/5/13 17:02
|
||||
*/
|
||||
public class CustomInMemoryHttpTraceRepository extends InMemoryHttpExchangeRepository {
|
||||
|
||||
@Override
|
||||
public List<HttpExchange> findAll() {
|
||||
return super.findAll();
|
||||
}
|
||||
|
||||
public List<HttpExchange> findAll(String query) {
|
||||
List<HttpExchange> allTrace = super.findAll();
|
||||
if (null != allTrace && !allTrace.isEmpty()) {
|
||||
Stream<HttpExchange> stream = allTrace.stream();
|
||||
String[] params = query.split(",");
|
||||
stream = filter(params, stream);
|
||||
stream = sort(params, stream);
|
||||
allTrace = stream.collect(Collectors.toList());
|
||||
}
|
||||
return allTrace;
|
||||
}
|
||||
|
||||
private Stream<HttpExchange> sort(String[] params, Stream<HttpExchange> stream) {
|
||||
if (params.length < 2) {
|
||||
return stream;
|
||||
}
|
||||
String sortBy = params[1];
|
||||
String order;
|
||||
if (params.length > 2) {
|
||||
order = params[2];
|
||||
} else {
|
||||
order = "desc";
|
||||
}
|
||||
return stream.sorted((o1, o2) -> {
|
||||
int i = 0;
|
||||
if("timeTaken".equalsIgnoreCase(sortBy)) {
|
||||
i = o1.getTimeTaken().compareTo(o2.getTimeTaken());
|
||||
}else if("timestamp".equalsIgnoreCase(sortBy)){
|
||||
i = o1.getTimestamp().compareTo(o2.getTimestamp());
|
||||
}
|
||||
if("desc".equalsIgnoreCase(order)){
|
||||
i *=-1;
|
||||
}
|
||||
return i;
|
||||
});
|
||||
}
|
||||
|
||||
private static Stream<HttpExchange> filter(String[] params, Stream<HttpExchange> stream) {
|
||||
if (params.length == 0) {
|
||||
return stream;
|
||||
}
|
||||
String statusQuery = params[0];
|
||||
if (null != statusQuery && !statusQuery.isEmpty()) {
|
||||
statusQuery = statusQuery.toLowerCase().trim();
|
||||
switch (statusQuery) {
|
||||
case "error":
|
||||
stream = stream.filter(httpTrace -> {
|
||||
int status = httpTrace.getResponse().getStatus();
|
||||
return status >= 404 && status < 501;
|
||||
});
|
||||
break;
|
||||
case "warn":
|
||||
stream = stream.filter(httpTrace -> {
|
||||
int status = httpTrace.getResponse().getStatus();
|
||||
return status >= 201 && status < 404;
|
||||
});
|
||||
break;
|
||||
case "success":
|
||||
stream = stream.filter(httpTrace -> {
|
||||
int status = httpTrace.getResponse().getStatus();
|
||||
return status == 200;
|
||||
});
|
||||
break;
|
||||
case "all":
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package org.jeecg.modules.monitor.controller;
|
||||
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 内存健康检查
|
||||
* @author: chenrui
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/actuator/memory")
|
||||
public class ActuatorMemoryController {
|
||||
|
||||
|
||||
/**
|
||||
* 内存详情
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/info")
|
||||
public Result<?> getRedisInfo() throws Exception {
|
||||
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
JSONObject operatingSystemJson = JSONObject.parseObject(JSONObject.toJSONString(operatingSystemMXBean));
|
||||
long totalPhysicalMemory = operatingSystemJson.getLongValue("totalPhysicalMemorySize");
|
||||
long freePhysicalMemory = operatingSystemJson.getLongValue("freePhysicalMemorySize");
|
||||
long usedPhysicalMemory = totalPhysicalMemory - freePhysicalMemory;
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
Map<String,Number> result = new HashMap<>();
|
||||
result.put("memory.physical.total", totalPhysicalMemory);
|
||||
result.put("memory.physical.used", freePhysicalMemory);
|
||||
result.put("memory.physical.free", usedPhysicalMemory);
|
||||
result.put("memory.physical.usage", NumberUtil.div(usedPhysicalMemory, totalPhysicalMemory));
|
||||
result.put("memory.runtime.total", runtime.totalMemory());
|
||||
result.put("memory.runtime.used", runtime.freeMemory());
|
||||
result.put("memory.runtime.max", runtime.totalMemory() - runtime.freeMemory());
|
||||
result.put("memory.runtime.free", runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory());
|
||||
result.put("memory.runtime.usage", NumberUtil.div(runtime.totalMemory() - runtime.freeMemory(), runtime.totalMemory()));
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,138 @@
|
||||
package org.jeecg.modules.monitor.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.monitor.domain.RedisInfo;
|
||||
import org.jeecg.modules.monitor.service.RedisService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: ActuatorRedisController
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/actuator/redis")
|
||||
public class ActuatorRedisController {
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* Redis详细信息
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/info")
|
||||
public Result<?> getRedisInfo() throws Exception {
|
||||
List<RedisInfo> infoList = this.redisService.getRedisInfo();
|
||||
//log.info(infoList.toString());
|
||||
return Result.ok(infoList);
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
/**
|
||||
* Redis历史性能指标查询(过去一小时)
|
||||
* @return
|
||||
* @throws Exception
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:56
|
||||
*/
|
||||
@GetMapping(value = "/metrics/history")
|
||||
public Result<?> getMetricsHistory() throws Exception {
|
||||
Map<String,List<Map<String,Object>>> metricsHistory = this.redisService.getMetricsHistory();
|
||||
return Result.OK(metricsHistory);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
|
||||
@GetMapping("/keysSize")
|
||||
public Map<String, Object> getKeysSize() throws Exception {
|
||||
return redisService.getKeysSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取redis key数量 for 报表
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/keysSizeForReport")
|
||||
public Map<String, JSONArray> getKeysSizeReport() throws Exception {
|
||||
return redisService.getMapForReport("1");
|
||||
}
|
||||
/**
|
||||
* 获取redis 内存 for 报表
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/memoryForReport")
|
||||
public Map<String, JSONArray> memoryForReport() throws Exception {
|
||||
return redisService.getMapForReport("2");
|
||||
}
|
||||
/**
|
||||
* 获取redis 全部信息 for 报表
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/infoForReport")
|
||||
public Map<String, JSONArray> infoForReport() throws Exception {
|
||||
return redisService.getMapForReport("3");
|
||||
}
|
||||
|
||||
@GetMapping("/memoryInfo")
|
||||
public Map<String, Object> getMemoryInfo() throws Exception {
|
||||
return redisService.getMemoryInfo();
|
||||
}
|
||||
|
||||
//update-begin--Author:zhangweijian Date:20190425 for:获取磁盘信息
|
||||
/**
|
||||
* @功能:获取磁盘信息
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDiskInfo")
|
||||
public Result<List<Map<String,Object>>> queryDiskInfo(HttpServletRequest request, HttpServletResponse response){
|
||||
Result<List<Map<String,Object>>> res = new Result<>();
|
||||
try {
|
||||
// 当前文件系统类
|
||||
FileSystemView fsv = FileSystemView.getFileSystemView();
|
||||
// 列出所有windows 磁盘
|
||||
File[] fs = File.listRoots();
|
||||
log.info("查询磁盘信息:"+fs.length+"个");
|
||||
List<Map<String,Object>> list = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < fs.length; i++) {
|
||||
if(fs[i].getTotalSpace()==0) {
|
||||
continue;
|
||||
}
|
||||
Map<String,Object> map = new HashMap(5);
|
||||
map.put("name", fsv.getSystemDisplayName(fs[i]));
|
||||
map.put("max", fs[i].getTotalSpace());
|
||||
map.put("rest", fs[i].getFreeSpace());
|
||||
map.put("restPPT", (fs[i].getTotalSpace()-fs[i].getFreeSpace())*100/fs[i].getTotalSpace());
|
||||
list.add(map);
|
||||
log.info(map.toString());
|
||||
}
|
||||
res.setResult(list);
|
||||
res.success("查询成功");
|
||||
} catch (Exception e) {
|
||||
res.error500("查询失败"+e.getMessage());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//update-end--Author:zhangweijian Date:20190425 for:获取磁盘信息
|
||||
}
|
||||
@ -0,0 +1,141 @@
|
||||
package org.jeecg.modules.monitor.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: redis信息
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class RedisInfo {
|
||||
|
||||
private static Map<String, String> map = new HashMap(5);
|
||||
|
||||
static {
|
||||
map.put("redis_version", "Redis 服务器版本");
|
||||
map.put("redis_git_sha1", "Git SHA1");
|
||||
map.put("redis_git_dirty", "Git dirty flag");
|
||||
map.put("os", "Redis 服务器的宿主操作系统");
|
||||
map.put("arch_bits", " 架构(32 或 64 位)");
|
||||
map.put("multiplexing_api", "Redis 所使用的事件处理机制");
|
||||
map.put("gcc_version", "编译 Redis 时所使用的 GCC 版本");
|
||||
map.put("process_id", "服务器进程的 PID");
|
||||
map.put("run_id", "Redis 服务器的随机标识符(用于 Sentinel 和集群)");
|
||||
map.put("tcp_port", "TCP/IP 监听端口");
|
||||
map.put("uptime_in_seconds", "自 Redis 服务器启动以来,经过的秒数");
|
||||
map.put("uptime_in_days", "自 Redis 服务器启动以来,经过的天数");
|
||||
map.put("lru_clock", " 以分钟为单位进行自增的时钟,用于 LRU 管理");
|
||||
map.put("connected_clients", "已连接客户端的数量(不包括通过从属服务器连接的客户端)");
|
||||
map.put("client_longest_output_list", "当前连接的客户端当中,最长的输出列表");
|
||||
map.put("client_longest_input_buf", "当前连接的客户端当中,最大输入缓存");
|
||||
map.put("blocked_clients", "正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量");
|
||||
map.put("used_memory", "由 Redis 分配器分配的内存总量,以字节(byte)为单位");
|
||||
map.put("used_memory_human", "以人类可读的格式返回 Redis 分配的内存总量");
|
||||
map.put("used_memory_rss", "从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致");
|
||||
map.put("used_memory_peak", " Redis 的内存消耗峰值(以字节为单位)");
|
||||
map.put("used_memory_peak_human", "以人类可读的格式返回 Redis 的内存消耗峰值");
|
||||
map.put("used_memory_lua", "Lua 引擎所使用的内存大小(以字节为单位)");
|
||||
map.put("mem_fragmentation_ratio", "sed_memory_rss 和 used_memory 之间的比率");
|
||||
map.put("mem_allocator", "在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc");
|
||||
|
||||
map.put("redis_build_id", "redis_build_id");
|
||||
map.put("redis_mode", "运行模式,单机(standalone)或者集群(cluster)");
|
||||
map.put("atomicvar_api", "atomicvar_api");
|
||||
map.put("hz", "redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率,程序规定serverCron每秒运行10次。");
|
||||
map.put("executable", "server脚本目录");
|
||||
map.put("config_file", "配置文件目录");
|
||||
map.put("client_biggest_input_buf", "当前连接的客户端当中,最大输入缓存,用client list命令观察qbuf和qbuf-free两个字段最大值");
|
||||
map.put("used_memory_rss_human", "以人类可读的方式返回 Redis 已分配的内存总量");
|
||||
map.put("used_memory_peak_perc", "内存使用率峰值");
|
||||
map.put("total_system_memory", "系统总内存");
|
||||
map.put("total_system_memory_human", "以人类可读的方式返回系统总内存");
|
||||
map.put("used_memory_lua_human", "以人类可读的方式返回Lua 引擎所使用的内存大小");
|
||||
map.put("maxmemory", "最大内存限制,0表示无限制");
|
||||
map.put("maxmemory_human", "以人类可读的方式返回最大限制内存");
|
||||
map.put("maxmemory_policy", "超过内存限制后的处理策略");
|
||||
map.put("loading", "服务器是否正在载入持久化文件");
|
||||
map.put("rdb_changes_since_last_save", "离最近一次成功生成rdb文件,写入命令的个数,即有多少个写入命令没有持久化");
|
||||
map.put("rdb_bgsave_in_progress", "服务器是否正在创建rdb文件");
|
||||
map.put("rdb_last_save_time", "离最近一次成功创建rdb文件的时间戳。当前时间戳 - rdb_last_save_time=多少秒未成功生成rdb文件");
|
||||
map.put("rdb_last_bgsave_status", "最近一次rdb持久化是否成功");
|
||||
map.put("rdb_last_bgsave_time_sec", "最近一次成功生成rdb文件耗时秒数");
|
||||
map.put("rdb_current_bgsave_time_sec", "如果服务器正在创建rdb文件,那么这个域记录的就是当前的创建操作已经耗费的秒数");
|
||||
map.put("aof_enabled", "是否开启了aof");
|
||||
map.put("aof_rewrite_in_progress", "标识aof的rewrite操作是否在进行中");
|
||||
map.put("aof_rewrite_scheduled", "rewrite任务计划,当客户端发送bgrewriteaof指令,如果当前rewrite子进程正在执行,那么将客户端请求的bgrewriteaof变为计划任务,待aof子进程结束后执行rewrite ");
|
||||
|
||||
map.put("aof_last_rewrite_time_sec", "最近一次aof rewrite耗费的时长");
|
||||
map.put("aof_current_rewrite_time_sec", "如果rewrite操作正在进行,则记录所使用的时间,单位秒");
|
||||
map.put("aof_last_bgrewrite_status", "上次bgrewrite aof操作的状态");
|
||||
map.put("aof_last_write_status", "上次aof写入状态");
|
||||
|
||||
map.put("total_commands_processed", "redis处理的命令数");
|
||||
map.put("total_connections_received", "新创建连接个数,如果新创建连接过多,过度地创建和销毁连接对性能有影响,说明短连接严重或连接池使用有问题,需调研代码的连接设置");
|
||||
map.put("instantaneous_ops_per_sec", "redis当前的qps,redis内部较实时的每秒执行的命令数");
|
||||
map.put("total_net_input_bytes", "redis网络入口流量字节数");
|
||||
map.put("total_net_output_bytes", "redis网络出口流量字节数");
|
||||
|
||||
map.put("instantaneous_input_kbps", "redis网络入口kps");
|
||||
map.put("instantaneous_output_kbps", "redis网络出口kps");
|
||||
map.put("rejected_connections", "拒绝的连接个数,redis连接个数达到maxclients限制,拒绝新连接的个数");
|
||||
map.put("sync_full", "主从完全同步成功次数");
|
||||
|
||||
map.put("sync_partial_ok", "主从部分同步成功次数");
|
||||
map.put("sync_partial_err", "主从部分同步失败次数");
|
||||
map.put("expired_keys", "运行以来过期的key的数量");
|
||||
map.put("evicted_keys", "运行以来剔除(超过了maxmemory后)的key的数量");
|
||||
map.put("keyspace_hits", "命中次数");
|
||||
map.put("keyspace_misses", "没命中次数");
|
||||
map.put("pubsub_channels", "当前使用中的频道数量");
|
||||
map.put("pubsub_patterns", "当前使用的模式的数量");
|
||||
map.put("latest_fork_usec", "最近一次fork操作阻塞redis进程的耗时数,单位微秒");
|
||||
map.put("role", "实例的角色,是master or slave");
|
||||
map.put("connected_slaves", "连接的slave实例个数");
|
||||
map.put("master_repl_offset", "主从同步偏移量,此值如果和上面的offset相同说明主从一致没延迟");
|
||||
map.put("repl_backlog_active", "复制积压缓冲区是否开启");
|
||||
map.put("repl_backlog_size", "复制积压缓冲大小");
|
||||
map.put("repl_backlog_first_byte_offset", "复制缓冲区里偏移量的大小");
|
||||
map.put("repl_backlog_histlen", "此值等于 master_repl_offset - repl_backlog_first_byte_offset,该值不会超过repl_backlog_size的大小");
|
||||
map.put("used_cpu_sys", "将所有redis主进程在核心态所占用的CPU时求和累计起来");
|
||||
map.put("used_cpu_user", "将所有redis主进程在用户态所占用的CPU时求和累计起来");
|
||||
map.put("used_cpu_sys_children", "将后台进程在核心态所占用的CPU时求和累计起来");
|
||||
map.put("used_cpu_user_children", "将后台进程在用户态所占用的CPU时求和累计起来");
|
||||
map.put("cluster_enabled", "实例是否启用集群模式");
|
||||
map.put("db0", "db0的key的数量,以及带有生存期的key的数,平均存活时间");
|
||||
|
||||
}
|
||||
|
||||
private String key;
|
||||
private String value;
|
||||
private String description;
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
this.description = map.get(this.key);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RedisInfo{" + "key='" + key + '\'' + ", value='" + value + '\'' + ", desctiption='" + description + '\'' + '}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.monitor.exception;
|
||||
|
||||
/**
|
||||
* Redis 连接异常
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class RedisConnectException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1639374111871115063L;
|
||||
|
||||
public RedisConnectException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package org.jeecg.modules.monitor.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import org.jeecg.modules.monitor.domain.RedisInfo;
|
||||
import org.jeecg.modules.monitor.exception.RedisConnectException;
|
||||
|
||||
/**
|
||||
* @Description: redis信息service接口
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public interface RedisService {
|
||||
|
||||
/**
|
||||
* 获取 redis 的详细信息
|
||||
*
|
||||
* @return List
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
List<RedisInfo> getRedisInfo() throws RedisConnectException;
|
||||
|
||||
/**
|
||||
* 获取 redis key 数量
|
||||
*
|
||||
* @return Map
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
Map<String, Object> getKeysSize() throws RedisConnectException;
|
||||
|
||||
/**
|
||||
* 获取 redis 内存信息
|
||||
*
|
||||
* @return Map
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
Map<String, Object> getMemoryInfo() throws RedisConnectException;
|
||||
/**
|
||||
* 获取 报表需要个redis信息
|
||||
* @param type
|
||||
* @return Map
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
Map<String, JSONArray> getMapForReport(String type) throws RedisConnectException ;
|
||||
|
||||
/**
|
||||
* 获取历史性能指标
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:57
|
||||
*/
|
||||
Map<String, List<Map<String, Object>>> getMetricsHistory();
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package org.jeecg.modules.monitor.service.impl;
|
||||
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 功能说明:自定义邮件检测
|
||||
*
|
||||
* @author: 李波
|
||||
* @email: 503378406@qq.com
|
||||
* @date: 2019-06-29
|
||||
*/
|
||||
@Component
|
||||
public class MailHealthIndicator implements HealthIndicator {
|
||||
|
||||
|
||||
@Override public Health health() {
|
||||
int errorCode = check();
|
||||
if (errorCode != 0) {
|
||||
return Health.down().withDetail("Error Code", errorCode) .build();
|
||||
}
|
||||
return Health.up().build();
|
||||
}
|
||||
int check(){
|
||||
//可以实现自定义的数据库检测逻辑
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,174 @@
|
||||
package org.jeecg.modules.monitor.service.impl;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.monitor.domain.RedisInfo;
|
||||
import org.jeecg.modules.monitor.exception.RedisConnectException;
|
||||
import org.jeecg.modules.monitor.service.RedisService;
|
||||
import org.springframework.cglib.beans.BeanMap;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Redis 监控信息获取
|
||||
*
|
||||
* @Author MrBird
|
||||
*/
|
||||
@Service("redisService")
|
||||
@Slf4j
|
||||
public class RedisServiceImpl implements RedisService {
|
||||
|
||||
@Resource
|
||||
private RedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
/**
|
||||
* redis信息
|
||||
*/
|
||||
private static final String REDIS_MESSAGE = "3";
|
||||
|
||||
/**
|
||||
* redis性能信息记录
|
||||
*/
|
||||
private static final Map<String,List<Map<String, Object>>> REDIS_METRICS = new HashMap<>(2);
|
||||
|
||||
/**
|
||||
* Redis详细信息
|
||||
*/
|
||||
@Override
|
||||
public List<RedisInfo> getRedisInfo() throws RedisConnectException {
|
||||
Properties info = redisConnectionFactory.getConnection().info();
|
||||
List<RedisInfo> infoList = new ArrayList<>();
|
||||
RedisInfo redisInfo = null;
|
||||
for (Map.Entry<Object, Object> entry : info.entrySet()) {
|
||||
redisInfo = new RedisInfo();
|
||||
redisInfo.setKey(oConvertUtils.getString(entry.getKey()));
|
||||
redisInfo.setValue(oConvertUtils.getString(entry.getValue()));
|
||||
infoList.add(redisInfo);
|
||||
}
|
||||
return infoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getKeysSize() throws RedisConnectException {
|
||||
Long dbSize = redisConnectionFactory.getConnection().dbSize();
|
||||
Map<String, Object> map = new HashMap(5);
|
||||
map.put("create_time", System.currentTimeMillis());
|
||||
map.put("dbSize", dbSize);
|
||||
|
||||
log.debug("--getKeysSize--: " + map.toString());
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getMemoryInfo() throws RedisConnectException {
|
||||
Map<String, Object> map = null;
|
||||
Properties info = redisConnectionFactory.getConnection().info();
|
||||
for (Map.Entry<Object, Object> entry : info.entrySet()) {
|
||||
String key = oConvertUtils.getString(entry.getKey());
|
||||
if ("used_memory".equals(key)) {
|
||||
map = new HashMap(5);
|
||||
map.put("used_memory", entry.getValue());
|
||||
map.put("create_time", System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
log.debug("--getMemoryInfo--: " + map.toString());
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询redis信息for报表
|
||||
* @param type 1redis key数量 2 占用内存 3redis信息
|
||||
* @return
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
@Override
|
||||
public Map<String, JSONArray> getMapForReport(String type) throws RedisConnectException {
|
||||
Map<String,JSONArray> mapJson=new HashMap(5);
|
||||
JSONArray json = new JSONArray();
|
||||
if(REDIS_MESSAGE.equals(type)){
|
||||
List<RedisInfo> redisInfo = getRedisInfo();
|
||||
for(RedisInfo info:redisInfo){
|
||||
Map<String, Object> map= Maps.newHashMap();
|
||||
BeanMap beanMap = BeanMap.create(info);
|
||||
for (Object key : beanMap.keySet()) {
|
||||
map.put(key+"", beanMap.get(key));
|
||||
}
|
||||
json.add(map);
|
||||
}
|
||||
mapJson.put("data",json);
|
||||
return mapJson;
|
||||
}
|
||||
int length = 5;
|
||||
for(int i = 0; i < length; i++){
|
||||
JSONObject jo = new JSONObject();
|
||||
Map<String, Object> map;
|
||||
if("1".equals(type)){
|
||||
map= getKeysSize();
|
||||
jo.put("value",map.get("dbSize"));
|
||||
}else{
|
||||
map = getMemoryInfo();
|
||||
Integer usedMemory = Integer.valueOf(map.get("used_memory").toString());
|
||||
jo.put("value",usedMemory/1000);
|
||||
}
|
||||
String createTime = DateUtil.formatTime(DateUtil.date((Long) map.get("create_time")-(4-i)*1000));
|
||||
jo.put("name",createTime);
|
||||
json.add(jo);
|
||||
}
|
||||
mapJson.put("data",json);
|
||||
return mapJson;
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
/**
|
||||
* 获取历史性能指标
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:57
|
||||
*/
|
||||
@Override
|
||||
public Map<String, List<Map<String, Object>>> getMetricsHistory() {
|
||||
return REDIS_METRICS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录近一小时redis监控数据 <br/>
|
||||
* 60s一次,,记录存储keysize和内存
|
||||
* @throws RedisConnectException
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:09
|
||||
*/
|
||||
@Scheduled(fixedRate = 60000)
|
||||
public void recordCustomMetric() throws RedisConnectException {
|
||||
List<Map<String, Object>> list= new ArrayList<>();
|
||||
if(REDIS_METRICS.containsKey("dbSize")){
|
||||
list = REDIS_METRICS.get("dbSize");
|
||||
}else{
|
||||
REDIS_METRICS.put("dbSize",list);
|
||||
}
|
||||
if(list.size()>60){
|
||||
list.remove(0);
|
||||
}
|
||||
list.add(getKeysSize());
|
||||
list= new ArrayList<>();
|
||||
if(REDIS_METRICS.containsKey("memory")){
|
||||
list = REDIS_METRICS.get("memory");
|
||||
}else{
|
||||
REDIS_METRICS.put("memory",list);
|
||||
}
|
||||
if(list.size()>60){
|
||||
list.remove(0);
|
||||
}
|
||||
list.add(getMemoryInfo());
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
//package org.jeecg.modules.ngalain.aop;
|
||||
//
|
||||
//import javax.servlet.http.HttpServletRequest;
|
||||
//
|
||||
//import org.aspectj.lang.ProceedingJoinPoint;
|
||||
//import org.aspectj.lang.annotation.Around;
|
||||
//import org.aspectj.lang.annotation.Aspect;
|
||||
//import org.aspectj.lang.annotation.Pointcut;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.web.context.request.RequestAttributes;
|
||||
//import org.springframework.web.context.request.RequestContextHolder;
|
||||
//import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
//import org.slf4j.Logger;
|
||||
//import org.slf4j.LoggerFactory;;
|
||||
//
|
||||
//
|
||||
//// 暂时注释掉,提高系统性能
|
||||
////@Aspect //定义一个切面
|
||||
////@Configuration
|
||||
//public class LogRecordAspect {
|
||||
//private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);
|
||||
//
|
||||
// // 定义切点Pointcut
|
||||
// @Pointcut("execution(public * org.jeecg.modules.*.*.*Controller.*(..))")
|
||||
// public void excudeService() {
|
||||
// }
|
||||
//
|
||||
// @Around("excudeService()")
|
||||
// public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
|
||||
// RequestAttributes ra = RequestContextHolder.getRequestAttributes();
|
||||
// ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
||||
// HttpServletRequest request = sra.getRequest();
|
||||
//
|
||||
// String url = request.getRequestURL().toString();
|
||||
// String method = request.getMethod();
|
||||
// String uri = request.getRequestURI();
|
||||
// String queryString = request.getQueryString();
|
||||
// logger.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString);
|
||||
//
|
||||
// // result的值就是被拦截方法的返回值
|
||||
// Object result = pjp.proceed();
|
||||
//
|
||||
// logger.info("请求结束,controller的返回值是 " + result);
|
||||
// return result;
|
||||
// }
|
||||
//}
|
||||
@ -0,0 +1,86 @@
|
||||
//package org.jeecg.modules.ngalain.controller;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//
|
||||
//import javax.servlet.http.HttpServletRequest;
|
||||
//
|
||||
//import org.apache.shiro.SecurityUtils;
|
||||
//import org.jeecg.common.api.vo.Result;
|
||||
//import org.jeecg.common.system.vo.DictModel;
|
||||
//import org.jeecg.common.system.vo.LoginUser;
|
||||
//import org.jeecg.modules.ngalain.service.NgAlainService;
|
||||
//import org.jeecg.modules.system.service.ISysDictService;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.web.bind.annotation.PathVariable;
|
||||
//import org.springframework.web.bind.annotation.RequestMapping;
|
||||
//import org.springframework.web.bind.annotation.RequestMethod;
|
||||
//import org.springframework.web.bind.annotation.ResponseBody;
|
||||
//import org.springframework.web.bind.annotation.RestController;
|
||||
//
|
||||
//import com.alibaba.fastjson.JSONObject;
|
||||
//
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//
|
||||
//@Slf4j
|
||||
//@RestController
|
||||
//@RequestMapping("/sys/ng-alain")
|
||||
//public class NgAlainController {
|
||||
// @Autowired
|
||||
// private NgAlainService ngAlainService;
|
||||
// @Autowired
|
||||
// private ISysDictService sysDictService;
|
||||
//
|
||||
// @RequestMapping(value = "/getAppData")
|
||||
// @ResponseBody
|
||||
// public JSONObject getAppData(HttpServletRequest request) throws Exception {
|
||||
// String token=request.getHeader("X-Access-Token");
|
||||
// JSONObject j = new JSONObject();
|
||||
// LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
// JSONObject userObjcet = new JSONObject();
|
||||
// userObjcet.put("name", user.getUsername());
|
||||
// userObjcet.put("avatar", user.getAvatar());
|
||||
// userObjcet.put("email", user.getEmail());
|
||||
// userObjcet.put("token", token);
|
||||
// j.put("user", userObjcet);
|
||||
// j.put("menu",ngAlainService.getMenu(user.getUsername()));
|
||||
// JSONObject app = new JSONObject();
|
||||
// app.put("name", "jeecg-boot-angular");
|
||||
// app.put("description", "jeecg+ng-alain整合版本");
|
||||
// j.put("app", app);
|
||||
// return j;
|
||||
// }
|
||||
//
|
||||
// @RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
|
||||
// public Object getDictItems(@PathVariable String dictCode) {
|
||||
// log.info(" dictCode : "+ dictCode);
|
||||
// Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
// List<DictModel> ls = null;
|
||||
// try {
|
||||
// ls = sysDictService.queryDictItemsByCode(dictCode);
|
||||
// result.setSuccess(true);
|
||||
// result.setResult(ls);
|
||||
// } catch (Exception e) {
|
||||
// log.error(e.getMessage(),e);
|
||||
// result.error500("操作失败");
|
||||
// return result;
|
||||
// }
|
||||
// List<JSONObject> dictlist=new ArrayList<>();
|
||||
// for (DictModel l : ls) {
|
||||
// JSONObject dict=new JSONObject();
|
||||
// try {
|
||||
// dict.put("value",Integer.parseInt(l.getValue()));
|
||||
// } catch (NumberFormatException e) {
|
||||
// dict.put("value",l.getValue());
|
||||
// }
|
||||
// dict.put("label",l.getText());
|
||||
// dictlist.add(dict);
|
||||
// }
|
||||
// return dictlist;
|
||||
// }
|
||||
// @RequestMapping(value = "/getDictItemsByTable/{table}/{key}/{value}", method = RequestMethod.GET)
|
||||
// public Object getDictItemsByTable(@PathVariable String table,@PathVariable String key,@PathVariable String value) {
|
||||
// return this.ngAlainService.getDictByTable(table,key,value);
|
||||
// }
|
||||
//}
|
||||
@ -0,0 +1,37 @@
|
||||
//package org.jeecg.modules.ngalain.service;
|
||||
//
|
||||
//import com.alibaba.fastjson.JSONArray;
|
||||
//
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//
|
||||
///**
|
||||
// * @Description: NgAlainService接口
|
||||
// * @author: jeecg-boot
|
||||
// */
|
||||
//public interface NgAlainService {
|
||||
// /**
|
||||
// * 菜单
|
||||
// * @param id
|
||||
// * @return JSONArray
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public JSONArray getMenu(String id) throws Exception;
|
||||
//
|
||||
// /**
|
||||
// * jeecg菜单
|
||||
// * @param id
|
||||
// * @return JSONArray
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public JSONArray getJeecgMenu(String id) throws Exception;
|
||||
//
|
||||
// /**
|
||||
// * 获取字典值
|
||||
// * @param table
|
||||
// * @param key
|
||||
// * @param value
|
||||
// * @return List<Map<String, String>>
|
||||
// */
|
||||
// public List<Map<String, String>> getDictByTable(String table, String key, String value);
|
||||
//}
|
||||
@ -0,0 +1,187 @@
|
||||
//package org.jeecg.modules.ngalain.service.impl;
|
||||
//
|
||||
//import com.alibaba.fastjson.JSONArray;
|
||||
//import com.alibaba.fastjson.JSONObject;
|
||||
//import org.jeecg.common.constant.CommonConstant;
|
||||
//import org.jeecg.common.constant.SymbolConstant;
|
||||
//import org.jeecg.common.util.oConvertUtils;
|
||||
//import org.jeecg.modules.ngalain.service.NgAlainService;
|
||||
//import org.jeecg.modules.system.entity.SysPermission;
|
||||
//import org.jeecg.modules.system.mapper.SysDictMapper;
|
||||
//import org.jeecg.modules.system.service.ISysPermissionService;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.stereotype.Service;
|
||||
//import org.springframework.transaction.annotation.Transactional;
|
||||
//
|
||||
//import java.util.Base64;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//
|
||||
///**
|
||||
// * @Description: NgAlainServiceImpl 实现类
|
||||
// * @author: jeecg-boot
|
||||
// */
|
||||
//@Service("ngAlainService")
|
||||
//public class NgAlainServiceImpl implements NgAlainService {
|
||||
// @Autowired
|
||||
// private ISysPermissionService sysPermissionService;
|
||||
// @Autowired
|
||||
// private SysDictMapper mapper;
|
||||
// @Override
|
||||
// public JSONArray getMenu(String id) throws Exception {
|
||||
// return getJeecgMenu(id);
|
||||
// }
|
||||
// @Override
|
||||
// public JSONArray getJeecgMenu(String id) throws Exception {
|
||||
// List<SysPermission> metaList = sysPermissionService.queryByUser(id);
|
||||
// JSONArray jsonArray = new JSONArray();
|
||||
// getPermissionJsonArray(jsonArray, metaList, null);
|
||||
// JSONArray menulist= parseNgAlain(jsonArray);
|
||||
// JSONObject jeecgMenu = new JSONObject();
|
||||
// jeecgMenu.put("text", "jeecg菜单");
|
||||
// jeecgMenu.put("group",true);
|
||||
// jeecgMenu.put("children", menulist);
|
||||
// JSONArray jeecgMenuList=new JSONArray();
|
||||
// jeecgMenuList.add(jeecgMenu);
|
||||
// return jeecgMenuList;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public List<Map<String, String>> getDictByTable(String table, String key, String value) {
|
||||
// return this.mapper.getDictByTableNgAlain(table,key,value);
|
||||
// }
|
||||
//
|
||||
// private JSONArray parseNgAlain(JSONArray jsonArray) {
|
||||
// JSONArray menulist=new JSONArray();
|
||||
// for (Object object : jsonArray) {
|
||||
// JSONObject jsonObject= (JSONObject) object;
|
||||
// String path= (String) jsonObject.get("path");
|
||||
// JSONObject meta= (JSONObject) jsonObject.get("meta");
|
||||
// JSONObject menu=new JSONObject();
|
||||
// menu.put("text",meta.get("title"));
|
||||
// menu.put("reuse",true);
|
||||
// if (jsonObject.get("children")!=null){
|
||||
// JSONArray child= parseNgAlain((JSONArray) jsonObject.get("children"));
|
||||
// menu.put("children",child);
|
||||
// JSONObject icon=new JSONObject();
|
||||
// icon.put("type", "icon");
|
||||
// icon.put("value", meta.get("icon"));
|
||||
// menu.put("icon",icon);
|
||||
// }else {
|
||||
// menu.put("link",path);
|
||||
// }
|
||||
// menulist.add(menu);
|
||||
// }
|
||||
// return menulist;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取菜单JSON数组
|
||||
// * @param jsonArray
|
||||
// * @param metaList
|
||||
// * @param parentJson
|
||||
// */
|
||||
// private void getPermissionJsonArray(JSONArray jsonArray,List<SysPermission> metaList,JSONObject parentJson) {
|
||||
// for (SysPermission permission : metaList) {
|
||||
// if(permission.getMenuType()==null) {
|
||||
// continue;
|
||||
// }
|
||||
// String tempPid = permission.getParentId();
|
||||
// JSONObject json = getPermissionJsonObject(permission);
|
||||
// if(parentJson==null && oConvertUtils.isEmpty(tempPid)) {
|
||||
// jsonArray.add(json);
|
||||
// if(!permission.isLeaf()) {
|
||||
// getPermissionJsonArray(jsonArray, metaList, json);
|
||||
// }
|
||||
// }else if(parentJson!=null && oConvertUtils.isNotEmpty(tempPid) && tempPid.equals(parentJson.getString("id"))){
|
||||
// if(permission.getMenuType()==0) {
|
||||
// JSONObject metaJson = parentJson.getJSONObject("meta");
|
||||
// if(metaJson.containsKey("permissionList")) {
|
||||
// metaJson.getJSONArray("permissionList").add(json);
|
||||
// }else {
|
||||
// JSONArray permissionList = new JSONArray();
|
||||
// permissionList.add(json);
|
||||
// metaJson.put("permissionList", permissionList);
|
||||
// }
|
||||
//
|
||||
// }else if(permission.getMenuType()==1) {
|
||||
// if(parentJson.containsKey("children")) {
|
||||
// parentJson.getJSONArray("children").add(json);
|
||||
// }else {
|
||||
// JSONArray children = new JSONArray();
|
||||
// children.add(json);
|
||||
// parentJson.put("children", children);
|
||||
// }
|
||||
//
|
||||
// if(!permission.isLeaf()) {
|
||||
// getPermissionJsonArray(jsonArray, metaList, json);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// private JSONObject getPermissionJsonObject(SysPermission permission) {
|
||||
// JSONObject json = new JSONObject();
|
||||
// //类型(0:一级菜单 1:子菜单 2:按钮)
|
||||
// if(CommonConstant.MENU_TYPE_2.equals(permission.getMenuType())) {
|
||||
// json.put("action", permission.getPerms());
|
||||
// json.put("describe", permission.getName());
|
||||
// }else if(CommonConstant.MENU_TYPE_0.equals(permission.getMenuType()) || CommonConstant.MENU_TYPE_1.equals(permission.getMenuType())) {
|
||||
// json.put("id", permission.getId());
|
||||
// boolean flag = permission.getUrl()!=null&&(permission.getUrl().startsWith(CommonConstant.HTTP_PROTOCOL)||permission.getUrl().startsWith(CommonConstant.HTTPS_PROTOCOL));
|
||||
// if(flag) {
|
||||
// String url= new String(Base64.getUrlEncoder().encode(permission.getUrl().getBytes()));
|
||||
// json.put("path", "/sys/link/" +url.replaceAll("=",""));
|
||||
// }else {
|
||||
// json.put("path", permission.getUrl());
|
||||
// }
|
||||
//
|
||||
// //重要规则:路由name (通过URL生成路由name,路由name供前端开发,页面跳转使用)
|
||||
// json.put("name", urlToRouteName(permission.getUrl()));
|
||||
//
|
||||
// //是否隐藏路由,默认都是显示的
|
||||
// if(permission.isHidden()) {
|
||||
// json.put("hidden",true);
|
||||
// }
|
||||
// //聚合路由
|
||||
// if(permission.isAlwaysShow()) {
|
||||
// json.put("alwaysShow",true);
|
||||
// }
|
||||
// json.put("component", permission.getComponent());
|
||||
// JSONObject meta = new JSONObject();
|
||||
// meta.put("title", permission.getName());
|
||||
// if(oConvertUtils.isEmpty(permission.getParentId())) {
|
||||
// //一级菜单跳转地址
|
||||
// json.put("redirect",permission.getRedirect());
|
||||
// meta.put("icon", oConvertUtils.getString(permission.getIcon(), ""));
|
||||
// }else {
|
||||
// meta.put("icon", oConvertUtils.getString(permission.getIcon(), ""));
|
||||
// }
|
||||
// if(flag) {
|
||||
// meta.put("url", permission.getUrl());
|
||||
// }
|
||||
// json.put("meta", meta);
|
||||
// }
|
||||
//
|
||||
// return json;
|
||||
// }
|
||||
// /**
|
||||
// * 通过URL生成路由name(去掉URL前缀斜杠,替换内容中的斜杠‘/’为-)
|
||||
// * 举例: URL = /isystem/role
|
||||
// * RouteName = isystem-role
|
||||
// * @return
|
||||
// */
|
||||
// private String urlToRouteName(String url) {
|
||||
// if(oConvertUtils.isNotEmpty(url)) {
|
||||
// if(url.startsWith(SymbolConstant.SINGLE_SLASH)) {
|
||||
// url = url.substring(1);
|
||||
// }
|
||||
// url = url.replace("/", "-");
|
||||
// return url;
|
||||
// }else {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@ -0,0 +1,97 @@
|
||||
package org.jeecg.modules.oss.controller;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.oss.entity.OssFile;
|
||||
import org.jeecg.modules.oss.service.IOssFileService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 云存储示例 DEMO
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/sys/oss/file")
|
||||
public class OssFileController {
|
||||
|
||||
@Autowired
|
||||
private IOssFileService ossFileService;
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
public Result<IPage<OssFile>> queryPageList(OssFile file,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
Result<IPage<OssFile>> result = new Result<>();
|
||||
QueryWrapper<OssFile> queryWrapper = QueryGenerator.initQueryWrapper(file, req.getParameterMap());
|
||||
Page<OssFile> page = new Page<>(pageNo, pageSize);
|
||||
IPage<OssFile> pageList = ossFileService.page(page, queryWrapper);
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/upload")
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:ossFile:upload")
|
||||
public Result upload(@RequestParam("file") MultipartFile multipartFile) {
|
||||
Result result = new Result();
|
||||
try {
|
||||
ossFileService.upload(multipartFile);
|
||||
result.success("上传成功!");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
log.info(ex.getMessage(), ex);
|
||||
result.error500("上传失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@DeleteMapping("/delete")
|
||||
public Result delete(@RequestParam(name = "id") String id) {
|
||||
Result result = new Result();
|
||||
OssFile file = ossFileService.getById(id);
|
||||
if (file == null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
boolean ok = ossFileService.delete(file);
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询.
|
||||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/queryById")
|
||||
public Result<OssFile> queryById(@RequestParam(name = "id") String id) {
|
||||
Result<OssFile> result = new Result<>();
|
||||
OssFile file = ossFileService.getById(id);
|
||||
if (file == null) {
|
||||
result.error500("未找到对应实体");
|
||||
}
|
||||
else {
|
||||
result.setResult(file);
|
||||
result.setSuccess(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package org.jeecg.modules.oss.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.jeecg.common.system.base.entity.JeecgEntity;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
|
||||
/**
|
||||
* @Description: oss云存储实体类
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Data
|
||||
@TableName("oss_file")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class OssFile extends JeecgEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Excel(name = "文件名称")
|
||||
private String fileName;
|
||||
|
||||
@Excel(name = "文件地址")
|
||||
private String url;
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package org.jeecg.modules.oss.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.jeecg.modules.oss.entity.OssFile;
|
||||
|
||||
/**
|
||||
* @Description: oss云存储Mapper
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public interface OssFileMapper extends BaseMapper<OssFile> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package org.jeecg.modules.oss.service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.oss.entity.OssFile;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* @Description: OOS云存储service接口
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public interface IOssFileService extends IService<OssFile> {
|
||||
|
||||
/**
|
||||
* oss文件上传
|
||||
* @param multipartFile
|
||||
* @throws IOException
|
||||
*/
|
||||
void upload(MultipartFile multipartFile) throws Exception;
|
||||
|
||||
/**
|
||||
* oss文件删除
|
||||
* @param ossFile OSSFile对象
|
||||
* @return
|
||||
*/
|
||||
boolean delete(OssFile ossFile);
|
||||
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package org.jeecg.modules.oss.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.common.util.oss.OssBootUtil;
|
||||
import org.jeecg.modules.oss.entity.OssFile;
|
||||
import org.jeecg.modules.oss.mapper.OssFileMapper;
|
||||
import org.jeecg.modules.oss.service.IOssFileService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @Description: OSS云存储实现类
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Service("ossFileService")
|
||||
public class OssFileServiceImpl extends ServiceImpl<OssFileMapper, OssFile> implements IOssFileService {
|
||||
|
||||
@Override
|
||||
public void upload(MultipartFile multipartFile) throws Exception {
|
||||
String fileName = multipartFile.getOriginalFilename();
|
||||
fileName = CommonUtils.getFileName(fileName);
|
||||
OssFile ossFile = new OssFile();
|
||||
ossFile.setFileName(fileName);
|
||||
String url = OssBootUtil.upload(multipartFile,"upload/test");
|
||||
if(oConvertUtils.isEmpty(url)){
|
||||
throw new JeecgBootException("上传文件失败! ");
|
||||
}
|
||||
//update-begin--Author:scott Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败-------------------
|
||||
// 返回阿里云原生域名前缀URL
|
||||
ossFile.setUrl(OssBootUtil.getOriginalUrl(url));
|
||||
//update-end--Author:scott Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败-------------------
|
||||
this.save(ossFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(OssFile ossFile) {
|
||||
try {
|
||||
this.removeById(ossFile.getId());
|
||||
OssBootUtil.deleteUrl(ossFile.getUrl());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
log.error(ex.getMessage(),ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,292 @@
|
||||
package org.jeecg.modules.quartz.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.ImportExcelUtil;
|
||||
import org.jeecg.modules.quartz.entity.QuartzJob;
|
||||
import org.jeecg.modules.quartz.service.IQuartzJobService;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 定时任务在线管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-01-02
|
||||
* @Version:V1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/quartzJob")
|
||||
@Slf4j
|
||||
@Tag(name = "定时任务接口")
|
||||
public class QuartzJobController {
|
||||
@Autowired
|
||||
private IQuartzJobService quartzJobService;
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param quartzJob
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
public Result<?> queryPageList(QuartzJob quartzJob, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
QueryWrapper<QuartzJob> queryWrapper = QueryGenerator.initQueryWrapper(quartzJob, req.getParameterMap());
|
||||
Page<QuartzJob> page = new Page<QuartzJob>(pageNo, pageSize);
|
||||
IPage<QuartzJob> pageList = quartzJobService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加定时任务
|
||||
*
|
||||
* @param quartzJob
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:add")
|
||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||
public Result<?> add(@RequestBody QuartzJob quartzJob) {
|
||||
quartzJobService.saveAndScheduleJob(quartzJob);
|
||||
return Result.ok("创建定时任务成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新定时任务
|
||||
*
|
||||
* @param quartzJob
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:edit")
|
||||
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
|
||||
public Result<?> eidt(@RequestBody QuartzJob quartzJob) {
|
||||
try {
|
||||
quartzJobService.editAndScheduleJob(quartzJob);
|
||||
} catch (SchedulerException e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return Result.error("更新定时任务失败!");
|
||||
}
|
||||
return Result.ok("更新定时任务成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:delete")
|
||||
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
QuartzJob quartzJob = quartzJobService.getById(id);
|
||||
if (quartzJob == null) {
|
||||
return Result.error("未找到对应实体");
|
||||
}
|
||||
quartzJobService.deleteAndStopJob(quartzJob);
|
||||
return Result.ok("删除成功!");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:deleteBatch")
|
||||
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
if (ids == null || "".equals(ids.trim())) {
|
||||
return Result.error("参数不识别!");
|
||||
}
|
||||
for (String id : Arrays.asList(ids.split(SymbolConstant.COMMA))) {
|
||||
QuartzJob job = quartzJobService.getById(id);
|
||||
quartzJobService.deleteAndStopJob(job);
|
||||
}
|
||||
return Result.ok("删除定时任务成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停定时任务
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:pause")
|
||||
@GetMapping(value = "/pause")
|
||||
@Operation(summary = "停止定时任务")
|
||||
public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
|
||||
QuartzJob job = quartzJobService.getById(id);
|
||||
if (job == null) {
|
||||
return Result.error("定时任务不存在!");
|
||||
}
|
||||
quartzJobService.pause(job);
|
||||
return Result.ok("停止定时任务成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动定时任务
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:resume")
|
||||
@GetMapping(value = "/resume")
|
||||
@Operation(summary = "启动定时任务")
|
||||
public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
|
||||
QuartzJob job = quartzJobService.getById(id);
|
||||
if (job == null) {
|
||||
return Result.error("定时任务不存在!");
|
||||
}
|
||||
quartzJobService.resumeJob(job);
|
||||
//scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
|
||||
return Result.ok("启动定时任务成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryById", method = RequestMethod.GET)
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
QuartzJob quartzJob = quartzJobService.getById(id);
|
||||
return Result.ok(quartzJob);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param quartzJob
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, QuartzJob quartzJob) {
|
||||
// Step.1 组装查询条件
|
||||
QueryWrapper<QuartzJob> queryWrapper = QueryGenerator.initQueryWrapper(quartzJob, request.getParameterMap());
|
||||
// Step.2 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
List<QuartzJob> pageList = quartzJobService.list(queryWrapper);
|
||||
// 导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "定时任务列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, QuartzJob.class);
|
||||
//获取当前登录用户
|
||||
//update-begin---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:"+user.getRealname(), "导出信息"));
|
||||
//update-end---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
// 错误信息
|
||||
List<String> errorMessage = new ArrayList<>();
|
||||
int successLines = 0, errorLines = 0;
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 获取上传文件对象
|
||||
MultipartFile file = entity.getValue();
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
List<QuartzJob> listQuartzJobs = ExcelImportUtil.importExcel(file.getInputStream(), QuartzJob.class, params);
|
||||
//add-begin-author:taoyan date:20210909 for:导入定时任务,并不会被启动和调度,需要手动点击启动,才会加入调度任务中 #2986
|
||||
for(QuartzJob job: listQuartzJobs){
|
||||
job.setStatus(CommonConstant.STATUS_DISABLE);
|
||||
}
|
||||
List<String> list = ImportExcelUtil.importDateSave(listQuartzJobs, IQuartzJobService.class, errorMessage,CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME);
|
||||
//add-end-author:taoyan date:20210909 for:导入定时任务,并不会被启动和调度,需要手动点击启动,才会加入调度任务中 #2986
|
||||
errorLines+=list.size();
|
||||
successLines+=(listQuartzJobs.size()-errorLines);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("文件导入失败!");
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ImportExcelUtil.imporReturnRes(errorLines,successLines,errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@RequiresPermissions("system:quartzJob:execute")
|
||||
@GetMapping("/execute")
|
||||
public Result<?> execute(@RequestParam(name = "id", required = true) String id) {
|
||||
QuartzJob quartzJob = quartzJobService.getById(id);
|
||||
if (quartzJob == null) {
|
||||
return Result.error("未找到对应实体");
|
||||
}
|
||||
try {
|
||||
quartzJobService.execute(quartzJob);
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
log.info("定时任务 立即执行失败>>"+e.getMessage());
|
||||
return Result.error("执行失败!");
|
||||
}
|
||||
return Result.ok("执行成功!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package org.jeecg.modules.quartz.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: 定时任务在线管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-01-02
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_quartz_job")
|
||||
public class QuartzJob implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**id*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private java.lang.String id;
|
||||
/**创建人*/
|
||||
private java.lang.String createBy;
|
||||
/**创建时间*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
private java.util.Date createTime;
|
||||
/**删除状态*/
|
||||
private java.lang.Integer delFlag;
|
||||
/**修改人*/
|
||||
private java.lang.String updateBy;
|
||||
/**修改时间*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
private java.util.Date updateTime;
|
||||
/**任务类名*/
|
||||
@Excel(name="任务类名",width=40)
|
||||
private java.lang.String jobClassName;
|
||||
/**cron表达式*/
|
||||
@Excel(name="cron表达式",width=30)
|
||||
private java.lang.String cronExpression;
|
||||
/**参数*/
|
||||
@Excel(name="参数",width=15)
|
||||
private java.lang.String parameter;
|
||||
/**描述*/
|
||||
@Excel(name="描述",width=40)
|
||||
private java.lang.String description;
|
||||
/**状态 0正常 -1停止*/
|
||||
@Excel(name="状态",width=15,dicCode="quartz_status")
|
||||
@Dict(dicCode = "quartz_status")
|
||||
private java.lang.Integer status;
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package org.jeecg.modules.quartz.job;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.quartz.*;
|
||||
|
||||
/**
|
||||
* @Description: 同步定时任务测试
|
||||
*
|
||||
* 此处的同步是指 当定时任务的执行时间大于任务的时间间隔时
|
||||
* 会等待第一个任务执行完成才会走第二个任务
|
||||
*
|
||||
*
|
||||
* @author: taoyan
|
||||
* @date: 2020年06月19日
|
||||
*/
|
||||
@PersistJobDataAfterExecution
|
||||
@DisallowConcurrentExecution
|
||||
@Slf4j
|
||||
public class AsyncJob implements Job {
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
log.info(" --- 同步任务调度开始 --- ");
|
||||
try {
|
||||
//此处模拟任务执行时间 5秒 任务表达式配置为每秒执行一次:0/1 * * * * ? *
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//测试发现 每5秒执行一次
|
||||
log.info(" --- 执行完毕,时间:"+DateUtils.now()+"---");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package org.jeecg.modules.quartz.job;
|
||||
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 示例不带参定时任务
|
||||
*
|
||||
* @Author Scott
|
||||
*/
|
||||
@Slf4j
|
||||
public class SampleJob implements Job {
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
log.info(" Job Execution key:"+jobExecutionContext.getJobDetail().getKey());
|
||||
log.info(String.format(" Jeecg-Boot 普通定时任务 SampleJob ! 时间:" + DateUtils.getTimestamp()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package org.jeecg.modules.quartz.job;
|
||||
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 示例带参定时任务
|
||||
*
|
||||
* @Author Scott
|
||||
*/
|
||||
@Slf4j
|
||||
public class SampleParamJob implements Job {
|
||||
|
||||
/**
|
||||
* 若参数变量名修改 QuartzJobController中也需对应修改
|
||||
*/
|
||||
private String parameter;
|
||||
|
||||
public void setParameter(String parameter) {
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
log.info(" Job Execution key:"+jobExecutionContext.getJobDetail().getKey());
|
||||
log.info( String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package org.jeecg.modules.quartz.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.quartz.entity.QuartzJob;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 定时任务在线管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-01-02
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface QuartzJobMapper extends BaseMapper<QuartzJob> {
|
||||
|
||||
/**
|
||||
* 根据jobClassName查询
|
||||
* @param jobClassName 任务类名
|
||||
* @return
|
||||
*/
|
||||
public List<QuartzJob> findByJobClassName(@Param("jobClassName") String jobClassName);
|
||||
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.jeecg.modules.quartz.mapper.QuartzJobMapper">
|
||||
|
||||
<!-- 根据jobClassName查询 -->
|
||||
<select id="findByJobClassName" resultType="org.jeecg.modules.quartz.entity.QuartzJob">
|
||||
select * from sys_quartz_job where job_class_name = #{jobClassName}
|
||||
</select>
|
||||
</mapper>
|
||||
@ -0,0 +1,67 @@
|
||||
package org.jeecg.modules.quartz.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.modules.quartz.entity.QuartzJob;
|
||||
import org.quartz.SchedulerException;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 定时任务在线管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-28
|
||||
* @Version: V1.1
|
||||
*/
|
||||
public interface IQuartzJobService extends IService<QuartzJob> {
|
||||
|
||||
/**
|
||||
* 通过类名寻找定时任务
|
||||
* @param jobClassName 类名
|
||||
* @return List<QuartzJob>
|
||||
*/
|
||||
List<QuartzJob> findByJobClassName(String jobClassName);
|
||||
|
||||
/**
|
||||
* 保存定时任务
|
||||
* @param quartzJob
|
||||
* @return boolean
|
||||
*/
|
||||
boolean saveAndScheduleJob(QuartzJob quartzJob);
|
||||
|
||||
/**
|
||||
* 编辑定时任务
|
||||
* @param quartzJob
|
||||
* @return boolean
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 删除定时任务
|
||||
* @param quartzJob
|
||||
* @return boolean
|
||||
*/
|
||||
boolean deleteAndStopJob(QuartzJob quartzJob);
|
||||
|
||||
/**
|
||||
* 恢复定时任务
|
||||
* @param quartzJob
|
||||
* @return
|
||||
*/
|
||||
boolean resumeJob(QuartzJob quartzJob);
|
||||
|
||||
/**
|
||||
* 执行定时任务
|
||||
* @param quartzJob
|
||||
* @throws Exception
|
||||
*/
|
||||
void execute(QuartzJob quartzJob) throws Exception;
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
* @param quartzJob
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
void pause(QuartzJob quartzJob);
|
||||
}
|
||||
@ -0,0 +1,183 @@
|
||||
package org.jeecg.modules.quartz.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.jeecg.modules.quartz.entity.QuartzJob;
|
||||
import org.jeecg.modules.quartz.mapper.QuartzJobMapper;
|
||||
import org.jeecg.modules.quartz.service.IQuartzJobService;
|
||||
import org.quartz.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 定时任务在线管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-04-28
|
||||
* @Version: V1.1
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob> implements IQuartzJobService {
|
||||
@Autowired
|
||||
private QuartzJobMapper quartzJobMapper;
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
/**
|
||||
* 立即执行的任务分组
|
||||
*/
|
||||
private static final String JOB_TEST_GROUP = "test_group";
|
||||
|
||||
@Override
|
||||
public List<QuartzJob> findByJobClassName(String jobClassName) {
|
||||
return quartzJobMapper.findByJobClassName(jobClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存&启动定时任务
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = JeecgBootException.class)
|
||||
public boolean saveAndScheduleJob(QuartzJob quartzJob) {
|
||||
// DB设置修改
|
||||
quartzJob.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
boolean success = this.save(quartzJob);
|
||||
if (success) {
|
||||
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
||||
// 定时器添加
|
||||
this.schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复定时任务
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = JeecgBootException.class)
|
||||
public boolean resumeJob(QuartzJob quartzJob) {
|
||||
schedulerDelete(quartzJob.getId());
|
||||
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||
quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
|
||||
return this.updateById(quartzJob);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑&启停定时任务
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = JeecgBootException.class)
|
||||
public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
|
||||
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
||||
schedulerDelete(quartzJob.getId());
|
||||
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||
}else{
|
||||
scheduler.pauseJob(JobKey.jobKey(quartzJob.getId()));
|
||||
}
|
||||
return this.updateById(quartzJob);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除&停止删除定时任务
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = JeecgBootException.class)
|
||||
public boolean deleteAndStopJob(QuartzJob job) {
|
||||
schedulerDelete(job.getId());
|
||||
boolean ok = this.removeById(job.getId());
|
||||
return ok;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(QuartzJob quartzJob) throws Exception {
|
||||
String jobName = quartzJob.getJobClassName().trim();
|
||||
Date startDate = new Date();
|
||||
String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
|
||||
String identity = jobName + ymd;
|
||||
//3秒后执行 只执行一次
|
||||
// update-begin--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||
startDate.setTime(startDate.getTime() + 100L);
|
||||
// update-end--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||
// 定义一个Trigger
|
||||
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
|
||||
.withIdentity(identity, JOB_TEST_GROUP)
|
||||
.startAt(startDate)
|
||||
.build();
|
||||
// 构建job信息
|
||||
JobDetail jobDetail = JobBuilder.newJob(getClass(jobName).getClass()).withIdentity(identity).usingJobData("parameter", quartzJob.getParameter()).build();
|
||||
// 将trigger和 jobDetail 加入这个调度
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
// 启动scheduler
|
||||
scheduler.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = JeecgBootException.class)
|
||||
public void pause(QuartzJob quartzJob){
|
||||
schedulerDelete(quartzJob.getId());
|
||||
quartzJob.setStatus(CommonConstant.STATUS_DISABLE);
|
||||
this.updateById(quartzJob);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加定时任务
|
||||
*
|
||||
* @param jobClassName
|
||||
* @param cronExpression
|
||||
* @param parameter
|
||||
*/
|
||||
private void schedulerAdd(String id, String jobClassName, String cronExpression, String parameter) {
|
||||
try {
|
||||
// 启动调度器
|
||||
scheduler.start();
|
||||
|
||||
// 构建job信息
|
||||
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(id).usingJobData("parameter", parameter).build();
|
||||
|
||||
// 表达式调度构建器(即任务执行的时间)
|
||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
|
||||
|
||||
// 按新的cronExpression表达式构建一个新的trigger
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(id).withSchedule(scheduleBuilder).build();
|
||||
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
} catch (SchedulerException e) {
|
||||
throw new JeecgBootException("创建定时任务失败", e);
|
||||
} catch (RuntimeException e) {
|
||||
throw new JeecgBootException(e.getMessage(), e);
|
||||
}catch (Exception e) {
|
||||
throw new JeecgBootException("后台找不到该类名:" + jobClassName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时任务
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
private void schedulerDelete(String id) {
|
||||
try {
|
||||
scheduler.pauseTrigger(TriggerKey.triggerKey(id));
|
||||
scheduler.unscheduleJob(TriggerKey.triggerKey(id));
|
||||
scheduler.deleteJob(JobKey.jobKey(id));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new JeecgBootException("删除定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
private static Job getClass(String classname) throws Exception {
|
||||
Class<?> class1 = Class.forName(classname);
|
||||
return (Job) class1.newInstance();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package org.jeecg.modules.system.cache;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import me.zhyd.oauth.cache.AuthCacheConfig;
|
||||
import me.zhyd.oauth.cache.AuthStateCache;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
public class AuthStateRedisCache implements AuthStateCache {
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
private ValueOperations<String, String> valueOperations;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
valueOperations = redisTemplate.opsForValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 存入缓存,默认3分钟
|
||||
*
|
||||
* @param key 缓存key
|
||||
* @param value 缓存内容
|
||||
*/
|
||||
@Override
|
||||
public void cache(String key, String value) {
|
||||
valueOperations.set(key, value, AuthCacheConfig.timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 存入缓存
|
||||
*
|
||||
* @param key 缓存key
|
||||
* @param value 缓存内容
|
||||
* @param timeout 指定缓存过期时间(毫秒)
|
||||
*/
|
||||
@Override
|
||||
public void cache(String key, String value, long timeout) {
|
||||
valueOperations.set(key, value, timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存内容
|
||||
*
|
||||
* @param key 缓存key
|
||||
* @return 缓存内容
|
||||
*/
|
||||
@Override
|
||||
public String get(String key) {
|
||||
return valueOperations.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在key,如果对应key的value值已过期,也返回false
|
||||
*
|
||||
* @param key 缓存key
|
||||
* @return true:存在key,并且value没过期;false:key不存在或者已过期
|
||||
*/
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return redisTemplate.hasKey(key);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package org.jeecg.modules.system.config;
|
||||
|
||||
import me.zhyd.oauth.cache.AuthStateCache;
|
||||
import org.jeecg.modules.system.cache.AuthStateRedisCache;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class AuthStateConfiguration {
|
||||
|
||||
@Bean
|
||||
public AuthStateCache authStateCache() {
|
||||
return new AuthStateRedisCache();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package org.jeecg.modules.system.constant;
|
||||
|
||||
/**
|
||||
* 默认首页常量
|
||||
*/
|
||||
public interface DefIndexConst {
|
||||
|
||||
/**
|
||||
* 默认首页的roleCode
|
||||
*/
|
||||
String DEF_INDEX_ALL = "DEF_INDEX_ALL";
|
||||
|
||||
/**
|
||||
* 默认首页的缓存key
|
||||
*/
|
||||
String CACHE_KEY = "sys:cache:def_index";
|
||||
|
||||
/**
|
||||
* 默认首页的初始值
|
||||
*/
|
||||
String DEF_INDEX_NAME = "首页";
|
||||
String DEF_INDEX_URL = "/dashboard/analysis";
|
||||
String DEF_INDEX_COMPONENT = "dashboard/Analysis";
|
||||
|
||||
}
|
||||
@ -0,0 +1,351 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.constant.enums.FileTypeEnum;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @Author scott
|
||||
* @since 2018-12-20
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/common")
|
||||
public class CommonController {
|
||||
|
||||
@Value(value = "${jeecg.path.upload}")
|
||||
private String uploadpath;
|
||||
|
||||
/**
|
||||
* 本地:local minio:minio 阿里:alioss
|
||||
*/
|
||||
@Value(value="${jeecg.uploadType}")
|
||||
private String uploadType;
|
||||
|
||||
/**
|
||||
* @Author 政辉
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/403")
|
||||
public Result<?> noauth() {
|
||||
return Result.error("没有权限,请联系管理员授权,后刷新缓存!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传统一方法
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/upload")
|
||||
public Result<?> upload(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
Result<?> result = new Result<>();
|
||||
String savePath = "";
|
||||
String bizPath = request.getParameter("biz");
|
||||
|
||||
//LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
|
||||
if (oConvertUtils.isNotEmpty(bizPath)) {
|
||||
if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){
|
||||
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
||||
}
|
||||
}
|
||||
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
// 获取上传文件对象
|
||||
MultipartFile file = multipartRequest.getFile("file");
|
||||
if(oConvertUtils.isEmpty(bizPath)){
|
||||
if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
|
||||
//未指定目录,则用阿里云默认目录 upload
|
||||
bizPath = "upload";
|
||||
//result.setMessage("使用阿里云文件上传时,必须添加目录!");
|
||||
//result.setSuccess(false);
|
||||
//return result;
|
||||
}else{
|
||||
bizPath = "";
|
||||
}
|
||||
}
|
||||
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
|
||||
//update-begin-author:liusq date:20221102 for: 过滤上传文件类型
|
||||
SsrfFileTypeFilter.checkUploadFileType(file);
|
||||
//update-end-author:liusq date:20221102 for: 过滤上传文件类型
|
||||
//update-begin-author:lvdandan date:20200928 for:修改JEditor编辑器本地上传
|
||||
savePath = this.uploadLocal(file,bizPath);
|
||||
//update-begin-author:lvdandan date:20200928 for:修改JEditor编辑器本地上传
|
||||
/** 富文本编辑器及markdown本地上传时,采用返回链接方式
|
||||
//针对jeditor编辑器如何使 lcaol模式,采用 base64格式存储
|
||||
String jeditor = request.getParameter("jeditor");
|
||||
if(oConvertUtils.isNotEmpty(jeditor)){
|
||||
result.setMessage(CommonConstant.UPLOAD_TYPE_LOCAL);
|
||||
result.setSuccess(true);
|
||||
return result;
|
||||
}else{
|
||||
savePath = this.uploadLocal(file,bizPath);
|
||||
}
|
||||
*/
|
||||
}else{
|
||||
//update-begin-author:taoyan date:20200814 for:文件上传改造
|
||||
savePath = CommonUtils.upload(file, bizPath, uploadType);
|
||||
//update-end-author:taoyan date:20200814 for:文件上传改造
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(savePath)){
|
||||
result.setMessage(savePath);
|
||||
result.setSuccess(true);
|
||||
}else {
|
||||
result.setMessage("上传失败!");
|
||||
result.setSuccess(false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地文件上传
|
||||
* @param mf 文件
|
||||
* @param bizPath 自定义路径
|
||||
* @return
|
||||
*/
|
||||
private String uploadLocal(MultipartFile mf,String bizPath){
|
||||
try {
|
||||
String ctxPath = uploadpath;
|
||||
String fileName = null;
|
||||
File file = new File(ctxPath + File.separator + bizPath + File.separator );
|
||||
if (!file.exists()) {
|
||||
// 创建文件根目录
|
||||
file.mkdirs();
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = mf.getOriginalFilename();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
if(orgName.indexOf(SymbolConstant.SPOT)!=-1){
|
||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||
}else{
|
||||
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||
}
|
||||
String savePath = file.getPath() + File.separator + fileName;
|
||||
File savefile = new File(savePath);
|
||||
FileCopyUtils.copy(mf.getBytes(), savefile);
|
||||
String dbpath = null;
|
||||
if(oConvertUtils.isNotEmpty(bizPath)){
|
||||
dbpath = bizPath + File.separator + fileName;
|
||||
}else{
|
||||
dbpath = fileName;
|
||||
}
|
||||
if (dbpath.contains(SymbolConstant.DOUBLE_BACKSLASH)) {
|
||||
dbpath = dbpath.replace(SymbolConstant.DOUBLE_BACKSLASH, SymbolConstant.SINGLE_SLASH);
|
||||
}
|
||||
return dbpath;
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// @PostMapping(value = "/upload2")
|
||||
// public Result<?> upload2(HttpServletRequest request, HttpServletResponse response) {
|
||||
// Result<?> result = new Result<>();
|
||||
// try {
|
||||
// String ctxPath = uploadpath;
|
||||
// String fileName = null;
|
||||
// String bizPath = "files";
|
||||
// String tempBizPath = request.getParameter("biz");
|
||||
// if(oConvertUtils.isNotEmpty(tempBizPath)){
|
||||
// bizPath = tempBizPath;
|
||||
// }
|
||||
// String nowday = new SimpleDateFormat("yyyyMMdd").format(new Date());
|
||||
// File file = new File(ctxPath + File.separator + bizPath + File.separator + nowday);
|
||||
// if (!file.exists()) {
|
||||
// file.mkdirs();// 创建文件根目录
|
||||
// }
|
||||
// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
// MultipartFile mf = multipartRequest.getFile("file");// 获取上传文件对象
|
||||
// String orgName = mf.getOriginalFilename();// 获取文件名
|
||||
// fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
// String savePath = file.getPath() + File.separator + fileName;
|
||||
// File savefile = new File(savePath);
|
||||
// FileCopyUtils.copy(mf.getBytes(), savefile);
|
||||
// String dbpath = bizPath + File.separator + nowday + File.separator + fileName;
|
||||
// if (dbpath.contains("\\")) {
|
||||
// dbpath = dbpath.replace("\\", "/");
|
||||
// }
|
||||
// result.setMessage(dbpath);
|
||||
// result.setSuccess(true);
|
||||
// } catch (IOException e) {
|
||||
// result.setSuccess(false);
|
||||
// result.setMessage(e.getMessage());
|
||||
// log.error(e.getMessage(), e);
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 预览图片&下载文件
|
||||
* 请求地址:http://localhost:8080/common/static/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
@GetMapping(value = "/static/**")
|
||||
public void view(HttpServletRequest request, HttpServletResponse response) {
|
||||
// ISO-8859-1 ==> UTF-8 进行编码转换
|
||||
String imgPath = extractPathFromPattern(request);
|
||||
if(oConvertUtils.isEmpty(imgPath) || CommonConstant.STRING_NULL.equals(imgPath)){
|
||||
return;
|
||||
}
|
||||
// 其余处理略
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream = null;
|
||||
try {
|
||||
imgPath = imgPath.replace("..", "").replace("../","");
|
||||
if (imgPath.endsWith(SymbolConstant.COMMA)) {
|
||||
imgPath = imgPath.substring(0, imgPath.length() - 1);
|
||||
}
|
||||
//update-begin---author:liusq ---date:20230912 for:检查下载文件类型--------------
|
||||
SsrfFileTypeFilter.checkDownloadFileType(imgPath);
|
||||
//update-end---author:liusq ---date:20230912 for:检查下载文件类型--------------
|
||||
|
||||
String filePath = uploadpath + File.separator + imgPath;
|
||||
File file = new File(filePath);
|
||||
if(!file.exists()){
|
||||
response.setStatus(404);
|
||||
log.error("文件["+imgPath+"]不存在..");
|
||||
return;
|
||||
//throw new RuntimeException();
|
||||
}
|
||||
// 设置强制下载不打开
|
||||
response.setContentType("application/force-download");
|
||||
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
|
||||
inputStream = new BufferedInputStream(new FileInputStream(filePath));
|
||||
outputStream = response.getOutputStream();
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = inputStream.read(buf)) > 0) {
|
||||
outputStream.write(buf, 0, len);
|
||||
}
|
||||
response.flushBuffer();
|
||||
} catch (IOException e) {
|
||||
log.error("预览文件失败" + e.getMessage());
|
||||
response.setStatus(404);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 下载文件
|
||||
// * 请求地址:http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
|
||||
// *
|
||||
// * @param request
|
||||
// * @param response
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @GetMapping(value = "/download/**")
|
||||
// public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
// // ISO-8859-1 ==> UTF-8 进行编码转换
|
||||
// String filePath = extractPathFromPattern(request);
|
||||
// // 其余处理略
|
||||
// InputStream inputStream = null;
|
||||
// OutputStream outputStream = null;
|
||||
// try {
|
||||
// filePath = filePath.replace("..", "");
|
||||
// if (filePath.endsWith(",")) {
|
||||
// filePath = filePath.substring(0, filePath.length() - 1);
|
||||
// }
|
||||
// String localPath = uploadpath;
|
||||
// String downloadFilePath = localPath + File.separator + filePath;
|
||||
// File file = new File(downloadFilePath);
|
||||
// if (file.exists()) {
|
||||
// response.setContentType("application/force-download");// 设置强制下载不打开
|
||||
// response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
|
||||
// inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||
// outputStream = response.getOutputStream();
|
||||
// byte[] buf = new byte[1024];
|
||||
// int len;
|
||||
// while ((len = inputStream.read(buf)) > 0) {
|
||||
// outputStream.write(buf, 0, len);
|
||||
// }
|
||||
// response.flushBuffer();
|
||||
// }
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// log.info("文件下载失败" + e.getMessage());
|
||||
// // e.printStackTrace();
|
||||
// } finally {
|
||||
// if (inputStream != null) {
|
||||
// try {
|
||||
// inputStream.close();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// if (outputStream != null) {
|
||||
// try {
|
||||
// outputStream.close();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* @功能:pdf预览Iframe
|
||||
* @param modelAndView
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/pdf/pdfPreviewIframe")
|
||||
public ModelAndView pdfPreviewIframe(ModelAndView modelAndView) {
|
||||
modelAndView.setViewName("pdfPreviewIframe");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把指定URL后的字符串全部截断当成参数
|
||||
* 这么做是为了防止URL中包含中文或者特殊字符(/等)时,匹配不了的问题
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
private static String extractPathFromPattern(final HttpServletRequest request) {
|
||||
String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
|
||||
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||
return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.system.model.DuplicateCheckVo;
|
||||
import org.jeecg.modules.system.service.ISysDictService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @Title: DuplicateCheckAction
|
||||
* @Description: 重复校验工具
|
||||
* @Author 张代浩
|
||||
* @Date 2019-03-25
|
||||
* @Version V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/duplicate")
|
||||
@Tag(name="重复校验")
|
||||
public class DuplicateCheckController {
|
||||
|
||||
@Autowired
|
||||
ISysDictService sysDictService;
|
||||
|
||||
/**
|
||||
* 校验数据是否在系统中是否存在
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/check", method = RequestMethod.GET)
|
||||
@Operation(summary = "重复校验接口")
|
||||
public Result<String> doDuplicateCheck(DuplicateCheckVo duplicateCheckVo, HttpServletRequest request) {
|
||||
log.debug("----duplicate check------:"+ duplicateCheckVo.toString());
|
||||
|
||||
// 1.填值为空,直接返回
|
||||
if(StringUtils.isEmpty(duplicateCheckVo.getFieldVal())){
|
||||
Result rs = new Result();
|
||||
rs.setCode(500);
|
||||
rs.setSuccess(true);
|
||||
rs.setMessage("数据为空,不作处理!");
|
||||
return rs;
|
||||
}
|
||||
|
||||
// 2.返回结果
|
||||
if (sysDictService.duplicateCheckData(duplicateCheckVo)) {
|
||||
// 该值可用
|
||||
return Result.ok("该值可用!");
|
||||
} else {
|
||||
// 该值不可用
|
||||
log.info("该值不可用,系统中已存在!");
|
||||
return Result.error("该值不可用,系统中已存在!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,828 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyuncs.exceptions.ClientException;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.constant.enums.DySmsEnum;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.*;
|
||||
import org.jeecg.common.util.encryption.EncryptedString;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||
import org.jeecg.modules.system.entity.SysTenant;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.model.SysLoginModel;
|
||||
import org.jeecg.modules.system.service.*;
|
||||
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
|
||||
import org.jeecg.modules.system.util.RandImageUtil;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author scott
|
||||
* @since 2018-12-17
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys")
|
||||
@Tag(name="用户登录")
|
||||
@Slf4j
|
||||
public class LoginController {
|
||||
@Autowired
|
||||
private ISysUserService sysUserService;
|
||||
@Autowired
|
||||
private ISysPermissionService sysPermissionService;
|
||||
@Autowired
|
||||
private SysBaseApiImpl sysBaseApi;
|
||||
@Autowired
|
||||
private ISysLogService logService;
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
@Autowired
|
||||
private ISysDepartService sysDepartService;
|
||||
@Autowired
|
||||
private ISysDictService sysDictService;
|
||||
@Resource
|
||||
private BaseCommonService baseCommonService;
|
||||
@Autowired
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
|
||||
private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
|
||||
|
||||
@Operation(summary = "登录接口")
|
||||
@RequestMapping(value = "/login", method = RequestMethod.POST)
|
||||
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel, HttpServletRequest request){
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String username = sysLoginModel.getUsername();
|
||||
String password = sysLoginModel.getPassword();
|
||||
if(isLoginFailOvertimes(username)){
|
||||
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||
}
|
||||
|
||||
// step.1 验证码check
|
||||
String captcha = sysLoginModel.getCaptcha();
|
||||
if(captcha==null){
|
||||
result.error500("验证码无效");
|
||||
return result;
|
||||
}
|
||||
String lowerCaseCaptcha = captcha.toLowerCase();
|
||||
// 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可
|
||||
String origin = lowerCaseCaptcha+sysLoginModel.getCheckKey()+jeecgBaseConfig.getSignatureSecret();
|
||||
String realKey = Md5Util.md5Encode(origin, "utf-8");
|
||||
Object checkCode = redisUtil.get(realKey);
|
||||
//当进入登录页时,有一定几率出现验证码错误 #1714
|
||||
if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) {
|
||||
log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);
|
||||
result.error500("验证码错误");
|
||||
// 改成特殊的code 便于前端判断
|
||||
result.setCode(HttpStatus.PRECONDITION_FAILED.value());
|
||||
return result;
|
||||
}
|
||||
|
||||
// step.2 校验用户是否存在且有效
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysUser::getUsername,username);
|
||||
SysUser sysUser = sysUserService.getOne(queryWrapper);
|
||||
result = sysUserService.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// step.3 校验用户名或密码是否正确
|
||||
String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
|
||||
String syspassword = sysUser.getPassword();
|
||||
if (!syspassword.equals(userpassword)) {
|
||||
addLoginFailOvertimes(username);
|
||||
result.error500("用户名或密码错误");
|
||||
return result;
|
||||
}
|
||||
|
||||
// step.4 登录成功获取用户信息
|
||||
userInfo(sysUser, result, request);
|
||||
|
||||
// step.5 登录成功删除验证码
|
||||
redisUtil.del(realKey);
|
||||
redisUtil.del(CommonConstant.LOGIN_FAIL + username);
|
||||
|
||||
// step.6 记录用户登录日志
|
||||
LoginUser loginUser = new LoginUser();
|
||||
BeanUtils.copyProperties(sysUser, loginUser);
|
||||
baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【vue3专用】获取用户信息
|
||||
*/
|
||||
@GetMapping("/user/getUserInfo")
|
||||
public Result<JSONObject> getUserInfo(HttpServletRequest request){
|
||||
long start = System.currentTimeMillis();
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
if(oConvertUtils.isNotEmpty(username)) {
|
||||
// 根据用户名查询用户信息
|
||||
SysUser sysUser = sysUserService.getUserByName(username);
|
||||
JSONObject obj=new JSONObject();
|
||||
log.info("1 获取用户信息耗时(用户基础信息)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
//update-begin---author:scott ---date:2022-06-20 for:vue3前端,支持自定义首页-----------
|
||||
String vue3Version = request.getHeader(CommonConstant.VERSION);
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
|
||||
SysRoleIndex roleIndex = sysUserService.getDynamicIndexByUserRole(username, vue3Version);
|
||||
if (oConvertUtils.isNotEmpty(vue3Version) && roleIndex != null && oConvertUtils.isNotEmpty(roleIndex.getUrl())) {
|
||||
String homePath = roleIndex.getUrl();
|
||||
if (!homePath.startsWith(SymbolConstant.SINGLE_SLASH)) {
|
||||
homePath = SymbolConstant.SINGLE_SLASH + homePath;
|
||||
}
|
||||
sysUser.setHomePath(homePath);
|
||||
}
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
|
||||
//update-end---author:scott ---date::2022-06-20 for:vue3前端,支持自定义首页--------------
|
||||
log.info("2 获取用户信息耗时 (首页面配置)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
obj.put("userInfo",sysUser);
|
||||
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
|
||||
log.info("3 获取用户信息耗时 (字典数据)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
result.setResult(obj);
|
||||
result.success("");
|
||||
}
|
||||
log.info("end 获取用户信息耗时 " + (System.currentTimeMillis() - start) + "毫秒");
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/logout")
|
||||
public Result<Object> logout(HttpServletRequest request,HttpServletResponse response) {
|
||||
//用户退出逻辑
|
||||
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||
if(oConvertUtils.isEmpty(token)) {
|
||||
return Result.error("退出登录失败!");
|
||||
}
|
||||
String username = JwtUtil.getUsername(token);
|
||||
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||
if(sysUser!=null) {
|
||||
//update-begin--Author:wangshuai Date:20200714 for:登出日志没有记录人员
|
||||
baseCommonService.addLog("用户名: "+sysUser.getRealname()+",退出成功!", CommonConstant.LOG_TYPE_1, null,sysUser);
|
||||
//update-end--Author:wangshuai Date:20200714 for:登出日志没有记录人员
|
||||
log.info(" 用户名: "+sysUser.getRealname()+",退出成功! ");
|
||||
//清空用户登录Token缓存
|
||||
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
|
||||
//清空用户登录Shiro权限缓存
|
||||
redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
|
||||
//清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username>
|
||||
redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
|
||||
//调用shiro的logout
|
||||
SecurityUtils.getSubject().logout();
|
||||
return Result.ok("退出登录成功!");
|
||||
}else {
|
||||
return Result.error("Token无效!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取访问量
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("loginfo")
|
||||
public Result<JSONObject> loginfo() {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
JSONObject obj = new JSONObject();
|
||||
//update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
// 获取一天的开始和结束时间
|
||||
Calendar calendar = new GregorianCalendar();
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
Date dayStart = calendar.getTime();
|
||||
calendar.add(Calendar.DATE, 1);
|
||||
Date dayEnd = calendar.getTime();
|
||||
// 获取系统访问记录
|
||||
Long totalVisitCount = logService.findTotalVisitCount();
|
||||
obj.put("totalVisitCount", totalVisitCount);
|
||||
Long todayVisitCount = logService.findTodayVisitCount(dayStart,dayEnd);
|
||||
obj.put("todayVisitCount", todayVisitCount);
|
||||
Long todayIp = logService.findTodayIp(dayStart,dayEnd);
|
||||
//update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
obj.put("todayIp", todayIp);
|
||||
result.setResult(obj);
|
||||
result.success("登录成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取访问量
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/visitInfo")
|
||||
public Result<List<Map<String,Object>>> visitInfo() {
|
||||
Result<List<Map<String,Object>>> result = new Result<List<Map<String,Object>>>();
|
||||
Calendar calendar = new GregorianCalendar();
|
||||
calendar.set(Calendar.HOUR_OF_DAY,0);
|
||||
calendar.set(Calendar.MINUTE,0);
|
||||
calendar.set(Calendar.SECOND,0);
|
||||
calendar.set(Calendar.MILLISECOND,0);
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
Date dayEnd = calendar.getTime();
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -7);
|
||||
Date dayStart = calendar.getTime();
|
||||
List<Map<String,Object>> list = logService.findVisitCount(dayStart, dayEnd);
|
||||
result.setResult(oConvertUtils.toLowerCasePageList(list));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 登陆成功选择用户当前部门
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/selectDepart", method = RequestMethod.PUT)
|
||||
public Result<JSONObject> selectDepart(@RequestBody SysUser user) {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String username = user.getUsername();
|
||||
if(oConvertUtils.isEmpty(username)) {
|
||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||
username = sysUser.getUsername();
|
||||
}
|
||||
|
||||
//获取登录部门
|
||||
String orgCode= user.getOrgCode();
|
||||
//获取登录租户
|
||||
Integer tenantId = user.getLoginTenantId();
|
||||
//设置用户登录部门和登录租户
|
||||
this.sysUserService.updateUserDepart(username, orgCode,tenantId);
|
||||
SysUser sysUser = sysUserService.getUserByName(username);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("userInfo", sysUser);
|
||||
result.setResult(obj);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 短信登录接口
|
||||
*
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/sms")
|
||||
public Result<String> sms(@RequestBody JSONObject jsonObject,HttpServletRequest request) {
|
||||
Result<String> result = new Result<String>();
|
||||
String clientIp = IpUtils.getIpAddr(request);
|
||||
String mobile = jsonObject.get("mobile").toString();
|
||||
//手机号模式 登录模式: "2" 注册模式: "1"
|
||||
String smsmode=jsonObject.get("smsmode").toString();
|
||||
log.info("-------- IP:{}, 手机号:{},获取绑定验证码", clientIp, mobile);
|
||||
|
||||
if(oConvertUtils.isEmpty(mobile)){
|
||||
result.setMessage("手机号不允许为空!");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+mobile;
|
||||
Object object = redisUtil.get(redisKey);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
|
||||
if (object != null) {
|
||||
result.setMessage("验证码10分钟内,仍然有效!");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
//增加 check防止恶意刷短信接口
|
||||
if(!DySmsLimit.canSendSms(clientIp)){
|
||||
log.warn("--------[警告] IP地址:{}, 短信接口请求太多-------", clientIp);
|
||||
result.setMessage("短信接口请求太多,请稍后再试!");
|
||||
result.setCode(CommonConstant.PHONE_SMS_FAIL_CODE);
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
//随机数
|
||||
String captcha = RandomUtil.randomNumbers(6);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("code", captcha);
|
||||
try {
|
||||
boolean b = false;
|
||||
//注册模板
|
||||
if (CommonConstant.SMS_TPL_TYPE_1.equals(smsmode)) {
|
||||
SysUser sysUser = sysUserService.getUserByPhone(mobile);
|
||||
if(sysUser!=null) {
|
||||
result.error500(" 手机号已经注册,请直接登录!");
|
||||
baseCommonService.addLog("手机号已经注册,请直接登录!", CommonConstant.LOG_TYPE_1, null);
|
||||
return result;
|
||||
}
|
||||
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.REGISTER_TEMPLATE_CODE);
|
||||
}else {
|
||||
//登录模式,校验用户有效性
|
||||
SysUser sysUser = sysUserService.getUserByPhone(mobile);
|
||||
result = sysUserService.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
String message = result.getMessage();
|
||||
String userNotExist="该用户不存在,请注册";
|
||||
if(userNotExist.equals(message)){
|
||||
result.error500("该用户不存在或未绑定手机号");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* smsmode 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板
|
||||
*/
|
||||
if (CommonConstant.SMS_TPL_TYPE_0.equals(smsmode)) {
|
||||
//登录模板
|
||||
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.LOGIN_TEMPLATE_CODE);
|
||||
} else if(CommonConstant.SMS_TPL_TYPE_2.equals(smsmode)) {
|
||||
//忘记密码模板
|
||||
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
if (b == false) {
|
||||
result.setMessage("短信验证码发送失败,请稍后重试");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
//验证码10分钟内有效
|
||||
redisUtil.set(redisKey, captcha, 600);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
|
||||
//update-begin--Author:scott Date:20190812 for:issues#391
|
||||
//result.setResult(captcha);
|
||||
//update-end--Author:scott Date:20190812 for:issues#391
|
||||
result.setSuccess(true);
|
||||
|
||||
} catch (ClientException e) {
|
||||
e.printStackTrace();
|
||||
result.error500(" 短信接口未配置,请联系管理员!");
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 手机号登录接口
|
||||
*
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary ="手机号登录接口")
|
||||
@PostMapping("/phoneLogin")
|
||||
public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String phone = jsonObject.getString("mobile");
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
if(isLoginFailOvertimes(phone)){
|
||||
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||
}
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
//校验用户有效性
|
||||
SysUser sysUser = sysUserService.getUserByPhone(phone);
|
||||
result = sysUserService.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
String smscode = jsonObject.getString("captcha");
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
|
||||
Object code = redisUtil.get(redisKey);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
|
||||
if (!smscode.equals(code)) {
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
addLoginFailOvertimes(phone);
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
return Result.error("手机验证码错误");
|
||||
}
|
||||
//用户信息
|
||||
userInfo(sysUser, result, request);
|
||||
//添加日志
|
||||
baseCommonService.addLog("用户名: " + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*
|
||||
* @param sysUser
|
||||
* @param result
|
||||
* @return
|
||||
*/
|
||||
private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result, HttpServletRequest request) {
|
||||
String username = sysUser.getUsername();
|
||||
String syspassword = sysUser.getPassword();
|
||||
// 获取用户部门信息
|
||||
JSONObject obj = new JSONObject(new LinkedHashMap<>());
|
||||
|
||||
//1.生成token
|
||||
String token = JwtUtil.sign(username, syspassword);
|
||||
// 设置token缓存有效时间
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
||||
obj.put("token", token);
|
||||
|
||||
//2.设置登录租户
|
||||
Result<JSONObject> loginTenantError = sysUserService.setLoginTenant(sysUser, obj, username,result);
|
||||
if (loginTenantError != null) {
|
||||
return loginTenantError;
|
||||
}
|
||||
|
||||
//3.设置登录用户信息
|
||||
obj.put("userInfo", sysUser);
|
||||
|
||||
//4.设置登录部门
|
||||
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
|
||||
obj.put("departs", departs);
|
||||
if (departs == null || departs.size() == 0) {
|
||||
obj.put("multi_depart", 0);
|
||||
} else if (departs.size() == 1) {
|
||||
sysUserService.updateUserDepart(username, departs.get(0).getOrgCode(),null);
|
||||
obj.put("multi_depart", 1);
|
||||
} else {
|
||||
//查询当前是否有登录部门
|
||||
// update-begin--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
|
||||
SysUser sysUserById = sysUserService.getById(sysUser.getId());
|
||||
if(oConvertUtils.isEmpty(sysUserById.getOrgCode())){
|
||||
sysUserService.updateUserDepart(username, departs.get(0).getOrgCode(),null);
|
||||
}
|
||||
// update-end--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
|
||||
obj.put("multi_depart", 2);
|
||||
}
|
||||
|
||||
//update-begin---author:scott ---date:2024-01-05 for:【QQYUN-7802】前端在登录时加载了两次数据字典,建议优化下,避免数据字典太多时可能产生的性能问题 #956---
|
||||
// login接口,在vue3前端下不加载字典数据,vue2下加载字典
|
||||
String vue3Version = request.getHeader(CommonConstant.VERSION);
|
||||
if(oConvertUtils.isEmpty(vue3Version)){
|
||||
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
|
||||
}
|
||||
//end-begin---author:scott ---date:2024-01-05 for:【QQYUN-7802】前端在登录时加载了两次数据字典,建议优化下,避免数据字典太多时可能产生的性能问题 #956---
|
||||
|
||||
result.setResult(obj);
|
||||
result.success("登录成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取加密字符串
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/getEncryptedString")
|
||||
public Result<Map<String,String>> getEncryptedString(){
|
||||
Result<Map<String,String>> result = new Result<Map<String,String>>();
|
||||
Map<String,String> map = new HashMap(5);
|
||||
map.put("key", EncryptedString.key);
|
||||
map.put("iv",EncryptedString.iv);
|
||||
result.setResult(map);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台生成图形验证码 :有效
|
||||
* @param response
|
||||
* @param key
|
||||
*/
|
||||
@Operation(summary ="获取验证码")
|
||||
@GetMapping(value = "/randomImage/{key}")
|
||||
public Result<String> randomImage(HttpServletResponse response,@PathVariable("key") String key){
|
||||
Result<String> res = new Result<String>();
|
||||
try {
|
||||
//生成验证码
|
||||
String code = RandomUtil.randomString(BASE_CHECK_CODES,4);
|
||||
//存到redis中
|
||||
String lowerCaseCode = code.toLowerCase();
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可
|
||||
String origin = lowerCaseCode+key+jeecgBaseConfig.getSignatureSecret();
|
||||
String realKey = Md5Util.md5Encode(origin, "utf-8");
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
|
||||
redisUtil.set(realKey, lowerCaseCode, 60);
|
||||
log.info("获取验证码,Redis key = {},checkCode = {}", realKey, code);
|
||||
//返回前端
|
||||
String base64 = RandImageUtil.generate(code);
|
||||
res.setSuccess(true);
|
||||
res.setResult(base64);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
res.error500("获取验证码失败,请检查redis配置!");
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换菜单表为vue3的表
|
||||
*/
|
||||
@RequiresRoles({"admin"})
|
||||
@GetMapping(value = "/switchVue3Menu")
|
||||
public Result<String> switchVue3Menu(HttpServletResponse response) {
|
||||
Result<String> res = new Result<String>();
|
||||
sysPermissionService.switchVue3Menu();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* app登录
|
||||
* @param sysLoginModel
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@RequestMapping(value = "/mLogin", method = RequestMethod.POST)
|
||||
public Result<JSONObject> mLogin(@RequestBody SysLoginModel sysLoginModel) throws Exception {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String username = sysLoginModel.getUsername();
|
||||
String password = sysLoginModel.getPassword();
|
||||
JSONObject obj = new JSONObject();
|
||||
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
if(isLoginFailOvertimes(username)){
|
||||
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||
}
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
//1. 校验用户是否有效
|
||||
SysUser sysUser = sysUserService.getUserByName(username);
|
||||
result = sysUserService.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//2. 校验用户名或密码是否正确
|
||||
String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
|
||||
String syspassword = sysUser.getPassword();
|
||||
if (!syspassword.equals(userpassword)) {
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
addLoginFailOvertimes(username);
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
result.error500("用户名或密码错误");
|
||||
return result;
|
||||
}
|
||||
|
||||
//3.设置登录部门
|
||||
String orgCode = sysUser.getOrgCode();
|
||||
if(oConvertUtils.isEmpty(orgCode)) {
|
||||
//如果当前用户无选择部门 查看部门关联信息
|
||||
|
||||
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
|
||||
//update-begin-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
|
||||
if (departs == null || departs.size() == 0) {
|
||||
/*result.error500("用户暂未归属部门,不可登录!");
|
||||
|
||||
return result;*/
|
||||
}else{
|
||||
orgCode = departs.get(0).getOrgCode();
|
||||
sysUser.setOrgCode(orgCode);
|
||||
this.sysUserService.updateUserDepart(username, orgCode,null);
|
||||
}
|
||||
//update-end-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
|
||||
}
|
||||
|
||||
//4. 设置登录租户
|
||||
Result<JSONObject> loginTenantError = sysUserService.setLoginTenant(sysUser, obj, username, result);
|
||||
if (loginTenantError != null) {
|
||||
return loginTenantError;
|
||||
}
|
||||
|
||||
//5. 设置登录用户信息
|
||||
obj.put("userInfo", sysUser);
|
||||
|
||||
//6. 生成token
|
||||
String token = JwtUtil.sign(username, syspassword);
|
||||
// 设置超时时间
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
|
||||
|
||||
//token 信息
|
||||
obj.put("token", token);
|
||||
result.setResult(obj);
|
||||
result.setSuccess(true);
|
||||
result.setCode(200);
|
||||
baseCommonService.addLog("用户名: " + username + ",登录成功[移动端]!", CommonConstant.LOG_TYPE_1, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 图形验证码
|
||||
* @param sysLoginModel
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/checkCaptcha", method = RequestMethod.POST)
|
||||
public Result<?> checkCaptcha(@RequestBody SysLoginModel sysLoginModel){
|
||||
String captcha = sysLoginModel.getCaptcha();
|
||||
String checkKey = sysLoginModel.getCheckKey();
|
||||
if(captcha==null){
|
||||
return Result.error("验证码无效");
|
||||
}
|
||||
String lowerCaseCaptcha = captcha.toLowerCase();
|
||||
String realKey = Md5Util.md5Encode(lowerCaseCaptcha+checkKey, "utf-8");
|
||||
Object checkCode = redisUtil.get(realKey);
|
||||
if(checkCode==null || !checkCode.equals(lowerCaseCaptcha)) {
|
||||
return Result.error("验证码错误");
|
||||
}
|
||||
return Result.ok();
|
||||
}
|
||||
/**
|
||||
* 登录二维码
|
||||
*/
|
||||
@Operation(summary = "登录二维码")
|
||||
@GetMapping("/getLoginQrcode")
|
||||
public Result<?> getLoginQrcode() {
|
||||
String qrcodeId = CommonConstant.LOGIN_QRCODE_PRE+IdWorker.getIdStr();
|
||||
//定义二维码参数
|
||||
Map params = new HashMap(5);
|
||||
params.put("qrcodeId", qrcodeId);
|
||||
//存放二维码唯一标识30秒有效
|
||||
redisUtil.set(CommonConstant.LOGIN_QRCODE + qrcodeId, qrcodeId, 30);
|
||||
return Result.OK(params);
|
||||
}
|
||||
/**
|
||||
* 扫码二维码
|
||||
*/
|
||||
@Operation(summary = "扫码登录二维码")
|
||||
@PostMapping("/scanLoginQrcode")
|
||||
public Result<?> scanLoginQrcode(@RequestParam String qrcodeId, @RequestParam String token) {
|
||||
Object check = redisUtil.get(CommonConstant.LOGIN_QRCODE + qrcodeId);
|
||||
if (oConvertUtils.isNotEmpty(check)) {
|
||||
//存放token给前台读取
|
||||
redisUtil.set(CommonConstant.LOGIN_QRCODE_TOKEN+qrcodeId, token, 60);
|
||||
} else {
|
||||
return Result.error("二维码已过期,请刷新后重试");
|
||||
}
|
||||
return Result.OK("扫码成功");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户扫码后保存的token
|
||||
*/
|
||||
@Operation(summary = "获取用户扫码后保存的token")
|
||||
@GetMapping("/getQrcodeToken")
|
||||
public Result getQrcodeToken(@RequestParam String qrcodeId) {
|
||||
Object token = redisUtil.get(CommonConstant.LOGIN_QRCODE_TOKEN + qrcodeId);
|
||||
Map result = new HashMap(5);
|
||||
Object qrcodeIdExpire = redisUtil.get(CommonConstant.LOGIN_QRCODE + qrcodeId);
|
||||
if (oConvertUtils.isEmpty(qrcodeIdExpire)) {
|
||||
//二维码过期通知前台刷新
|
||||
result.put("token", "-2");
|
||||
return Result.OK(result);
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(token)) {
|
||||
result.put("success", true);
|
||||
result.put("token", token);
|
||||
} else {
|
||||
result.put("token", "-1");
|
||||
}
|
||||
return Result.OK(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录失败超出次数5 返回true
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
private boolean isLoginFailOvertimes(String username){
|
||||
String key = CommonConstant.LOGIN_FAIL + username;
|
||||
Object failTime = redisUtil.get(key);
|
||||
if(failTime!=null){
|
||||
Integer val = Integer.parseInt(failTime.toString());
|
||||
if(val>5){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录失败次数
|
||||
* @param username
|
||||
*/
|
||||
private void addLoginFailOvertimes(String username){
|
||||
String key = CommonConstant.LOGIN_FAIL + username;
|
||||
Object failTime = redisUtil.get(key);
|
||||
Integer val = 0;
|
||||
if(failTime!=null){
|
||||
val = Integer.parseInt(failTime.toString());
|
||||
}
|
||||
// 10分钟,一分钟为60s
|
||||
redisUtil.set(key, ++val, 600);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信验证码接口(修改密码)
|
||||
*
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/sendChangePwdSms")
|
||||
public Result<String> sendSms(@RequestBody JSONObject jsonObject) {
|
||||
Result<String> result = new Result<>();
|
||||
String mobile = jsonObject.get("mobile").toString();
|
||||
if (oConvertUtils.isEmpty(mobile)) {
|
||||
result.setMessage("手机号不允许为空!");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
String username = sysUser.getUsername();
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysUser::getUsername, username).eq(SysUser::getPhone, mobile);
|
||||
SysUser user = sysUserService.getOne(query);
|
||||
if (null == user) {
|
||||
return Result.error("当前登录用户和绑定的手机号不匹配,无法修改密码!");
|
||||
}
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + mobile;
|
||||
Object object = redisUtil.get(redisKey);
|
||||
if (object != null) {
|
||||
result.setMessage("验证码10分钟内,仍然有效!");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
//随机数
|
||||
String captcha = RandomUtil.randomNumbers(6);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("code", captcha);
|
||||
try {
|
||||
boolean b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.CHANGE_PASSWORD_TEMPLATE_CODE);
|
||||
if (!b) {
|
||||
result.setMessage("短信验证码发送失败,请稍后重试");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
//验证码5分钟内有效
|
||||
redisUtil.set(redisKey, captcha, 300);
|
||||
result.setSuccess(true);
|
||||
} catch (ClientException e) {
|
||||
e.printStackTrace();
|
||||
result.error500(" 短信接口未配置,请联系管理员!");
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 图形验证码
|
||||
* @param sysLoginModel
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/smsCheckCaptcha", method = RequestMethod.POST)
|
||||
public Result<?> smsCheckCaptcha(@RequestBody SysLoginModel sysLoginModel, HttpServletRequest request){
|
||||
String captcha = sysLoginModel.getCaptcha();
|
||||
String checkKey = sysLoginModel.getCheckKey();
|
||||
if(captcha==null){
|
||||
return Result.error("验证码无效");
|
||||
}
|
||||
String lowerCaseCaptcha = captcha.toLowerCase();
|
||||
String realKey = Md5Util.md5Encode(lowerCaseCaptcha+checkKey+jeecgBaseConfig.getSignatureSecret(), "utf-8");
|
||||
Object checkCode = redisUtil.get(realKey);
|
||||
if(checkCode==null || !checkCode.equals(lowerCaseCaptcha)) {
|
||||
return Result.error("验证码错误");
|
||||
}
|
||||
String clientIp = IpUtils.getIpAddr(request);
|
||||
//清空短信记录数量
|
||||
DySmsLimit.clearSendSmsCount(clientIp);
|
||||
redisUtil.removeAll(realKey);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,643 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.jeecg.dingtalk.api.core.response.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.CommonSendStatus;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.*;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.message.enums.RangeDateEnum;
|
||||
import org.jeecg.modules.message.websocket.WebSocket;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncement;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
||||
import org.jeecg.modules.system.service.ISysAnnouncementService;
|
||||
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
|
||||
import org.jeecg.modules.system.util.XssUtils;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jeecg.common.constant.CommonConstant.ANNOUNCEMENT_SEND_STATUS_1;
|
||||
|
||||
/**
|
||||
* @Title: Controller
|
||||
* @Description: 系统通告表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-01-02
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/annountCement")
|
||||
@Slf4j
|
||||
public class SysAnnouncementController {
|
||||
@Autowired
|
||||
private ISysAnnouncementService sysAnnouncementService;
|
||||
@Autowired
|
||||
private ISysAnnouncementSendService sysAnnouncementSendService;
|
||||
@Resource
|
||||
private WebSocket webSocket;
|
||||
@Autowired
|
||||
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||
@Autowired
|
||||
ThirdAppDingtalkServiceImpl dingtalkService;
|
||||
@Autowired
|
||||
private SysBaseApiImpl sysBaseApi;
|
||||
@Autowired
|
||||
@Lazy
|
||||
private RedisUtil redisUtil;
|
||||
@Autowired
|
||||
public RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* QQYUN-5072【性能优化】线上通知消息打开有点慢
|
||||
*/
|
||||
public static ExecutorService cachedThreadPool = new ThreadPoolExecutor(0, 1024,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
|
||||
public static ExecutorService completeNoteThreadPool = new ThreadPoolExecutor(0, 1024,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
* @param sysAnnouncement
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
public Result<IPage<SysAnnouncement>> queryPageList(SysAnnouncement sysAnnouncement,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysAnnouncement.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
Result<IPage<SysAnnouncement>> result = new Result<IPage<SysAnnouncement>>();
|
||||
sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
QueryWrapper<SysAnnouncement> queryWrapper = QueryGenerator.initQueryWrapper(sysAnnouncement, req.getParameterMap());
|
||||
Page<SysAnnouncement> page = new Page<SysAnnouncement>(pageNo,pageSize);
|
||||
IPage<SysAnnouncement> pageList = sysAnnouncementService.page(page, queryWrapper);
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
* @param sysAnnouncement
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||
public Result<SysAnnouncement> add(@RequestBody SysAnnouncement sysAnnouncement) {
|
||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||
try {
|
||||
// update-begin-author:liusq date:20210804 for:标题处理xss攻击的问题
|
||||
String title = XssUtils.scriptXss(sysAnnouncement.getTitile());
|
||||
sysAnnouncement.setTitile(title);
|
||||
// update-end-author:liusq date:20210804 for:标题处理xss攻击的问题
|
||||
sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
//未发布
|
||||
sysAnnouncement.setSendStatus(CommonSendStatus.UNPUBLISHED_STATUS_0);
|
||||
sysAnnouncementService.saveAnnouncement(sysAnnouncement);
|
||||
result.success("添加成功!");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param sysAnnouncement
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<SysAnnouncement> eidt(@RequestBody SysAnnouncement sysAnnouncement) {
|
||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||
SysAnnouncement sysAnnouncementEntity = sysAnnouncementService.getById(sysAnnouncement.getId());
|
||||
if(sysAnnouncementEntity==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
// update-begin-author:liusq date:20210804 for:标题处理xss攻击的问题
|
||||
String title = XssUtils.scriptXss(sysAnnouncement.getTitile());
|
||||
sysAnnouncement.setTitile(title);
|
||||
// update-end-author:liusq date:20210804 for:标题处理xss攻击的问题
|
||||
boolean ok = sysAnnouncementService.upDateAnnouncement(sysAnnouncement);
|
||||
//TODO 返回false说明什么?
|
||||
if(ok) {
|
||||
result.success("修改成功!");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
|
||||
public Result<SysAnnouncement> delete(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||
SysAnnouncement sysAnnouncement = sysAnnouncementService.getById(id);
|
||||
if(sysAnnouncement==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_1.toString());
|
||||
boolean ok = sysAnnouncementService.updateById(sysAnnouncement);
|
||||
if(ok) {
|
||||
result.success("删除成功!");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
|
||||
public Result<SysAnnouncement> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||
if(ids==null || "".equals(ids.trim())) {
|
||||
result.error500("参数不识别!");
|
||||
}else {
|
||||
String[] id = ids.split(",");
|
||||
for(int i=0;i<id.length;i++) {
|
||||
SysAnnouncement announcement = sysAnnouncementService.getById(id[i]);
|
||||
announcement.setDelFlag(CommonConstant.DEL_FLAG_1.toString());
|
||||
sysAnnouncementService.updateById(announcement);
|
||||
}
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryById", method = RequestMethod.GET)
|
||||
public Result<SysAnnouncement> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||
SysAnnouncement sysAnnouncement = sysAnnouncementService.getById(id);
|
||||
if(sysAnnouncement==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
result.setResult(sysAnnouncement);
|
||||
result.setSuccess(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新发布操作
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/doReleaseData", method = RequestMethod.GET)
|
||||
public Result<SysAnnouncement> doReleaseData(@RequestParam(name="id",required=true) String id, HttpServletRequest request) {
|
||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||
SysAnnouncement sysAnnouncement = sysAnnouncementService.getById(id);
|
||||
if(sysAnnouncement==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
//发布中
|
||||
sysAnnouncement.setSendStatus(CommonSendStatus.PUBLISHED_STATUS_1);
|
||||
sysAnnouncement.setSendTime(new Date());
|
||||
String currentUserName = JwtUtil.getUserNameByToken(request);
|
||||
sysAnnouncement.setSender(currentUserName);
|
||||
boolean ok = sysAnnouncementService.updateById(sysAnnouncement);
|
||||
if(ok) {
|
||||
result.success("系统通知推送成功");
|
||||
if(sysAnnouncement.getMsgType().equals(CommonConstant.MSG_TYPE_ALL)) {
|
||||
// 补全公告和用户之前的关系
|
||||
sysAnnouncementService.batchInsertSysAnnouncementSend(sysAnnouncement.getId(), sysAnnouncement.getTenantId());
|
||||
|
||||
// 推送websocket通知
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
|
||||
obj.put(WebsocketConst.MSG_ID, sysAnnouncement.getId());
|
||||
obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
|
||||
webSocket.sendMessage(obj.toJSONString());
|
||||
}else {
|
||||
// 2.插入用户通告阅读标记表记录
|
||||
String userId = sysAnnouncement.getUserIds();
|
||||
String[] userIds = userId.substring(0, (userId.length()-1)).split(",");
|
||||
String anntId = sysAnnouncement.getId();
|
||||
Date refDate = new Date();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
|
||||
obj.put(WebsocketConst.MSG_ID, sysAnnouncement.getId());
|
||||
obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
|
||||
webSocket.sendMessage(userIds, obj.toJSONString());
|
||||
}
|
||||
try {
|
||||
// 同步企业微信、钉钉的消息通知
|
||||
Response<String> dtResponse = dingtalkService.sendActionCardMessage(sysAnnouncement, null, true);
|
||||
wechatEnterpriseService.sendTextCardMessage(sysAnnouncement, true);
|
||||
|
||||
if (dtResponse != null && dtResponse.isSuccess()) {
|
||||
String taskId = dtResponse.getResult();
|
||||
sysAnnouncement.setDtTaskId(taskId);
|
||||
sysAnnouncementService.updateById(sysAnnouncement);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("同步发送第三方APP消息失败:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新撤销操作
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/doReovkeData", method = RequestMethod.GET)
|
||||
public Result<SysAnnouncement> doReovkeData(@RequestParam(name="id",required=true) String id, HttpServletRequest request) {
|
||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||
SysAnnouncement sysAnnouncement = sysAnnouncementService.getById(id);
|
||||
if(sysAnnouncement==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
//撤销发布
|
||||
sysAnnouncement.setSendStatus(CommonSendStatus.REVOKE_STATUS_2);
|
||||
sysAnnouncement.setCancelTime(new Date());
|
||||
boolean ok = sysAnnouncementService.updateById(sysAnnouncement);
|
||||
if(ok) {
|
||||
result.success("该系统通知撤销成功");
|
||||
if (oConvertUtils.isNotEmpty(sysAnnouncement.getDtTaskId())) {
|
||||
try {
|
||||
dingtalkService.recallMessage(sysAnnouncement.getDtTaskId());
|
||||
} catch (Exception e) {
|
||||
log.error("第三方APP撤回消息失败:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:补充用户数据,并返回系统消息
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/listByUser", method = RequestMethod.GET)
|
||||
public Result<Map<String, Object>> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize, HttpServletRequest request) {
|
||||
long start = System.currentTimeMillis();
|
||||
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
|
||||
Map<String,Object> sysMsgMap = new HashMap(5);
|
||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||
String userId = sysUser.getId();
|
||||
|
||||
|
||||
//update-begin---author:scott ---date:2024-05-11 for:【性能优化】优化系统通知,只查近2个月的通知---
|
||||
// 获取上个月的第一天(只查近两个月的通知)
|
||||
Date lastMonthStartDay = DateRangeUtils.getLastMonthStartDay();
|
||||
log.info("-----查询近两个月收到的未读通知-----,近2月的第一天:{}", lastMonthStartDay);
|
||||
//update-end---author:scott ---date::2024-05-11 for:【性能优化】优化系统通知,只查近2个月的通知---
|
||||
|
||||
// //补推送数据(用户和通知的关系表)
|
||||
// completeNoteThreadPool.execute(()->{
|
||||
// sysAnnouncementService.completeAnnouncementSendInfo();
|
||||
// });
|
||||
|
||||
// 2.查询用户未读的系统消息
|
||||
Page<SysAnnouncement> anntMsgList = new Page<SysAnnouncement>(0, pageSize);
|
||||
//通知公告消息
|
||||
anntMsgList = sysAnnouncementService.querySysCementPageByUserId(anntMsgList,userId,"1",null, lastMonthStartDay);
|
||||
sysMsgMap.put("anntMsgList", anntMsgList.getRecords());
|
||||
sysMsgMap.put("anntMsgTotal", anntMsgList.getTotal());
|
||||
|
||||
log.info("begin 获取用户近2个月的系统公告 (通知)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
//系统消息
|
||||
Page<SysAnnouncement> sysMsgList = new Page<SysAnnouncement>(0, pageSize);
|
||||
sysMsgList = sysAnnouncementService.querySysCementPageByUserId(sysMsgList,userId,"2",null, lastMonthStartDay);
|
||||
sysMsgMap.put("sysMsgList", sysMsgList.getRecords());
|
||||
sysMsgMap.put("sysMsgTotal", sysMsgList.getTotal());
|
||||
|
||||
log.info("end 获取用户2个月的系统公告 (系统消息)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
result.setSuccess(true);
|
||||
result.setResult(sysMsgMap);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取未读消息通知数量
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/getUnreadMessageCount", method = RequestMethod.GET)
|
||||
public Result<Integer> getUnreadMessageCount(@RequestParam(required = false, defaultValue = "5") Integer pageSize, HttpServletRequest request) {
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
String userId = sysUser.getId();
|
||||
|
||||
// 获取上个月的第一天(只查近两个月的通知)
|
||||
Date lastMonthStartDay = DateRangeUtils.getLastMonthStartDay();
|
||||
log.info(" ------查询近两个月收到的未读通知消息数量------,近2月的第一天:{}", lastMonthStartDay);
|
||||
Integer unreadMessageCount = sysAnnouncementService.getUnreadMessageCountByUserId(userId, lastMonthStartDay);
|
||||
return Result.ok(unreadMessageCount);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(SysAnnouncement sysAnnouncement,HttpServletRequest request) {
|
||||
// Step.1 组装查询条件
|
||||
LambdaQueryWrapper<SysAnnouncement> queryWrapper = new LambdaQueryWrapper<SysAnnouncement>(sysAnnouncement);
|
||||
//Step.2 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
queryWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
|
||||
List<SysAnnouncement> pageList = sysAnnouncementService.list(queryWrapper);
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "系统通告列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysAnnouncement.class);
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("系统通告列表数据", "导出人:"+user.getRealname(), "导出信息"));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 获取上传文件对象
|
||||
MultipartFile file = entity.getValue();
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
List<SysAnnouncement> listSysAnnouncements = ExcelImportUtil.importExcel(file.getInputStream(), SysAnnouncement.class, params);
|
||||
for (SysAnnouncement sysAnnouncementExcel : listSysAnnouncements) {
|
||||
if(sysAnnouncementExcel.getDelFlag()==null){
|
||||
sysAnnouncementExcel.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
}
|
||||
sysAnnouncementService.save(sysAnnouncementExcel);
|
||||
}
|
||||
return Result.ok("文件导入成功!数据行数:" + listSysAnnouncements.size());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return Result.error("文件导入失败!");
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.error("文件导入失败!");
|
||||
}
|
||||
/**
|
||||
*同步消息
|
||||
* @param anntId
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/syncNotic", method = RequestMethod.GET)
|
||||
public Result<SysAnnouncement> syncNotic(@RequestParam(name="anntId",required=false) String anntId, HttpServletRequest request) {
|
||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||
JSONObject obj = new JSONObject();
|
||||
if(StringUtils.isNotBlank(anntId)){
|
||||
SysAnnouncement sysAnnouncement = sysAnnouncementService.getById(anntId);
|
||||
if(sysAnnouncement==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
if(sysAnnouncement.getMsgType().equals(CommonConstant.MSG_TYPE_ALL)) {
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
|
||||
obj.put(WebsocketConst.MSG_ID, sysAnnouncement.getId());
|
||||
obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
|
||||
webSocket.sendMessage(obj.toJSONString());
|
||||
}else {
|
||||
// 2.插入用户通告阅读标记表记录
|
||||
String userId = sysAnnouncement.getUserIds();
|
||||
if(oConvertUtils.isNotEmpty(userId)){
|
||||
String[] userIds = userId.substring(0, (userId.length()-1)).split(",");
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
|
||||
obj.put(WebsocketConst.MSG_ID, sysAnnouncement.getId());
|
||||
obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
|
||||
webSocket.sendMessage(userIds, obj.toJSONString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
|
||||
obj.put(WebsocketConst.MSG_TXT, "批量设置已读");
|
||||
webSocket.sendMessage(obj.toJSONString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通告查看详情页面(用于第三方APP)
|
||||
* @param modelAndView
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/show/{id}")
|
||||
public ModelAndView showContent(ModelAndView modelAndView, @PathVariable("id") String id, HttpServletRequest request) {
|
||||
SysAnnouncement announcement = sysAnnouncementService.getById(id);
|
||||
if (announcement != null) {
|
||||
boolean tokenOk = false;
|
||||
try {
|
||||
// 验证Token有效性
|
||||
tokenOk = TokenUtils.verifyToken(request, sysBaseApi, redisUtil);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
// 判断是否传递了Token,并且Token有效,如果传了就不做查看限制,直接返回
|
||||
// 如果Token无效,就做查看限制:只能查看已发布的
|
||||
if (tokenOk || ANNOUNCEMENT_SEND_STATUS_1.equals(announcement.getSendStatus())) {
|
||||
modelAndView.addObject("data", announcement);
|
||||
modelAndView.setViewName("announcement/showContent");
|
||||
return modelAndView;
|
||||
}
|
||||
}
|
||||
modelAndView.setStatus(HttpStatus.NOT_FOUND);
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【vue3用】 消息列表查询
|
||||
* @param fromUser
|
||||
* @param beginDate
|
||||
* @param endDate
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/vue3List", method = RequestMethod.GET)
|
||||
public Result<List<SysAnnouncement>> vue3List(@RequestParam(name="fromUser", required = false) String fromUser,
|
||||
@RequestParam(name="starFlag", required = false) String starFlag,
|
||||
@RequestParam(name="rangeDateKey", required = false) String rangeDateKey,
|
||||
@RequestParam(name="beginDate", required = false) String beginDate,
|
||||
@RequestParam(name="endDate", required = false) String endDate,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
|
||||
long calStartTime = System.currentTimeMillis(); // 记录开始时间
|
||||
|
||||
// 1、获取日期查询条件,开始时间和结束时间
|
||||
Date beginTime = null, endTime = null;
|
||||
if (RangeDateEnum.ZDY.getKey().equals(rangeDateKey)) {
|
||||
// 自定义日期范围查询
|
||||
if (oConvertUtils.isNotEmpty(beginDate)) {
|
||||
beginTime = DateUtils.parseDatetime(beginDate);
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(endDate)) {
|
||||
endTime = DateUtils.parseDatetime(endDate);
|
||||
}
|
||||
} else {
|
||||
// 日期段落查询
|
||||
Date[] arr = RangeDateEnum.getRangeArray(rangeDateKey);
|
||||
if (arr != null) {
|
||||
beginTime = arr[0];
|
||||
endTime = arr[1];
|
||||
}
|
||||
}
|
||||
|
||||
// 2、根据条件查询用户的通知消息
|
||||
List<SysAnnouncement> ls = this.sysAnnouncementService.querySysMessageList(pageSize, pageNo, fromUser, starFlag, beginTime, endTime);
|
||||
|
||||
// 3、设置当前页的消息为已读
|
||||
if (!CollectionUtils.isEmpty(ls)) {
|
||||
// 设置已读
|
||||
String readed = "1";
|
||||
List<String> annoceIdList = ls.stream().filter(item -> !readed.equals(item.getReadFlag())).map(item -> item.getId()).collect(Collectors.toList());
|
||||
if (!CollectionUtils.isEmpty(annoceIdList)) {
|
||||
cachedThreadPool.execute(() -> {
|
||||
sysAnnouncementService.updateReaded(annoceIdList);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
||||
|
||||
// 4、性能统计耗时
|
||||
long calEndTime = System.currentTimeMillis(); // 记录结束时间
|
||||
long duration = calEndTime - calStartTime; // 计算耗时
|
||||
System.out.println("耗时:" + duration + " 毫秒");
|
||||
|
||||
return Result.ok(ls);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据用户id获取最新一条消息发送时间(创建时间)
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getLastAnnountTime")
|
||||
public Result<Page<SysAnnouncementSend>> getLastAnnountTime(@RequestParam(name = "userId") String userId){
|
||||
Result<Page<SysAnnouncementSend>> result = new Result<>();
|
||||
//----------------------------------------------------------------------------------------
|
||||
// step.1 此接口过慢,可以采用缓存一小时方案
|
||||
String keyString = String.format(CommonConstant.CACHE_KEY_USER_LAST_ANNOUNT_TIME_1HOUR, userId);
|
||||
if (redisTemplate.hasKey(keyString)) {
|
||||
log.info("[SysAnnouncementSend Redis] 通过Redis缓存查询用户最后一次收到系统通知时间,userId={}", userId);
|
||||
Page<SysAnnouncementSend> pageList = (Page<SysAnnouncementSend>) redisTemplate.opsForValue().get(keyString);
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
Page<SysAnnouncementSend> page = new Page<>(1,1);
|
||||
LambdaQueryWrapper<SysAnnouncementSend> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysAnnouncementSend::getUserId,userId);
|
||||
//只查询上个月和本月,的通知的数据
|
||||
query.ne(SysAnnouncementSend::getCreateTime, DateRangeUtils.getLastMonthStartDay());
|
||||
query.select(SysAnnouncementSend::getCreateTime); // 提高查询效率
|
||||
query.orderByDesc(SysAnnouncementSend::getCreateTime);
|
||||
Page<SysAnnouncementSend> pageList = sysAnnouncementSendService.page(page, query);
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
if (pageList != null && pageList.getSize() > 0) {
|
||||
// step.3 保留1小时redis缓存
|
||||
redisTemplate.opsForValue().set(keyString, pageList, 3600, TimeUnit.SECONDS);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除当前用户所有未读消息
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/clearAllUnReadMessage")
|
||||
public Result<String> clearAllUnReadMessage(){
|
||||
sysAnnouncementService.clearAllUnReadMessage();
|
||||
return Result.ok("清除未读消息成功");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,269 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.DataBaseConstant;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.SqlInjectionUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.message.websocket.WebSocket;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||
import org.jeecg.modules.system.model.AnnouncementSendModel;
|
||||
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @Title: Controller
|
||||
* @Description: 用户通告阅读标记表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-02-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/sysAnnouncementSend")
|
||||
@Slf4j
|
||||
public class SysAnnouncementSendController {
|
||||
@Autowired
|
||||
private ISysAnnouncementSendService sysAnnouncementSendService;
|
||||
@Autowired
|
||||
private WebSocket webSocket;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
* @param sysAnnouncementSend
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<SysAnnouncementSend>> queryPageList(SysAnnouncementSend sysAnnouncementSend,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
Result<IPage<SysAnnouncementSend>> result = new Result<IPage<SysAnnouncementSend>>();
|
||||
QueryWrapper<SysAnnouncementSend> queryWrapper = new QueryWrapper<SysAnnouncementSend>(sysAnnouncementSend);
|
||||
Page<SysAnnouncementSend> page = new Page<SysAnnouncementSend>(pageNo,pageSize);
|
||||
//排序逻辑 处理
|
||||
String column = req.getParameter("column");
|
||||
String order = req.getParameter("order");
|
||||
|
||||
if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
|
||||
if(DataBaseConstant.SQL_ASC.equals(order)) {
|
||||
queryWrapper.orderByAsc(SqlInjectionUtil.getSqlInjectSortField(column));
|
||||
}else {
|
||||
queryWrapper.orderByDesc(SqlInjectionUtil.getSqlInjectSortField(column));
|
||||
}
|
||||
}
|
||||
IPage<SysAnnouncementSend> pageList = sysAnnouncementSendService.page(page, queryWrapper);
|
||||
//log.info("查询当前页:"+pageList.getCurrent());
|
||||
//log.info("查询当前页数量:"+pageList.getSize());
|
||||
//log.info("查询结果数量:"+pageList.getRecords().size());
|
||||
//log.info("数据总数:"+pageList.getTotal());
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
* @param sysAnnouncementSend
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/add")
|
||||
public Result<SysAnnouncementSend> add(@RequestBody SysAnnouncementSend sysAnnouncementSend) {
|
||||
Result<SysAnnouncementSend> result = new Result<SysAnnouncementSend>();
|
||||
try {
|
||||
sysAnnouncementSendService.save(sysAnnouncementSend);
|
||||
result.success("添加成功!");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param sysAnnouncementSend
|
||||
* @return
|
||||
*/
|
||||
@PutMapping(value = "/edit")
|
||||
public Result<SysAnnouncementSend> eidt(@RequestBody SysAnnouncementSend sysAnnouncementSend) {
|
||||
Result<SysAnnouncementSend> result = new Result<SysAnnouncementSend>();
|
||||
SysAnnouncementSend sysAnnouncementSendEntity = sysAnnouncementSendService.getById(sysAnnouncementSend.getId());
|
||||
if(sysAnnouncementSendEntity==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
boolean ok = sysAnnouncementSendService.updateById(sysAnnouncementSend);
|
||||
//TODO 返回false说明什么?
|
||||
if(ok) {
|
||||
result.success("操作成功!");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<SysAnnouncementSend> delete(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysAnnouncementSend> result = new Result<SysAnnouncementSend>();
|
||||
SysAnnouncementSend sysAnnouncementSend = sysAnnouncementSendService.getById(id);
|
||||
if(sysAnnouncementSend==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
boolean ok = sysAnnouncementSendService.removeById(id);
|
||||
if(ok) {
|
||||
result.success("删除成功!");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<SysAnnouncementSend> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
Result<SysAnnouncementSend> result = new Result<SysAnnouncementSend>();
|
||||
if(ids==null || "".equals(ids.trim())) {
|
||||
result.error500("参数不识别!");
|
||||
}else {
|
||||
this.sysAnnouncementSendService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<SysAnnouncementSend> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysAnnouncementSend> result = new Result<SysAnnouncementSend>();
|
||||
SysAnnouncementSend sysAnnouncementSend = sysAnnouncementSendService.getById(id);
|
||||
if(sysAnnouncementSend==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
result.setResult(sysAnnouncementSend);
|
||||
result.setSuccess(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:更新用户系统消息阅读状态
|
||||
* @param json
|
||||
* @return
|
||||
*/
|
||||
@PutMapping(value = "/editByAnntIdAndUserId")
|
||||
public Result<SysAnnouncementSend> editById(@RequestBody JSONObject json) {
|
||||
Result<SysAnnouncementSend> result = new Result<SysAnnouncementSend>();
|
||||
String anntId = json.getString("anntId");
|
||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||
String userId = sysUser.getId();
|
||||
LambdaUpdateWrapper<SysAnnouncementSend> updateWrapper = new UpdateWrapper().lambda();
|
||||
updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG);
|
||||
updateWrapper.set(SysAnnouncementSend::getReadTime, new Date());
|
||||
//update-begin-author:liusq date:2023-09-04 for:系统模块存在的sql漏洞写法
|
||||
updateWrapper.eq(SysAnnouncementSend::getAnntId,anntId);
|
||||
updateWrapper.eq(SysAnnouncementSend::getUserId,userId);
|
||||
//update-end-author:liusq date:2023-09-04 for: 系统模块存在的sql漏洞写法
|
||||
//updateWrapper.last("where annt_id ='"+anntId+"' and user_id ='"+userId+"'");
|
||||
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
||||
sysAnnouncementSendService.update(announcementSend, updateWrapper);
|
||||
result.setSuccess(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:获取我的消息
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/getMyAnnouncementSend")
|
||||
public Result<IPage<AnnouncementSendModel>> getMyAnnouncementSend(AnnouncementSendModel announcementSendModel,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
|
||||
Result<IPage<AnnouncementSendModel>> result = new Result<IPage<AnnouncementSendModel>>();
|
||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||
String userId = sysUser.getId();
|
||||
announcementSendModel.setUserId(userId);
|
||||
announcementSendModel.setPageNo((pageNo-1)*pageSize);
|
||||
announcementSendModel.setPageSize(pageSize);
|
||||
Page<AnnouncementSendModel> pageList = new Page<AnnouncementSendModel>(pageNo,pageSize);
|
||||
pageList = sysAnnouncementSendService.getMyAnnouncementSendPage(pageList, announcementSendModel);
|
||||
result.setResult(pageList);
|
||||
result.setSuccess(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:一键已读
|
||||
* @return
|
||||
*/
|
||||
@PutMapping(value = "/readAll")
|
||||
public Result<SysAnnouncementSend> readAll() {
|
||||
Result<SysAnnouncementSend> result = new Result<SysAnnouncementSend>();
|
||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||
String userId = sysUser.getId();
|
||||
LambdaUpdateWrapper<SysAnnouncementSend> updateWrapper = new UpdateWrapper().lambda();
|
||||
updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG);
|
||||
updateWrapper.set(SysAnnouncementSend::getReadTime, new Date());
|
||||
updateWrapper.eq(SysAnnouncementSend::getUserId,userId);
|
||||
//updateWrapper.last("where user_id ='"+userId+"'");
|
||||
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
||||
sysAnnouncementSendService.update(announcementSend, updateWrapper);
|
||||
JSONObject socketParams = new JSONObject();
|
||||
socketParams.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
|
||||
webSocket.sendMessage(socketParams.toJSONString());
|
||||
result.setSuccess(true);
|
||||
result.setMessage("全部已读");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据消息发送记录ID获取消息内容
|
||||
* @param sendId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/getOne")
|
||||
public Result<AnnouncementSendModel> getOne(@RequestParam(name="sendId",required=true) String sendId) {
|
||||
AnnouncementSendModel model = sysAnnouncementSendService.getOne(sendId);
|
||||
return Result.ok(model);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,538 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.ImportExcelUtil;
|
||||
import org.jeecg.common.util.ReflectHelper;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.system.entity.SysCategory;
|
||||
import org.jeecg.modules.system.model.TreeSelectModel;
|
||||
import org.jeecg.modules.system.service.ISysCategoryService;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: 分类字典
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-05-29
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/category")
|
||||
@Slf4j
|
||||
public class SysCategoryController {
|
||||
@Autowired
|
||||
private ISysCategoryService sysCategoryService;
|
||||
|
||||
/**
|
||||
* 分类编码0
|
||||
*/
|
||||
private static final String CATEGORY_ROOT_CODE = "0";
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
* @param sysCategory
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/rootList")
|
||||
public Result<IPage<SysCategory>> queryPageList(SysCategory sysCategory,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
if(oConvertUtils.isEmpty(sysCategory.getPid())){
|
||||
sysCategory.setPid("0");
|
||||
}
|
||||
Result<IPage<SysCategory>> result = new Result<IPage<SysCategory>>();
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysCategory.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(),0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
//--author:os_chengtgen---date:20190804 -----for: 分类字典页面显示错误,issues:377--------start
|
||||
//--author:liusq---date:20211119 -----for: 【vue3】分类字典页面查询条件配置--------start
|
||||
QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap());
|
||||
String name = sysCategory.getName();
|
||||
String code = sysCategory.getCode();
|
||||
//QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<SysCategory>();
|
||||
if(StringUtils.isBlank(name)&&StringUtils.isBlank(code)){
|
||||
queryWrapper.eq("pid", sysCategory.getPid());
|
||||
}
|
||||
//--author:liusq---date:20211119 -----for: 分类字典页面查询条件配置--------end
|
||||
//--author:os_chengtgen---date:20190804 -----for:【vue3】 分类字典页面显示错误,issues:377--------end
|
||||
|
||||
Page<SysCategory> page = new Page<SysCategory>(pageNo, pageSize);
|
||||
IPage<SysCategory> pageList = sysCategoryService.page(page, queryWrapper);
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/childList")
|
||||
public Result<List<SysCategory>> queryPageList(SysCategory sysCategory,HttpServletRequest req) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysCategory.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
Result<List<SysCategory>> result = new Result<List<SysCategory>>();
|
||||
QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap());
|
||||
List<SysCategory> list = sysCategoryService.list(queryWrapper);
|
||||
result.setSuccess(true);
|
||||
result.setResult(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加
|
||||
* @param sysCategory
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/add")
|
||||
public Result<SysCategory> add(@RequestBody SysCategory sysCategory) {
|
||||
Result<SysCategory> result = new Result<SysCategory>();
|
||||
try {
|
||||
sysCategoryService.addSysCategory(sysCategory);
|
||||
result.success("添加成功!");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param sysCategory
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/edit", method = { RequestMethod.PUT,RequestMethod.POST })
|
||||
public Result<SysCategory> edit(@RequestBody SysCategory sysCategory) {
|
||||
Result<SysCategory> result = new Result<SysCategory>();
|
||||
SysCategory sysCategoryEntity = sysCategoryService.getById(sysCategory.getId());
|
||||
if(sysCategoryEntity==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
sysCategoryService.updateSysCategory(sysCategory);
|
||||
result.success("修改成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<SysCategory> delete(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysCategory> result = new Result<SysCategory>();
|
||||
SysCategory sysCategory = sysCategoryService.getById(id);
|
||||
if(sysCategory==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
this.sysCategoryService.deleteSysCategory(id);
|
||||
result.success("删除成功!");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<SysCategory> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
Result<SysCategory> result = new Result<SysCategory>();
|
||||
if(ids==null || "".equals(ids.trim())) {
|
||||
result.error500("参数不识别!");
|
||||
}else {
|
||||
this.sysCategoryService.deleteSysCategory(ids);
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<SysCategory> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysCategory> result = new Result<SysCategory>();
|
||||
SysCategory sysCategory = sysCategoryService.getById(id);
|
||||
if(sysCategory==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
result.setResult(sysCategory);
|
||||
result.setSuccess(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysCategory sysCategory) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysCategory.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
// Step.1 组装查询条件查询数据
|
||||
QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, request.getParameterMap());
|
||||
List<SysCategory> pageList = sysCategoryService.list(queryWrapper);
|
||||
// Step.2 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
// 过滤选中数据
|
||||
String selections = request.getParameter("selections");
|
||||
if(oConvertUtils.isEmpty(selections)) {
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
}else {
|
||||
List<String> selectionList = Arrays.asList(selections.split(","));
|
||||
List<SysCategory> exportList = pageList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
|
||||
}
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "分类字典列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysCategory.class);
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("分类字典列表数据", "导出人:"+user.getRealname(), "导出信息"));
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) throws IOException{
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
// 错误信息
|
||||
List<String> errorMessage = new ArrayList<>();
|
||||
int successLines = 0, errorLines = 0;
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 获取上传文件对象
|
||||
MultipartFile file = entity.getValue();
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
List<SysCategory> listSysCategorys = ExcelImportUtil.importExcel(file.getInputStream(), SysCategory.class, params);
|
||||
//按照编码长度排序
|
||||
Collections.sort(listSysCategorys);
|
||||
log.info("排序后的list====>",listSysCategorys);
|
||||
for (int i = 0; i < listSysCategorys.size(); i++) {
|
||||
SysCategory sysCategoryExcel = listSysCategorys.get(i);
|
||||
String code = sysCategoryExcel.getCode();
|
||||
if(code.length()>3){
|
||||
String pCode = sysCategoryExcel.getCode().substring(0,code.length()-3);
|
||||
log.info("pCode====>",pCode);
|
||||
String pId=sysCategoryService.queryIdByCode(pCode);
|
||||
log.info("pId====>",pId);
|
||||
if(StringUtils.isNotBlank(pId)){
|
||||
sysCategoryExcel.setPid(pId);
|
||||
}
|
||||
}else{
|
||||
sysCategoryExcel.setPid("0");
|
||||
}
|
||||
try {
|
||||
sysCategoryService.save(sysCategoryExcel);
|
||||
successLines++;
|
||||
} catch (Exception e) {
|
||||
errorLines++;
|
||||
String message = e.getMessage().toLowerCase();
|
||||
int lineNumber = i + 1;
|
||||
// 通过索引名判断出错信息
|
||||
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CATEGORY_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:分类编码已经存在,忽略导入。");
|
||||
} else {
|
||||
errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入");
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
errorMessage.add("发生异常:" + e.getMessage());
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ImportExcelUtil.imporReturnRes(errorLines,successLines,errorMessage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 加载单个数据 用于回显
|
||||
*/
|
||||
@RequestMapping(value = "/loadOne", method = RequestMethod.GET)
|
||||
public Result<SysCategory> loadOne(@RequestParam(name="field") String field,@RequestParam(name="val") String val) {
|
||||
Result<SysCategory> result = new Result<SysCategory>();
|
||||
try {
|
||||
//update-begin-author:taoyan date:2022-5-6 for: issues/3663 sql注入问题
|
||||
boolean isClassField = ReflectHelper.isClassField(field, SysCategory.class);
|
||||
if (!isClassField) {
|
||||
return Result.error("字段无效,请检查!");
|
||||
}
|
||||
//update-end-author:taoyan date:2022-5-6 for: issues/3663 sql注入问题
|
||||
QueryWrapper<SysCategory> query = new QueryWrapper<SysCategory>();
|
||||
query.eq(field, val);
|
||||
List<SysCategory> ls = this.sysCategoryService.list(query);
|
||||
if(ls==null || ls.size()==0) {
|
||||
result.setMessage("查询无果");
|
||||
result.setSuccess(false);
|
||||
}else if(ls.size()>1) {
|
||||
result.setMessage("查询数据异常,["+field+"]存在多个值:"+val);
|
||||
result.setSuccess(false);
|
||||
}else {
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls.get(0));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result.setMessage(e.getMessage());
|
||||
result.setSuccess(false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载节点的子数据
|
||||
*/
|
||||
@RequestMapping(value = "/loadTreeChildren", method = RequestMethod.GET)
|
||||
public Result<List<TreeSelectModel>> loadTreeChildren(@RequestParam(name="pid") String pid) {
|
||||
Result<List<TreeSelectModel>> result = new Result<List<TreeSelectModel>>();
|
||||
try {
|
||||
List<TreeSelectModel> ls = this.sysCategoryService.queryListByPid(pid);
|
||||
result.setResult(ls);
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result.setMessage(e.getMessage());
|
||||
result.setSuccess(false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载一级节点/如果是同步 则所有数据
|
||||
*/
|
||||
@RequestMapping(value = "/loadTreeRoot", method = RequestMethod.GET)
|
||||
public Result<List<TreeSelectModel>> loadTreeRoot(@RequestParam(name="async") Boolean async,@RequestParam(name="pcode") String pcode) {
|
||||
Result<List<TreeSelectModel>> result = new Result<List<TreeSelectModel>>();
|
||||
try {
|
||||
List<TreeSelectModel> ls = this.sysCategoryService.queryListByCode(pcode);
|
||||
if(!async) {
|
||||
loadAllCategoryChildren(ls);
|
||||
}
|
||||
result.setResult(ls);
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result.setMessage(e.getMessage());
|
||||
result.setSuccess(false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归求子节点 同步加载用到
|
||||
*/
|
||||
private void loadAllCategoryChildren(List<TreeSelectModel> ls) {
|
||||
for (TreeSelectModel tsm : ls) {
|
||||
List<TreeSelectModel> temp = this.sysCategoryService.queryListByPid(tsm.getKey());
|
||||
if(temp!=null && temp.size()>0) {
|
||||
tsm.setChildren(temp);
|
||||
loadAllCategoryChildren(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验编码
|
||||
* @param pid
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/checkCode")
|
||||
public Result<?> checkCode(@RequestParam(name="pid",required = false) String pid,@RequestParam(name="code",required = false) String code) {
|
||||
if(oConvertUtils.isEmpty(code)){
|
||||
return Result.error("错误,类型编码为空!");
|
||||
}
|
||||
if(oConvertUtils.isEmpty(pid)){
|
||||
return Result.ok();
|
||||
}
|
||||
SysCategory parent = this.sysCategoryService.getById(pid);
|
||||
if(code.startsWith(parent.getCode())){
|
||||
return Result.ok();
|
||||
}else{
|
||||
return Result.error("编码不符合规范,须以\""+parent.getCode()+"\"开头!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分类字典树控件 加载节点
|
||||
* @param pid
|
||||
* @param pcode
|
||||
* @param condition
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadTreeData", method = RequestMethod.GET)
|
||||
public Result<List<TreeSelectModel>> loadDict(@RequestParam(name="pid",required = false) String pid,@RequestParam(name="pcode",required = false) String pcode, @RequestParam(name="condition",required = false) String condition) {
|
||||
Result<List<TreeSelectModel>> result = new Result<List<TreeSelectModel>>();
|
||||
//pid如果传值了 就忽略pcode的作用
|
||||
if(oConvertUtils.isEmpty(pid)){
|
||||
if(oConvertUtils.isEmpty(pcode)){
|
||||
result.setSuccess(false);
|
||||
result.setMessage("加载分类字典树参数有误.[null]!");
|
||||
return result;
|
||||
}else{
|
||||
if(ISysCategoryService.ROOT_PID_VALUE.equals(pcode)){
|
||||
pid = ISysCategoryService.ROOT_PID_VALUE;
|
||||
}else{
|
||||
pid = this.sysCategoryService.queryIdByCode(pcode);
|
||||
}
|
||||
if(oConvertUtils.isEmpty(pid)){
|
||||
result.setSuccess(false);
|
||||
result.setMessage("加载分类字典树参数有误.[code]!");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, String> query = null;
|
||||
if(oConvertUtils.isNotEmpty(condition)) {
|
||||
query = JSON.parseObject(condition, Map.class);
|
||||
}
|
||||
List<TreeSelectModel> ls = sysCategoryService.queryListByPid(pid,query);
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分类字典控件数据回显[表单页面]
|
||||
*
|
||||
* @param ids
|
||||
* @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadDictItem", method = RequestMethod.GET)
|
||||
public Result<List<String>> loadDictItem(@RequestParam(name = "ids") String ids, @RequestParam(name = "delNotExist", required = false, defaultValue = "true") boolean delNotExist) {
|
||||
Result<List<String>> result = new Result<>();
|
||||
// 非空判断
|
||||
if (StringUtils.isBlank(ids)) {
|
||||
result.setSuccess(false);
|
||||
result.setMessage("ids 不能为空");
|
||||
return result;
|
||||
}
|
||||
// 查询数据
|
||||
List<String> textList = sysCategoryService.loadDictItem(ids, delNotExist);
|
||||
result.setSuccess(true);
|
||||
result.setResult(textList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* [列表页面]加载分类字典数据 用于值的替换
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadAllData", method = RequestMethod.GET)
|
||||
public Result<List<DictModel>> loadAllData(@RequestParam(name="code",required = true) String code) {
|
||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
LambdaQueryWrapper<SysCategory> query = new LambdaQueryWrapper<SysCategory>();
|
||||
if(oConvertUtils.isNotEmpty(code) && !CATEGORY_ROOT_CODE.equals(code)){
|
||||
query.likeRight(SysCategory::getCode,code);
|
||||
}
|
||||
List<SysCategory> list = this.sysCategoryService.list(query);
|
||||
if(list==null || list.size()==0) {
|
||||
result.setMessage("无数据,参数有误.[code]");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
List<DictModel> rdList = new ArrayList<DictModel>();
|
||||
for (SysCategory c : list) {
|
||||
rdList.add(new DictModel(c.getId(),c.getName()));
|
||||
}
|
||||
result.setSuccess(true);
|
||||
result.setResult(rdList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据父级id批量查询子节点
|
||||
* @param parentIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getChildListBatch")
|
||||
public Result getChildListBatch(@RequestParam("parentIds") String parentIds) {
|
||||
try {
|
||||
QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<>();
|
||||
List<String> parentIdList = Arrays.asList(parentIds.split(","));
|
||||
queryWrapper.in("pid", parentIdList);
|
||||
List<SysCategory> list = sysCategoryService.list(queryWrapper);
|
||||
IPage<SysCategory> pageList = new Page<>(1, 10, list.size());
|
||||
pageList.setRecords(list);
|
||||
return Result.OK(pageList);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("批量查询子节点失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,186 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.system.entity.SysCheckRule;
|
||||
import org.jeecg.modules.system.service.ISysCheckRuleService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Description: 编码校验规则
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2020-02-04
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Tag(name = "编码校验规则")
|
||||
@RestController
|
||||
@RequestMapping("/sys/checkRule")
|
||||
public class SysCheckRuleController extends JeecgController<SysCheckRule, ISysCheckRuleService> {
|
||||
|
||||
@Autowired
|
||||
private ISysCheckRuleService sysCheckRuleService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysCheckRule
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "编码校验规则-分页列表查询")
|
||||
@Operation(summary = "编码校验规则-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result queryPageList(
|
||||
SysCheckRule sysCheckRule,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
QueryWrapper<SysCheckRule> queryWrapper = QueryGenerator.initQueryWrapper(sysCheckRule, request.getParameterMap());
|
||||
Page<SysCheckRule> page = new Page<>(pageNo, pageSize);
|
||||
IPage<SysCheckRule> pageList = sysCheckRuleService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param ruleCode
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "编码校验规则-通过Code校验传入的值")
|
||||
@Operation(summary = "编码校验规则-通过Code校验传入的值")
|
||||
@GetMapping(value = "/checkByCode")
|
||||
public Result checkByCode(
|
||||
@RequestParam(name = "ruleCode") String ruleCode,
|
||||
@RequestParam(name = "value") String value
|
||||
) throws UnsupportedEncodingException {
|
||||
SysCheckRule sysCheckRule = sysCheckRuleService.getByCode(ruleCode);
|
||||
if (sysCheckRule == null) {
|
||||
return Result.error("该编码不存在");
|
||||
}
|
||||
JSONObject errorResult = sysCheckRuleService.checkValue(sysCheckRule, URLDecoder.decode(value, "UTF-8"));
|
||||
if (errorResult == null) {
|
||||
return Result.ok();
|
||||
} else {
|
||||
Result<Object> r = Result.error(errorResult.getString("message"));
|
||||
r.setResult(errorResult);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysCheckRule
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "编码校验规则-添加")
|
||||
@Operation(summary = "编码校验规则-添加")
|
||||
@PostMapping(value = "/add")
|
||||
public Result add(@RequestBody SysCheckRule sysCheckRule) {
|
||||
sysCheckRuleService.save(sysCheckRule);
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysCheckRule
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "编码校验规则-编辑")
|
||||
@Operation(summary = "编码校验规则-编辑")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result edit(@RequestBody SysCheckRule sysCheckRule) {
|
||||
sysCheckRuleService.updateById(sysCheckRule);
|
||||
return Result.ok("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "编码校验规则-通过id删除")
|
||||
@Operation(summary = "编码校验规则-通过id删除")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result delete(@RequestParam(name = "id", required = true) String id) {
|
||||
sysCheckRuleService.removeById(id);
|
||||
return Result.ok("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "编码校验规则-批量删除")
|
||||
@Operation(summary = "编码校验规则-批量删除")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
this.sysCheckRuleService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "编码校验规则-通过id查询")
|
||||
@Operation(summary = "编码校验规则-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
SysCheckRule sysCheckRule = sysCheckRuleService.getById(id);
|
||||
return Result.ok(sysCheckRule);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param sysCheckRule
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysCheckRule sysCheckRule) {
|
||||
return super.exportXls(request, sysCheckRule, SysCheckRule.class, "编码校验规则");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysCheckRule.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,280 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.dto.DataLogDTO;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.modules.system.entity.SysComment;
|
||||
import org.jeecg.modules.system.service.ISysCommentService;
|
||||
import org.jeecg.modules.system.vo.SysCommentFileVo;
|
||||
import org.jeecg.modules.system.vo.SysCommentVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 系统评论回复表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2022-07-19
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name = "系统评论回复表")
|
||||
@RestController
|
||||
@RequestMapping("/sys/comment")
|
||||
@Slf4j
|
||||
public class SysCommentController extends JeecgController<SysComment, ISysCommentService> {
|
||||
|
||||
@Autowired
|
||||
private ISysCommentService sysCommentService;
|
||||
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseAPI;
|
||||
|
||||
|
||||
/**
|
||||
* 在线预览文件地址
|
||||
*/
|
||||
@Value("${jeecg.file-view-domain}/onlinePreview")
|
||||
private String onlinePreviewDomain;
|
||||
|
||||
/**
|
||||
* 查询评论+文件
|
||||
*
|
||||
* @param sysComment
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "系统评论回复表-列表查询")
|
||||
@GetMapping(value = "/listByForm")
|
||||
public Result<IPage<SysCommentVO>> queryListByForm(SysComment sysComment) {
|
||||
List<SysCommentVO> list = sysCommentService.queryFormCommentInfo(sysComment);
|
||||
IPage<SysCommentVO> pageList = new Page();
|
||||
pageList.setRecords(list);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询文件
|
||||
*
|
||||
* @param sysComment
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "系统评论回复表-列表查询")
|
||||
@GetMapping(value = "/fileList")
|
||||
public Result<IPage<SysCommentFileVo>> queryFileList(SysComment sysComment) {
|
||||
List<SysCommentFileVo> list = sysCommentService.queryFormFileList(sysComment.getTableName(), sysComment.getTableDataId());
|
||||
IPage<SysCommentFileVo> pageList = new Page();
|
||||
pageList.setRecords(list);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
@Operation(summary = "系统评论表-添加文本")
|
||||
@PostMapping(value = "/addText")
|
||||
public Result<String> addText(@RequestBody SysComment sysComment) {
|
||||
String commentId = sysCommentService.saveOne(sysComment);
|
||||
return Result.OK(commentId);
|
||||
}
|
||||
|
||||
@Operation(summary = "系统评论表-添加文件")
|
||||
@PostMapping(value = "/addFile")
|
||||
public Result<String> addFile(HttpServletRequest request) {
|
||||
try {
|
||||
sysCommentService.saveOneFileComment(request);
|
||||
return Result.OK("success");
|
||||
} catch (Exception e) {
|
||||
log.error("评论文件上传失败:{}", e.getMessage());
|
||||
return Result.error("操作失败," + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* app端添加评论表
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "系统评论表-添加文件")
|
||||
@PostMapping(value = "/appAddFile")
|
||||
public Result<String> appAddFile(HttpServletRequest request) {
|
||||
try {
|
||||
sysCommentService.appSaveOneFileComment(request);
|
||||
return Result.OK("success");
|
||||
} catch (Exception e) {
|
||||
log.error("评论文件上传失败:{}", e.getMessage());
|
||||
return Result.error("操作失败," + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "系统评论回复表-通过id删除")
|
||||
@DeleteMapping(value = "/deleteOne")
|
||||
public Result<String> deleteOne(@RequestParam(name = "id", required = true) String id) {
|
||||
SysComment comment = sysCommentService.getById(id);
|
||||
if(comment==null){
|
||||
return Result.error("该评论已被删除!");
|
||||
}
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
String username = sysUser.getUsername();
|
||||
String admin = "admin";
|
||||
//除了admin外 其他人只能删除自己的评论
|
||||
if((!admin.equals(username)) && !username.equals(comment.getCreateBy())){
|
||||
return Result.error("只能删除自己的评论!");
|
||||
}
|
||||
sysCommentService.deleteOne(id);
|
||||
//删除评论添加日志
|
||||
String logContent = "删除了评论, "+ comment.getCommentContent();
|
||||
DataLogDTO dataLog = new DataLogDTO(comment.getTableName(), comment.getTableDataId(), logContent, CommonConstant.DATA_LOG_TYPE_COMMENT);
|
||||
sysBaseAPI.saveDataLog(dataLog);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取文件预览的地址
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/getFileViewDomain")
|
||||
public Result<String> getFileViewDomain() {
|
||||
return Result.OK(onlinePreviewDomain);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysComment
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "系统评论回复表-分页列表查询")
|
||||
@Operation(summary = "系统评论回复表-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<SysComment>> queryPageList(SysComment sysComment,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<SysComment> queryWrapper = QueryGenerator.initQueryWrapper(sysComment, req.getParameterMap());
|
||||
Page<SysComment> page = new Page<SysComment>(pageNo, pageSize);
|
||||
IPage<SysComment> pageList = sysCommentService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysComment
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "系统评论回复表-添加")
|
||||
//@RequiresPermissions("org.jeecg.modules.demo:sys_comment:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody SysComment sysComment) {
|
||||
sysCommentService.save(sysComment);
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysComment
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "系统评论回复表-编辑")
|
||||
@Operation(summary = "系统评论回复表-编辑")
|
||||
//@RequiresPermissions("org.jeecg.modules.demo:sys_comment:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody SysComment sysComment) {
|
||||
sysCommentService.updateById(sysComment);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "系统评论回复表-通过id删除")
|
||||
@Operation(summary= "系统评论回复表-通过id删除")
|
||||
//@RequiresPermissions("org.jeecg.modules.demo:sys_comment:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
sysCommentService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "系统评论回复表-批量删除")
|
||||
@Operation(summary = "系统评论回复表-批量删除")
|
||||
//@RequiresPermissions("org.jeecg.modules.demo:sys_comment:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
this.sysCommentService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "系统评论回复表-通过id查询")
|
||||
@Operation(summary = "系统评论回复表-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<SysComment> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
SysComment sysComment = sysCommentService.getById(id);
|
||||
if (sysComment == null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(sysComment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param sysComment
|
||||
*/
|
||||
//@RequiresPermissions("org.jeecg.modules.demo:sys_comment:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysComment sysComment) {
|
||||
return super.exportXls(request, sysComment, SysComment.class, "系统评论回复表");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
//@RequiresPermissions("sys_comment:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysComment.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,109 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysDataLog;
|
||||
import org.jeecg.modules.system.service.ISysDataLogService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @Description: 系统数据日志
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/dataLog")
|
||||
@Slf4j
|
||||
public class SysDataLogController {
|
||||
@Autowired
|
||||
private ISysDataLogService service;
|
||||
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
|
||||
Result<IPage<SysDataLog>> result = new Result<IPage<SysDataLog>>();
|
||||
dataLog.setType(CommonConstant.DATA_LOG_TYPE_JSON);
|
||||
QueryWrapper<SysDataLog> queryWrapper = QueryGenerator.initQueryWrapper(dataLog, req.getParameterMap());
|
||||
Page<SysDataLog> page = new Page<SysDataLog>(pageNo, pageSize);
|
||||
IPage<SysDataLog> pageList = service.page(page, queryWrapper);
|
||||
log.info("查询当前页:"+pageList.getCurrent());
|
||||
log.info("查询当前页数量:"+pageList.getSize());
|
||||
log.info("查询结果数量:"+pageList.getRecords().size());
|
||||
log.info("数据总数:"+pageList.getTotal());
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询对比数据
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryCompareList", method = RequestMethod.GET)
|
||||
public Result<List<SysDataLog>> queryCompareList(HttpServletRequest req) {
|
||||
Result<List<SysDataLog>> result = new Result<>();
|
||||
String dataId1 = req.getParameter("dataId1");
|
||||
String dataId2 = req.getParameter("dataId2");
|
||||
List<String> idList = new ArrayList<String>();
|
||||
idList.add(dataId1);
|
||||
idList.add(dataId2);
|
||||
try {
|
||||
List<SysDataLog> list = (List<SysDataLog>) service.listByIds(idList);
|
||||
result.setResult(list);
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询版本信息
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryDataVerList", method = RequestMethod.GET)
|
||||
public Result<List<SysDataLog>> queryDataVerList(HttpServletRequest req) {
|
||||
Result<List<SysDataLog>> result = new Result<>();
|
||||
String dataTable = req.getParameter("dataTable");
|
||||
String dataId = req.getParameter("dataId");
|
||||
QueryWrapper<SysDataLog> queryWrapper = new QueryWrapper<SysDataLog>();
|
||||
queryWrapper.eq("data_table", dataTable);
|
||||
queryWrapper.eq("data_id", dataId);
|
||||
//update-begin-author:taoyan date:2022-7-26 for: 新增查询条件-type
|
||||
String type = req.getParameter("type");
|
||||
if (oConvertUtils.isNotEmpty(type)) {
|
||||
queryWrapper.eq("type", type);
|
||||
}
|
||||
// 按时间倒序排
|
||||
queryWrapper.orderByDesc("create_time");
|
||||
//update-end-author:taoyan date:2022-7-26 for:新增查询条件-type
|
||||
|
||||
List<SysDataLog> list = service.list(queryWrapper);
|
||||
if(list==null||list.size()<=0) {
|
||||
result.error500("未找到版本信息");
|
||||
}else {
|
||||
result.setResult(list);
|
||||
result.setSuccess(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,229 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.util.dynamic.db.DataSourceCachePool;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.common.util.security.JdbcSecurityUtil;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.system.entity.SysDataSource;
|
||||
import org.jeecg.modules.system.service.ISysDataSourceService;
|
||||
import org.jeecg.modules.system.util.SecurityUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 多数据源管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-12-25
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Tag(name = "多数据源管理")
|
||||
@RestController
|
||||
@RequestMapping("/sys/dataSource")
|
||||
public class SysDataSourceController extends JeecgController<SysDataSource, ISysDataSourceService> {
|
||||
|
||||
@Autowired
|
||||
private ISysDataSourceService sysDataSourceService;
|
||||
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysDataSource
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "多数据源管理-分页列表查询")
|
||||
@Operation(summary = "多数据源管理-分页列表查询")
|
||||
@RequiresPermissions("system:datasource:list")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(
|
||||
SysDataSource sysDataSource,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysDataSource.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
QueryWrapper<SysDataSource> queryWrapper = QueryGenerator.initQueryWrapper(sysDataSource, req.getParameterMap());
|
||||
Page<SysDataSource> page = new Page<>(pageNo, pageSize);
|
||||
IPage<SysDataSource> pageList = sysDataSourceService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/options")
|
||||
public Result<?> queryOptions(SysDataSource sysDataSource, HttpServletRequest req) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysDataSource.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
QueryWrapper<SysDataSource> queryWrapper = QueryGenerator.initQueryWrapper(sysDataSource, req.getParameterMap());
|
||||
List<SysDataSource> pageList = sysDataSourceService.list(queryWrapper);
|
||||
JSONArray array = new JSONArray(pageList.size());
|
||||
for (SysDataSource item : pageList) {
|
||||
JSONObject option = new JSONObject(3);
|
||||
option.put("value", item.getCode());
|
||||
option.put("label", item.getName());
|
||||
option.put("text", item.getName());
|
||||
array.add(option);
|
||||
}
|
||||
return Result.ok(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysDataSource
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "多数据源管理-添加")
|
||||
@Operation(summary = "多数据源管理-添加")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysDataSource sysDataSource) {
|
||||
//update-begin-author:taoyan date:2022-8-10 for: jdbc连接地址漏洞问题
|
||||
try {
|
||||
JdbcSecurityUtil.validate(sysDataSource.getDbUrl());
|
||||
}catch (JeecgBootException e){
|
||||
log.error(e.toString());
|
||||
return Result.error("操作失败:" + e.getMessage());
|
||||
}
|
||||
//update-end-author:taoyan date:2022-8-10 for: jdbc连接地址漏洞问题
|
||||
return sysDataSourceService.saveDataSource(sysDataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysDataSource
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "多数据源管理-编辑")
|
||||
@Operation(summary = "多数据源管理-编辑")
|
||||
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysDataSource sysDataSource) {
|
||||
//update-begin-author:taoyan date:2022-8-10 for: jdbc连接地址漏洞问题
|
||||
try {
|
||||
JdbcSecurityUtil.validate(sysDataSource.getDbUrl());
|
||||
} catch (JeecgBootException e) {
|
||||
log.error(e.toString());
|
||||
return Result.error("操作失败:" + e.getMessage());
|
||||
}
|
||||
//update-end-author:taoyan date:2022-8-10 for: jdbc连接地址漏洞问题
|
||||
return sysDataSourceService.editDataSource(sysDataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "多数据源管理-通过id删除")
|
||||
@Operation(summary = "多数据源管理-通过id删除")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id") String id) {
|
||||
return sysDataSourceService.deleteDataSource(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "多数据源管理-批量删除")
|
||||
@Operation(summary = "多数据源管理-批量删除")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids") String ids) {
|
||||
List<String> idList = Arrays.asList(ids.split(","));
|
||||
idList.forEach(item->{
|
||||
SysDataSource sysDataSource = sysDataSourceService.getById(item);
|
||||
DataSourceCachePool.removeCache(sysDataSource.getCode());
|
||||
});
|
||||
this.sysDataSourceService.removeByIds(idList);
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "多数据源管理-通过id查询")
|
||||
@Operation(summary = "多数据源管理-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id") String id) throws InterruptedException {
|
||||
SysDataSource sysDataSource = sysDataSourceService.getById(id);
|
||||
//密码解密
|
||||
String dbPassword = sysDataSource.getDbPassword();
|
||||
if(StringUtils.isNotBlank(dbPassword)){
|
||||
String decodedStr = SecurityUtil.jiemi(dbPassword);
|
||||
sysDataSource.setDbPassword(decodedStr);
|
||||
}
|
||||
return Result.ok(sysDataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param sysDataSource
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysDataSource sysDataSource) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysDataSource.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
return super.exportXls(request, sysDataSource, SysDataSource.class, "多数据源管理");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysDataSource.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,678 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.ImportExcelUtil;
|
||||
import org.jeecg.common.util.YouBianCodeUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.model.DepartIdModel;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.service.ISysDepartService;
|
||||
import org.jeecg.modules.system.service.ISysUserDepartService;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.jeecg.modules.system.vo.SysDepartExportVo;
|
||||
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 部门表 前端控制器
|
||||
* <p>
|
||||
*
|
||||
* @Author: Steve @Since: 2019-01-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/sysDepart")
|
||||
@Slf4j
|
||||
public class SysDepartController {
|
||||
|
||||
@Autowired
|
||||
private ISysDepartService sysDepartService;
|
||||
@Autowired
|
||||
public RedisTemplate<String, Object> redisTemplate;
|
||||
@Autowired
|
||||
private ISysUserService sysUserService;
|
||||
@Autowired
|
||||
private ISysUserDepartService sysUserDepartService;
|
||||
/**
|
||||
* 查询数据 查出我的部门,并以树结构数据格式响应给前端
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryMyDeptTreeList", method = RequestMethod.GET)
|
||||
public Result<List<SysDepartTreeModel>> queryMyDeptTreeList() {
|
||||
Result<List<SysDepartTreeModel>> result = new Result<>();
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
try {
|
||||
if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){
|
||||
//update-begin--Author:liusq Date:20210624 for:部门查询ids为空后的前端显示问题 issues/I3UD06
|
||||
String departIds = user.getDepartIds();
|
||||
if(StringUtils.isNotBlank(departIds)){
|
||||
List<SysDepartTreeModel> list = sysDepartService.queryMyDeptTreeList(departIds);
|
||||
result.setResult(list);
|
||||
}
|
||||
//update-end--Author:liusq Date:20210624 for:部门查询ids为空后的前端显示问题 issues/I3UD06
|
||||
result.setMessage(CommonConstant.USER_IDENTITY_2.toString());
|
||||
result.setSuccess(true);
|
||||
}else{
|
||||
result.setMessage(CommonConstant.USER_IDENTITY_1.toString());
|
||||
result.setSuccess(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据 查出所有部门,并以树结构数据格式响应给前端
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
|
||||
public Result<List<SysDepartTreeModel>> queryTreeList(@RequestParam(name = "ids", required = false) String ids) {
|
||||
Result<List<SysDepartTreeModel>> result = new Result<>();
|
||||
try {
|
||||
// 从内存中读取
|
||||
// List<SysDepartTreeModel> list =FindsDepartsChildrenUtil.getSysDepartTreeList();
|
||||
// if (CollectionUtils.isEmpty(list)) {
|
||||
// list = sysDepartService.queryTreeList();
|
||||
// }
|
||||
if(oConvertUtils.isNotEmpty(ids)){
|
||||
List<SysDepartTreeModel> departList = sysDepartService.queryTreeList(ids);
|
||||
result.setResult(departList);
|
||||
}else{
|
||||
List<SysDepartTreeModel> list = sysDepartService.queryTreeList();
|
||||
result.setResult(list);
|
||||
}
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步查询部门list
|
||||
* @param parentId 父节点 异步加载时传递
|
||||
* @param ids 前端回显是传递
|
||||
* @param primaryKey 主键字段(id或者orgCode)
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryDepartTreeSync", method = RequestMethod.GET)
|
||||
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) {
|
||||
Result<List<SysDepartTreeModel>> result = new Result<>();
|
||||
try {
|
||||
List<SysDepartTreeModel> list = sysDepartService.queryTreeListByPid(parentId,ids, primaryKey);
|
||||
result.setResult(list);
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.setSuccess(false);
|
||||
result.setMessage("查询失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个部门的所有父级部门的ID
|
||||
*
|
||||
* @param departId 根据departId查
|
||||
* @param orgCode 根据orgCode查,departId和orgCode必须有一个不为空
|
||||
*/
|
||||
@GetMapping("/queryAllParentId")
|
||||
public Result queryParentIds(
|
||||
@RequestParam(name = "departId", required = false) String departId,
|
||||
@RequestParam(name = "orgCode", required = false) String orgCode) {
|
||||
try {
|
||||
JSONObject data;
|
||||
if (oConvertUtils.isNotEmpty(departId)) {
|
||||
data = sysDepartService.queryAllParentIdByDepartId(departId);
|
||||
} else if (oConvertUtils.isNotEmpty(orgCode)) {
|
||||
data = sysDepartService.queryAllParentIdByOrgCode(orgCode);
|
||||
} else {
|
||||
return Result.error("departId 和 orgCode 不能都为空!");
|
||||
}
|
||||
return Result.OK(data);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加新数据 添加用户新建的部门对象数据,并保存到数据库
|
||||
*
|
||||
* @param sysDepart
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:depart:add")
|
||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||
@CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
|
||||
public Result<SysDepart> add(@RequestBody SysDepart sysDepart, HttpServletRequest request) {
|
||||
Result<SysDepart> result = new Result<SysDepart>();
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
try {
|
||||
sysDepart.setCreateBy(username);
|
||||
sysDepartService.saveDepartData(sysDepart, username);
|
||||
//清除部门树内存
|
||||
// FindsDepartsChildrenUtil.clearSysDepartTreeList();
|
||||
// FindsDepartsChildrenUtil.clearDepartIdModel();
|
||||
result.success("添加成功!");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑数据 编辑部门的部分数据,并保存到数据库
|
||||
*
|
||||
* @param sysDepart
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:depart:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
@CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
|
||||
public Result<SysDepart> edit(@RequestBody SysDepart sysDepart, HttpServletRequest request) {
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
sysDepart.setUpdateBy(username);
|
||||
Result<SysDepart> result = new Result<SysDepart>();
|
||||
SysDepart sysDepartEntity = sysDepartService.getById(sysDepart.getId());
|
||||
if (sysDepartEntity == null) {
|
||||
result.error500("未找到对应实体");
|
||||
} else {
|
||||
boolean ok = sysDepartService.updateDepartDataById(sysDepart, username);
|
||||
// TODO 返回false说明什么?
|
||||
if (ok) {
|
||||
//清除部门树内存
|
||||
//FindsDepartsChildrenUtil.clearSysDepartTreeList();
|
||||
//FindsDepartsChildrenUtil.clearDepartIdModel();
|
||||
result.success("修改成功!");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:depart:delete")
|
||||
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
|
||||
@CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
|
||||
public Result<SysDepart> delete(@RequestParam(name="id",required=true) String id) {
|
||||
|
||||
Result<SysDepart> result = new Result<SysDepart>();
|
||||
SysDepart sysDepart = sysDepartService.getById(id);
|
||||
if(sysDepart==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
sysDepartService.deleteDepart(id);
|
||||
//清除部门树内存
|
||||
//FindsDepartsChildrenUtil.clearSysDepartTreeList();
|
||||
// FindsDepartsChildrenUtil.clearDepartIdModel();
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量删除 根据前端请求的多个ID,对数据库执行删除相关部门数据的操作
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:depart:deleteBatch")
|
||||
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
|
||||
@CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
|
||||
public Result<SysDepart> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
|
||||
Result<SysDepart> result = new Result<SysDepart>();
|
||||
if (ids == null || "".equals(ids.trim())) {
|
||||
result.error500("参数不识别!");
|
||||
} else {
|
||||
this.sysDepartService.deleteBatchWithChildren(Arrays.asList(ids.split(",")));
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据 添加或编辑页面对该方法发起请求,以树结构形式加载所有部门的名称,方便用户的操作
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryIdTree", method = RequestMethod.GET)
|
||||
public Result<List<DepartIdModel>> queryIdTree() {
|
||||
// Result<List<DepartIdModel>> result = new Result<List<DepartIdModel>>();
|
||||
// List<DepartIdModel> idList;
|
||||
// try {
|
||||
// idList = FindsDepartsChildrenUtil.wrapDepartIdModel();
|
||||
// if (idList != null && idList.size() > 0) {
|
||||
// result.setResult(idList);
|
||||
// result.setSuccess(true);
|
||||
// } else {
|
||||
// sysDepartService.queryTreeList();
|
||||
// idList = FindsDepartsChildrenUtil.wrapDepartIdModel();
|
||||
// result.setResult(idList);
|
||||
// result.setSuccess(true);
|
||||
// }
|
||||
// return result;
|
||||
// } catch (Exception e) {
|
||||
// log.error(e.getMessage(),e);
|
||||
// result.setSuccess(false);
|
||||
// return result;
|
||||
// }
|
||||
Result<List<DepartIdModel>> result = new Result<>();
|
||||
try {
|
||||
List<DepartIdModel> list = sysDepartService.queryDepartIdTreeList();
|
||||
result.setResult(list);
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 部门搜索功能方法,根据关键字模糊搜索相关部门
|
||||
* </p>
|
||||
*
|
||||
* @param keyWord
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/searchBy", method = RequestMethod.GET)
|
||||
public Result<List<SysDepartTreeModel>> searchBy(@RequestParam(name = "keyWord", required = true) String keyWord,@RequestParam(name = "myDeptSearch", required = false) String myDeptSearch) {
|
||||
Result<List<SysDepartTreeModel>> result = new Result<List<SysDepartTreeModel>>();
|
||||
//部门查询,myDeptSearch为1时为我的部门查询,登录用户为上级时查只查负责部门下数据
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
String departIds = null;
|
||||
if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){
|
||||
departIds = user.getDepartIds();
|
||||
}
|
||||
List<SysDepartTreeModel> treeList = this.sysDepartService.searchByKeyWord(keyWord,myDeptSearch,departIds);
|
||||
if (treeList == null || treeList.size() == 0) {
|
||||
result.setSuccess(false);
|
||||
result.setMessage("未查询匹配数据!");
|
||||
return result;
|
||||
}
|
||||
result.setResult(treeList);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(SysDepart sysDepart,HttpServletRequest request) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysDepart.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
//update-begin---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
//// Step.1 组装查询条件
|
||||
//QueryWrapper<SysDepart> queryWrapper = QueryGenerator.initQueryWrapper(sysDepart, request.getParameterMap());
|
||||
//Step.1 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
//List<SysDepart> pageList = sysDepartService.list(queryWrapper);
|
||||
//按字典排序
|
||||
//Collections.sort(pageList, new Comparator<SysDepart>() {
|
||||
//@Override
|
||||
//public int compare(SysDepart arg0, SysDepart arg1) {
|
||||
//return arg0.getOrgCode().compareTo(arg1.getOrgCode());
|
||||
//}
|
||||
//});
|
||||
//step.2 组装导出数据
|
||||
Integer tenantId = sysDepart == null ? null : sysDepart.getTenantId();
|
||||
List<SysDepartExportVo> sysDepartExportVos = sysDepartService.getExportDepart(tenantId);
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "部门列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysDepartExportVo.class);
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("导入规则:\n" +
|
||||
"1、标题为第三行,部门路径和部门名称的标题不允许修改,否则会匹配失败;第四行为数据填写范围;\n" +
|
||||
"2、部门路径用英文字符/分割,部门名称为部门路径的最后一位;\n" +
|
||||
"3、部门从一级名称开始创建,如果有同级就需要多添加一行,如研发部/研发一部;研发部/研发二部;\n" +
|
||||
"4、自定义的部门编码需要满足规则才能导入。如一级部门编码为A01,那么子部门为A01A01,同级子部门为A01A02,编码固定为三位,首字母为A-Z,后两位为数字0-99,依次递增;", "导出人:"+user.getRealname(), "导出信息"));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, sysDepartExportVos);
|
||||
//update-end---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
* 部门导入方案1: 通过机构编码来计算出部门的父级ID,维护上下级关系;
|
||||
* 部门导入方案2: 你也可以改造下程序,机构编码直接导入,先不设置父ID;全部导入后,写一个sql,补下父ID;
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:depart:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
@CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
List<String> errorMessageList = new ArrayList<>();
|
||||
//List<SysDepart> listSysDeparts = null;
|
||||
List<SysDepartExportVo> listSysDeparts = null;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 获取上传文件对象
|
||||
MultipartFile file = entity.getValue();
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
//update-begin---author:wangshuai---date:2023-10-20---for: 注释掉原来的导入部门的逻辑---
|
||||
// // orgCode编码长度
|
||||
// int codeLength = YouBianCodeUtil.ZHANWEI_LENGTH;
|
||||
// listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), SysDepart.class, params);
|
||||
// //按长度排序
|
||||
// Collections.sort(listSysDeparts, new Comparator<SysDepart>() {
|
||||
// @Override
|
||||
// public int compare(SysDepart arg0, SysDepart arg1) {
|
||||
// return arg0.getOrgCode().length() - arg1.getOrgCode().length();
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// int num = 0;
|
||||
// for (SysDepart sysDepart : listSysDeparts) {
|
||||
// String orgCode = sysDepart.getOrgCode();
|
||||
// if(orgCode.length() > codeLength) {
|
||||
// String parentCode = orgCode.substring(0, orgCode.length()-codeLength);
|
||||
// QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<SysDepart>();
|
||||
// queryWrapper.eq("org_code", parentCode);
|
||||
// try {
|
||||
// SysDepart parentDept = sysDepartService.getOne(queryWrapper);
|
||||
// if(!parentDept.equals(null)) {
|
||||
// sysDepart.setParentId(parentDept.getId());
|
||||
// //更新父级部门不是叶子结点
|
||||
// sysDepartService.updateIzLeaf(parentDept.getId(),CommonConstant.NOT_LEAF);
|
||||
// } else {
|
||||
// sysDepart.setParentId("");
|
||||
// }
|
||||
// }catch (Exception e) {
|
||||
// //没有查找到parentDept
|
||||
// }
|
||||
// }else{
|
||||
// sysDepart.setParentId("");
|
||||
// }
|
||||
// //update-begin---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
|
||||
// sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
|
||||
// //update-end---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
|
||||
// sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
// //update-begin---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
// if(oConvertUtils.isEmpty(sysDepart.getOrgCategory())){
|
||||
// sysDepart.setOrgCategory("1");
|
||||
// }
|
||||
// //update-end---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
// ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
|
||||
// num++;
|
||||
// }
|
||||
//update-end---author:wangshuai---date:2023-10-20---for: 注释掉原来的导入部门的逻辑---
|
||||
|
||||
//update-begin---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), SysDepartExportVo.class, params);
|
||||
sysDepartService.importSysDepart(listSysDeparts,errorMessageList);
|
||||
//update-end---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
|
||||
//清空部门缓存
|
||||
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||
redisTemplate.delete(keys3);
|
||||
redisTemplate.delete(keys4);
|
||||
return ImportExcelUtil.imporReturnRes(errorMessageList.size(), listSysDeparts.size() - errorMessageList.size(), errorMessageList);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return Result.error("文件导入失败:"+e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.error("文件导入失败!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有部门信息
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("listAll")
|
||||
public Result<List<SysDepart>> listAll(@RequestParam(name = "id", required = false) String id) {
|
||||
Result<List<SysDepart>> result = new Result<>();
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
||||
query.orderByAsc(SysDepart::getOrgCode);
|
||||
if(oConvertUtils.isNotEmpty(id)){
|
||||
String[] arr = id.split(",");
|
||||
query.in(SysDepart::getId,arr);
|
||||
}
|
||||
List<SysDepart> ls = this.sysDepartService.list(query);
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* 查询数据 查出所有部门,并以树结构数据格式响应给前端
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryTreeByKeyWord", method = RequestMethod.GET)
|
||||
public Result<Map<String,Object>> queryTreeByKeyWord(@RequestParam(name = "keyWord", required = false) String keyWord) {
|
||||
Result<Map<String,Object>> result = new Result<>();
|
||||
try {
|
||||
Map<String,Object> map=new HashMap(5);
|
||||
List<SysDepartTreeModel> list = sysDepartService.queryTreeByKeyWord(keyWord);
|
||||
//根据keyWord获取用户信息
|
||||
LambdaQueryWrapper<SysUser> queryUser = new LambdaQueryWrapper<SysUser>();
|
||||
queryUser.eq(SysUser::getDelFlag,CommonConstant.DEL_FLAG_0);
|
||||
queryUser.and(i -> i.like(SysUser::getUsername, keyWord).or().like(SysUser::getRealname, keyWord));
|
||||
List<SysUser> sysUsers = this.sysUserService.list(queryUser);
|
||||
map.put("userList",sysUsers);
|
||||
map.put("departList",list);
|
||||
result.setResult(map);
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门编码获取部门信息
|
||||
*
|
||||
* @param orgCode
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDepartName")
|
||||
public Result<SysDepart> getDepartName(@RequestParam(name = "orgCode") String orgCode) {
|
||||
Result<SysDepart> result = new Result<>();
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysDepart::getOrgCode, orgCode);
|
||||
SysDepart sysDepart = sysDepartService.getOne(query);
|
||||
result.setSuccess(true);
|
||||
result.setResult(sysDepart);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门id获取用户信息
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUsersByDepartId")
|
||||
public Result<List<SysUser>> getUsersByDepartId(@RequestParam(name = "id") String id) {
|
||||
Result<List<SysUser>> result = new Result<>();
|
||||
List<SysUser> sysUsers = sysUserDepartService.queryUserByDepId(id);
|
||||
result.setSuccess(true);
|
||||
result.setResult(sysUsers);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:根据id 批量查询
|
||||
* @param deptIds
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryByIds", method = RequestMethod.GET)
|
||||
public Result<Collection<SysDepart>> queryByIds(@RequestParam(name = "deptIds") String deptIds) {
|
||||
Result<Collection<SysDepart>> result = new Result<>();
|
||||
String[] ids = deptIds.split(",");
|
||||
Collection<String> idList = Arrays.asList(ids);
|
||||
Collection<SysDepart> deptList = sysDepartService.listByIds(idList);
|
||||
result.setSuccess(true);
|
||||
result.setResult(deptList);
|
||||
return result;
|
||||
}
|
||||
|
||||
@GetMapping("/getMyDepartList")
|
||||
public Result<List<SysDepart>> getMyDepartList(){
|
||||
List<SysDepart> list = sysDepartService.getMyDepartList();
|
||||
return Result.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步查询部门list
|
||||
* @param parentId 父节点 异步加载时传递
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryBookDepTreeSync", method = RequestMethod.GET)
|
||||
public Result<List<SysDepartTreeModel>> queryBookDepTreeSync(@RequestParam(name = "pid", required = false) String parentId,
|
||||
@RequestParam(name = "tenantId") Integer tenantId,
|
||||
@RequestParam(name = "departName",required = false) String departName) {
|
||||
Result<List<SysDepartTreeModel>> result = new Result<>();
|
||||
try {
|
||||
List<SysDepartTreeModel> list = sysDepartService.queryBookDepTreeSync(parentId, tenantId, departName);
|
||||
result.setResult(list);
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过部门id和租户id获取用户 【低代码应用: 用于选择部门负责人】
|
||||
* @param departId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUsersByDepartTenantId")
|
||||
public Result<List<SysUser>> getUsersByDepartTenantId(@RequestParam("departId") String departId){
|
||||
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
|
||||
List<SysUser> sysUserList = sysUserDepartService.getUsersByDepartTenantId(departId,tenantId);
|
||||
return Result.ok(sysUserList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel【低代码应用: 用于导出部门】
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
@RequestMapping(value = "/appExportXls")
|
||||
public ModelAndView appExportXls(SysDepart sysDepart,HttpServletRequest request) {
|
||||
// Step.1 组装查询条件
|
||||
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
List<ExportDepartVo> pageList = sysDepartService.getExcelDepart(tenantId);
|
||||
//Step.2 AutoPoi 导出Excel
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "部门列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, ExportDepartVo.class);
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("部门列表数据", "导出人:"+user.getRealname(), "导出信息"));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入excel【低代码应用: 用于导出部门】
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
@RequestMapping(value = "/appImportExcel", method = RequestMethod.POST)
|
||||
@CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
|
||||
public Result<?> appImportExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
List<String> errorMessageList = new ArrayList<>();
|
||||
List<ExportDepartVo> listSysDeparts = null;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 获取上传文件对象
|
||||
MultipartFile file = entity.getValue();
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), ExportDepartVo.class, params);
|
||||
sysDepartService.importExcel(listSysDeparts,errorMessageList);
|
||||
//清空部门缓存
|
||||
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||
redisTemplate.delete(keys3);
|
||||
redisTemplate.delete(keys4);
|
||||
return ImportExcelUtil.imporReturnRes(errorMessageList.size(), listSysDeparts.size() - errorMessageList.size(), errorMessageList);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return Result.error("文件导入失败:"+e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.error("文件导入失败!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,321 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.entity.SysDepartPermission;
|
||||
import org.jeecg.modules.system.entity.SysDepartRolePermission;
|
||||
import org.jeecg.modules.system.entity.SysPermission;
|
||||
import org.jeecg.modules.system.entity.SysPermissionDataRule;
|
||||
import org.jeecg.modules.system.model.TreeModel;
|
||||
import org.jeecg.modules.system.service.ISysDepartPermissionService;
|
||||
import org.jeecg.modules.system.service.ISysDepartRolePermissionService;
|
||||
import org.jeecg.modules.system.service.ISysPermissionDataRuleService;
|
||||
import org.jeecg.modules.system.service.ISysPermissionService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: 部门权限表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2020-02-11
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Tag(name="部门权限表")
|
||||
@RestController
|
||||
@RequestMapping("/sys/sysDepartPermission")
|
||||
public class SysDepartPermissionController extends JeecgController<SysDepartPermission, ISysDepartPermissionService> {
|
||||
@Autowired
|
||||
private ISysDepartPermissionService sysDepartPermissionService;
|
||||
|
||||
@Autowired
|
||||
private ISysPermissionDataRuleService sysPermissionDataRuleService;
|
||||
|
||||
@Autowired
|
||||
private ISysPermissionService sysPermissionService;
|
||||
|
||||
@Autowired
|
||||
private ISysDepartRolePermissionService sysDepartRolePermissionService;
|
||||
|
||||
@Autowired
|
||||
private BaseCommonService baseCommonService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysDepartPermission
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary="部门权限表-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(SysDepartPermission sysDepartPermission,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<SysDepartPermission> queryWrapper = QueryGenerator.initQueryWrapper(sysDepartPermission, req.getParameterMap());
|
||||
Page<SysDepartPermission> page = new Page<SysDepartPermission>(pageNo, pageSize);
|
||||
IPage<SysDepartPermission> pageList = sysDepartPermissionService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysDepartPermission
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary="部门权限表-添加")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysDepartPermission sysDepartPermission) {
|
||||
sysDepartPermissionService.save(sysDepartPermission);
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysDepartPermission
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary="部门权限表-编辑")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysDepartPermission sysDepartPermission) {
|
||||
sysDepartPermissionService.updateById(sysDepartPermission);
|
||||
return Result.ok("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary="部门权限表-通过id删除")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
|
||||
sysDepartPermissionService.removeById(id);
|
||||
return Result.ok("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary="部门权限表-批量删除")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.sysDepartPermissionService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary="部门权限表-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
SysDepartPermission sysDepartPermission = sysDepartPermissionService.getById(id);
|
||||
return Result.ok(sysDepartPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param sysDepartPermission
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysDepartPermission sysDepartPermission) {
|
||||
return super.exportXls(request, sysDepartPermission, SysDepartPermission.class, "部门权限表");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysDepartPermission.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 部门管理授权查询数据规则数据
|
||||
*/
|
||||
@GetMapping(value = "/datarule/{permissionId}/{departId}")
|
||||
public Result<?> loadDatarule(@PathVariable("permissionId") String permissionId,@PathVariable("departId") String departId) {
|
||||
List<SysPermissionDataRule> list = sysPermissionDataRuleService.getPermRuleListByPermId(permissionId);
|
||||
if(list==null || list.size()==0) {
|
||||
return Result.error("未找到权限配置信息");
|
||||
}else {
|
||||
Map<String,Object> map = new HashMap(5);
|
||||
map.put("datarule", list);
|
||||
LambdaQueryWrapper<SysDepartPermission> query = new LambdaQueryWrapper<SysDepartPermission>()
|
||||
.eq(SysDepartPermission::getPermissionId, permissionId)
|
||||
.eq(SysDepartPermission::getDepartId,departId);
|
||||
SysDepartPermission sysDepartPermission = sysDepartPermissionService.getOne(query);
|
||||
if(sysDepartPermission==null) {
|
||||
//return Result.error("未找到角色菜单配置信息");
|
||||
}else {
|
||||
String drChecked = sysDepartPermission.getDataRuleIds();
|
||||
if(oConvertUtils.isNotEmpty(drChecked)) {
|
||||
map.put("drChecked", drChecked.endsWith(",")?drChecked.substring(0, drChecked.length()-1):drChecked);
|
||||
}
|
||||
}
|
||||
return Result.ok(map);
|
||||
//TODO 以后按钮权限的查询也走这个请求 无非在map中多加两个key
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据规则至部门菜单关联表
|
||||
*/
|
||||
@PostMapping(value = "/datarule")
|
||||
public Result<?> saveDatarule(@RequestBody JSONObject jsonObject) {
|
||||
try {
|
||||
String permissionId = jsonObject.getString("permissionId");
|
||||
String departId = jsonObject.getString("departId");
|
||||
String dataRuleIds = jsonObject.getString("dataRuleIds");
|
||||
log.info("保存数据规则>>"+"菜单ID:"+permissionId+"部门ID:"+ departId+"数据权限ID:"+dataRuleIds);
|
||||
LambdaQueryWrapper<SysDepartPermission> query = new LambdaQueryWrapper<SysDepartPermission>()
|
||||
.eq(SysDepartPermission::getPermissionId, permissionId)
|
||||
.eq(SysDepartPermission::getDepartId,departId);
|
||||
SysDepartPermission sysDepartPermission = sysDepartPermissionService.getOne(query);
|
||||
if(sysDepartPermission==null) {
|
||||
return Result.error("请先保存部门菜单权限!");
|
||||
}else {
|
||||
sysDepartPermission.setDataRuleIds(dataRuleIds);
|
||||
this.sysDepartPermissionService.updateById(sysDepartPermission);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("SysDepartPermissionController.saveDatarule()发生异常:" + e.getMessage(),e);
|
||||
return Result.error("保存失败");
|
||||
}
|
||||
return Result.ok("保存成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询角色授权
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryDeptRolePermission", method = RequestMethod.GET)
|
||||
public Result<List<String>> queryDeptRolePermission(@RequestParam(name = "roleId", required = true) String roleId) {
|
||||
Result<List<String>> result = new Result<>();
|
||||
try {
|
||||
List<SysDepartRolePermission> list = sysDepartRolePermissionService.list(new QueryWrapper<SysDepartRolePermission>().lambda().eq(SysDepartRolePermission::getRoleId, roleId));
|
||||
result.setResult(list.stream().map(sysDepartRolePermission -> String.valueOf(sysDepartRolePermission.getPermissionId())).collect(Collectors.toList()));
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存角色授权
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/saveDeptRolePermission", method = RequestMethod.POST)
|
||||
public Result<String> saveDeptRolePermission(@RequestBody JSONObject json) {
|
||||
long start = System.currentTimeMillis();
|
||||
Result<String> result = new Result<>();
|
||||
try {
|
||||
String roleId = json.getString("roleId");
|
||||
String permissionIds = json.getString("permissionIds");
|
||||
String lastPermissionIds = json.getString("lastpermissionIds");
|
||||
this.sysDepartRolePermissionService.saveDeptRolePermission(roleId, permissionIds, lastPermissionIds);
|
||||
result.success("保存成功!");
|
||||
//update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]部门角色授权添加敏感日志------------
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
baseCommonService.addLog("修改部门角色ID:"+roleId+"的权限配置,操作人: " +loginUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
|
||||
//update-end---author:wangshuai ---date:20220316 for:[VUEN-234]部门角色授权添加敏感日志------------
|
||||
log.info("======部门角色授权成功=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
} catch (Exception e) {
|
||||
result.error500("授权失败!");
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户角色授权功能,查询菜单权限树
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryTreeListForDeptRole", method = RequestMethod.GET)
|
||||
public Result<Map<String,Object>> queryTreeListForDeptRole(@RequestParam(name="departId",required=true) String departId,HttpServletRequest request) {
|
||||
Result<Map<String,Object>> result = new Result<>();
|
||||
//全部权限ids
|
||||
List<String> ids = new ArrayList<>();
|
||||
try {
|
||||
List<SysPermission> list = sysPermissionService.queryDepartPermissionList(departId);
|
||||
for(SysPermission sysPer : list) {
|
||||
ids.add(sysPer.getId());
|
||||
}
|
||||
List<TreeModel> treeList = new ArrayList<>();
|
||||
getTreeModelList(treeList, list, null);
|
||||
Map<String,Object> resMap = new HashMap(5);
|
||||
//全部树节点数据
|
||||
resMap.put("treeList", treeList);
|
||||
//全部树ids
|
||||
resMap.put("ids", ids);
|
||||
result.setResult(resMap);
|
||||
result.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void getTreeModelList(List<TreeModel> treeList, List<SysPermission> metaList, TreeModel temp) {
|
||||
for (SysPermission permission : metaList) {
|
||||
String tempPid = permission.getParentId();
|
||||
TreeModel tree = new TreeModel(permission.getId(), tempPid, permission.getName(),permission.getRuleFlag(), permission.isLeaf());
|
||||
if(temp==null && oConvertUtils.isEmpty(tempPid)) {
|
||||
treeList.add(tree);
|
||||
if(!tree.getIsLeaf()) {
|
||||
getTreeModelList(treeList, metaList, tree);
|
||||
}
|
||||
}else if(temp!=null && tempPid!=null && tempPid.equals(temp.getKey())){
|
||||
temp.getChildren().add(tree);
|
||||
if(!tree.getIsLeaf()) {
|
||||
getTreeModelList(treeList, metaList, tree);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,310 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.service.*;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
* @Description: 部门角色
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2020-02-12
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Tag(name="部门角色")
|
||||
@RestController
|
||||
@RequestMapping("/sys/sysDepartRole")
|
||||
public class SysDepartRoleController extends JeecgController<SysDepartRole, ISysDepartRoleService> {
|
||||
@Autowired
|
||||
private ISysDepartRoleService sysDepartRoleService;
|
||||
|
||||
@Autowired
|
||||
private ISysDepartRoleUserService departRoleUserService;
|
||||
|
||||
@Autowired
|
||||
private ISysDepartPermissionService sysDepartPermissionService;
|
||||
|
||||
@Autowired
|
||||
private ISysDepartRolePermissionService sysDepartRolePermissionService;
|
||||
|
||||
@Autowired
|
||||
private ISysDepartService sysDepartService;
|
||||
|
||||
@Autowired
|
||||
private BaseCommonService baseCommonService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysDepartRole
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary="部门角色-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(SysDepartRole sysDepartRole,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
@RequestParam(name="deptId",required=false) String deptId,
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<SysDepartRole> queryWrapper = QueryGenerator.initQueryWrapper(sysDepartRole, req.getParameterMap());
|
||||
Page<SysDepartRole> page = new Page<SysDepartRole>(pageNo, pageSize);
|
||||
// LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
// List<String> deptIds = null;
|
||||
// if(oConvertUtils.isEmpty(deptId)){
|
||||
// if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals(CommonConstant.USER_IDENTITY_2) ){
|
||||
// deptIds = sysDepartService.getMySubDepIdsByDepId(user.getDepartIds());
|
||||
// }else{
|
||||
// return Result.ok(null);
|
||||
// }
|
||||
// }else{
|
||||
// deptIds = sysDepartService.getSubDepIdsByDepId(deptId);
|
||||
// }
|
||||
// queryWrapper.in("depart_id",deptIds);
|
||||
|
||||
//我的部门,选中部门只能看当前部门下的角色
|
||||
if(oConvertUtils.isNotEmpty(deptId)){
|
||||
queryWrapper.eq("depart_id",deptId);
|
||||
}
|
||||
|
||||
IPage<SysDepartRole> pageList = sysDepartRoleService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysDepartRole
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:depart:role:add")
|
||||
@Operation(summary="部门角色-添加")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysDepartRole sysDepartRole) {
|
||||
sysDepartRoleService.save(sysDepartRole);
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysDepartRole
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary="部门角色-编辑")
|
||||
@RequiresPermissions("system:depart:role:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysDepartRole sysDepartRole) {
|
||||
sysDepartRoleService.updateById(sysDepartRole);
|
||||
return Result.ok("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "部门角色-通过id删除")
|
||||
@Operation(summary="部门角色-通过id删除")
|
||||
@RequiresPermissions("system:depart:role:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
|
||||
sysDepartRoleService.removeById(id);
|
||||
return Result.ok("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "部门角色-批量删除")
|
||||
@Operation(summary="部门角色-批量删除")
|
||||
@RequiresPermissions("system:depart:role:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.sysDepartRoleService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary="部门角色-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
SysDepartRole sysDepartRole = sysDepartRoleService.getById(id);
|
||||
return Result.ok(sysDepartRole);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门下角色
|
||||
* @param departId
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/getDeptRoleList", method = RequestMethod.GET)
|
||||
public Result<List<SysDepartRole>> getDeptRoleList(@RequestParam(value = "departId") String departId,@RequestParam(value = "userId") String userId){
|
||||
Result<List<SysDepartRole>> result = new Result<>();
|
||||
//查询选中部门的角色
|
||||
List<SysDepartRole> deptRoleList = sysDepartRoleService.list(new LambdaQueryWrapper<SysDepartRole>().eq(SysDepartRole::getDepartId,departId));
|
||||
result.setSuccess(true);
|
||||
result.setResult(deptRoleList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param json
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:depart:role:userAdd")
|
||||
@RequestMapping(value = "/deptRoleUserAdd", method = RequestMethod.POST)
|
||||
public Result<?> deptRoleAdd(@RequestBody JSONObject json) {
|
||||
String newRoleId = json.getString("newRoleId");
|
||||
String oldRoleId = json.getString("oldRoleId");
|
||||
String userId = json.getString("userId");
|
||||
departRoleUserService.deptRoleUserAdd(userId,newRoleId,oldRoleId);
|
||||
//update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]部门角色分配添加敏感日志------------
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
baseCommonService.addLog("给部门用户ID:"+userId+"分配角色,操作人: " +loginUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
|
||||
//update-end---author:wangshuai ---date:20220316 for:[VUEN-234]部门角色分配添加敏感日志------------
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id获取已设置部门角色
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/getDeptRoleByUserId", method = RequestMethod.GET)
|
||||
public Result<List<SysDepartRoleUser>> getDeptRoleByUserId(@RequestParam(value = "userId") String userId,@RequestParam(value = "departId") String departId){
|
||||
Result<List<SysDepartRoleUser>> result = new Result<>();
|
||||
//查询部门下角色
|
||||
List<SysDepartRole> roleList = sysDepartRoleService.list(new QueryWrapper<SysDepartRole>().eq("depart_id",departId));
|
||||
List<String> roleIds = roleList.stream().map(SysDepartRole::getId).collect(Collectors.toList());
|
||||
//根据角色id,用户id查询已授权角色
|
||||
List<SysDepartRoleUser> roleUserList = null;
|
||||
if(roleIds!=null && roleIds.size()>0){
|
||||
roleUserList = departRoleUserService.list(new QueryWrapper<SysDepartRoleUser>().eq("user_id",userId).in("drole_id",roleIds));
|
||||
}
|
||||
result.setSuccess(true);
|
||||
result.setResult(roleUserList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据规则数据
|
||||
*/
|
||||
@GetMapping(value = "/datarule/{permissionId}/{departId}/{roleId}")
|
||||
public Result<?> loadDatarule(@PathVariable("permissionId") String permissionId,@PathVariable("departId") String departId,@PathVariable("roleId") String roleId) {
|
||||
//查询已授权的部门规则
|
||||
List<SysPermissionDataRule> list = sysDepartPermissionService.getPermRuleListByDeptIdAndPermId(departId,permissionId);
|
||||
if(list==null || list.size()==0) {
|
||||
return Result.error("未找到权限配置信息");
|
||||
}else {
|
||||
Map<String,Object> map = new HashMap(5);
|
||||
map.put("datarule", list);
|
||||
LambdaQueryWrapper<SysDepartRolePermission> query = new LambdaQueryWrapper<SysDepartRolePermission>()
|
||||
.eq(SysDepartRolePermission::getPermissionId, permissionId)
|
||||
.eq(SysDepartRolePermission::getRoleId,roleId);
|
||||
SysDepartRolePermission sysRolePermission = sysDepartRolePermissionService.getOne(query);
|
||||
if(sysRolePermission==null) {
|
||||
//return Result.error("未找到角色菜单配置信息");
|
||||
}else {
|
||||
String drChecked = sysRolePermission.getDataRuleIds();
|
||||
if(oConvertUtils.isNotEmpty(drChecked)) {
|
||||
map.put("drChecked", drChecked.endsWith(",")?drChecked.substring(0, drChecked.length()-1):drChecked);
|
||||
}
|
||||
}
|
||||
return Result.ok(map);
|
||||
//TODO 以后按钮权限的查询也走这个请求 无非在map中多加两个key
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据规则至角色菜单关联表
|
||||
*/
|
||||
@PostMapping(value = "/datarule")
|
||||
public Result<?> saveDatarule(@RequestBody JSONObject jsonObject) {
|
||||
try {
|
||||
String permissionId = jsonObject.getString("permissionId");
|
||||
String roleId = jsonObject.getString("roleId");
|
||||
String dataRuleIds = jsonObject.getString("dataRuleIds");
|
||||
log.info("保存数据规则>>"+"菜单ID:"+permissionId+"角色ID:"+ roleId+"数据权限ID:"+dataRuleIds);
|
||||
LambdaQueryWrapper<SysDepartRolePermission> query = new LambdaQueryWrapper<SysDepartRolePermission>()
|
||||
.eq(SysDepartRolePermission::getPermissionId, permissionId)
|
||||
.eq(SysDepartRolePermission::getRoleId,roleId);
|
||||
SysDepartRolePermission sysRolePermission = sysDepartRolePermissionService.getOne(query);
|
||||
if(sysRolePermission==null) {
|
||||
return Result.error("请先保存角色菜单权限!");
|
||||
}else {
|
||||
sysRolePermission.setDataRuleIds(dataRuleIds);
|
||||
this.sysDepartRolePermissionService.updateById(sysRolePermission);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("SysRoleController.saveDatarule()发生异常:" + e.getMessage(),e);
|
||||
return Result.error("保存失败");
|
||||
}
|
||||
return Result.ok("保存成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param sysDepartRole
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysDepartRole sysDepartRole) {
|
||||
return super.exportXls(request, sysDepartRole, SysDepartRole.class, "部门角色");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysDepartRole.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,721 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.system.vo.DictQuery;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.ImportExcelUtil;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.TokenUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.config.shiro.ShiroRealm;
|
||||
import org.jeecg.modules.system.entity.SysDict;
|
||||
import org.jeecg.modules.system.entity.SysDictItem;
|
||||
import org.jeecg.modules.system.model.SysDictTree;
|
||||
import org.jeecg.modules.system.model.TreeSelectModel;
|
||||
import org.jeecg.modules.system.service.ISysDictItemService;
|
||||
import org.jeecg.modules.system.service.ISysDictService;
|
||||
import org.jeecg.modules.system.vo.SysDictPage;
|
||||
import org.jeecg.modules.system.vo.lowapp.SysDictVo;
|
||||
import org.jeecgframework.poi.excel.ExcelImportCheckUtil;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 字典表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @Author zhangweijian
|
||||
* @since 2018-12-28
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/dict")
|
||||
@Slf4j
|
||||
public class SysDictController {
|
||||
|
||||
@Autowired
|
||||
private ISysDictService sysDictService;
|
||||
@Autowired
|
||||
private ISysDictItemService sysDictItemService;
|
||||
@Autowired
|
||||
public RedisTemplate<String, Object> redisTemplate;
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
@Autowired
|
||||
private ShiroRealm shiroRealm;
|
||||
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
|
||||
Result<IPage<SysDict>> result = new Result<IPage<SysDict>>();
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysDict.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(),0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
QueryWrapper<SysDict> queryWrapper = QueryGenerator.initQueryWrapper(sysDict, req.getParameterMap());
|
||||
Page<SysDict> page = new Page<SysDict>(pageNo, pageSize);
|
||||
IPage<SysDict> pageList = sysDictService.page(page, queryWrapper);
|
||||
log.debug("查询当前页:"+pageList.getCurrent());
|
||||
log.debug("查询当前页数量:"+pageList.getSize());
|
||||
log.debug("查询结果数量:"+pageList.getRecords().size());
|
||||
log.debug("数据总数:"+pageList.getTotal());
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:获取树形字典数据
|
||||
* @param sysDict
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@RequestMapping(value = "/treeList", method = RequestMethod.GET)
|
||||
public Result<List<SysDictTree>> treeList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
|
||||
Result<List<SysDictTree>> result = new Result<>();
|
||||
LambdaQueryWrapper<SysDict> query = new LambdaQueryWrapper<>();
|
||||
// 构造查询条件
|
||||
String dictName = sysDict.getDictName();
|
||||
if(oConvertUtils.isNotEmpty(dictName)) {
|
||||
query.like(true, SysDict::getDictName, dictName);
|
||||
}
|
||||
query.orderByDesc(true, SysDict::getCreateTime);
|
||||
List<SysDict> list = sysDictService.list(query);
|
||||
List<SysDictTree> treeList = new ArrayList<>();
|
||||
for (SysDict node : list) {
|
||||
treeList.add(new SysDictTree(node));
|
||||
}
|
||||
result.setSuccess(true);
|
||||
result.setResult(treeList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部字典数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryAllDictItems", method = RequestMethod.GET)
|
||||
public Result<?> queryAllDictItems(HttpServletRequest request) {
|
||||
Map<String, List<DictModel>> res = new HashMap(5);
|
||||
res = sysDictService.queryAllDictItems();
|
||||
return Result.ok(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典数据
|
||||
* @param dictCode
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/getDictText/{dictCode}/{key}", method = RequestMethod.GET)
|
||||
public Result<String> getDictText(@PathVariable("dictCode") String dictCode, @PathVariable("key") String key) {
|
||||
log.info(" dictCode : "+ dictCode);
|
||||
Result<String> result = new Result<String>();
|
||||
String text = null;
|
||||
try {
|
||||
text = sysDictService.queryDictTextByKey(dictCode, key);
|
||||
result.setSuccess(true);
|
||||
result.setResult(text);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取字典数据 【接口签名验证】
|
||||
* @param dictCode 字典code
|
||||
* @param dictCode 表名,文本字段,code字段 | 举例:sys_user,realname,id
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
|
||||
public Result<List<DictModel>> getDictItems(@PathVariable("dictCode") String dictCode, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
|
||||
log.info(" dictCode : "+ dictCode);
|
||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
try {
|
||||
List<DictModel> ls = sysDictService.getDictItems(dictCode);
|
||||
if (ls == null) {
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
log.debug(result.toString());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
result.error500("操作失败");
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【接口签名验证】
|
||||
* 【JSearchSelectTag下拉搜索组件专用接口】
|
||||
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||
* @param dictCode 字典code格式:table,text,code
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadDict/{dictCode}", method = RequestMethod.GET)
|
||||
public Result<List<DictModel>> loadDict(@PathVariable("dictCode") String dictCode,
|
||||
@RequestParam(name="keyword",required = false) String keyword,
|
||||
@RequestParam(value = "sign",required = false) String sign,
|
||||
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
||||
|
||||
//update-begin-author:taoyan date:2023-5-22 for: /issues/4905 因为中括号(%5)的问题导致的 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905 RouteToRequestUrlFilter
|
||||
if(keyword!=null && keyword.indexOf("%5")>=0){
|
||||
try {
|
||||
keyword = URLDecoder.decode(keyword, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error("下拉搜索关键字解码失败", e);
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2023-5-22 for: /issues/4905 因为中括号(%5)的问题导致的 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
|
||||
|
||||
log.info(" 加载字典表数据,加载关键字: "+ keyword);
|
||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
try {
|
||||
List<DictModel> ls = sysDictService.loadDict(dictCode, keyword, pageSize);
|
||||
if (ls == null) {
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
log.info(result.toString());
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败:" + e.getMessage());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【接口签名验证】
|
||||
* 【给表单设计器的表字典使用】下拉搜索模式,有值时动态拼接数据
|
||||
* @param dictCode
|
||||
* @param keyword 当前控件的值,可以逗号分割
|
||||
* @param sign
|
||||
* @param pageSize
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadDictOrderByValue/{dictCode}", method = RequestMethod.GET)
|
||||
public Result<List<DictModel>> loadDictOrderByValue(
|
||||
@PathVariable("dictCode") String dictCode,
|
||||
@RequestParam(name = "keyword") String keyword,
|
||||
@RequestParam(value = "sign", required = false) String sign,
|
||||
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
||||
// 首次查询查出来用户选中的值,并且不分页
|
||||
Result<List<DictModel>> firstRes = this.loadDict(dictCode, keyword, sign, null);
|
||||
if (!firstRes.isSuccess()) {
|
||||
return firstRes;
|
||||
}
|
||||
// 然后再查询出第一页的数据
|
||||
Result<List<DictModel>> result = this.loadDict(dictCode, "", sign, pageSize);
|
||||
if (!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
// 合并两次查询的数据
|
||||
List<DictModel> firstList = firstRes.getResult();
|
||||
List<DictModel> list = result.getResult();
|
||||
for (DictModel firstItem : firstList) {
|
||||
// anyMatch 表示:判断的条件里,任意一个元素匹配成功,返回true
|
||||
// allMatch 表示:判断条件里的元素,所有的都匹配成功,返回true
|
||||
// noneMatch 跟 allMatch 相反,表示:判断条件里的元素,所有的都匹配失败,返回true
|
||||
boolean none = list.stream().noneMatch(item -> item.getValue().equals(firstItem.getValue()));
|
||||
// 当元素不存在时,再添加到集合里
|
||||
if (none) {
|
||||
list.add(0, firstItem);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【接口签名验证】
|
||||
* 根据字典code加载字典text 返回
|
||||
* @param dictCode 顺序:tableName,text,code
|
||||
* @param keys 要查询的key
|
||||
* @param sign
|
||||
* @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadDictItem/{dictCode}", method = RequestMethod.GET)
|
||||
public Result<List<String>> loadDictItem(@PathVariable("dictCode") String dictCode,@RequestParam(name="key") String keys, @RequestParam(value = "sign",required = false) String sign,@RequestParam(value = "delNotExist",required = false,defaultValue = "true") boolean delNotExist,HttpServletRequest request) {
|
||||
Result<List<String>> result = new Result<>();
|
||||
try {
|
||||
if(dictCode.indexOf(SymbolConstant.COMMA)!=-1) {
|
||||
String[] params = dictCode.split(SymbolConstant.COMMA);
|
||||
if(params.length!=3) {
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
List<String> texts = sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys, delNotExist);
|
||||
|
||||
result.setSuccess(true);
|
||||
result.setResult(texts);
|
||||
log.info(result.toString());
|
||||
}else {
|
||||
result.error500("字典Code格式不正确!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【接口签名验证】
|
||||
* 根据表名——显示字段-存储字段 pid 加载树形数据
|
||||
* @param hasChildField 是否叶子节点字段
|
||||
* @param converIsLeafVal 是否需要系统转换 是否叶子节点的值 (0标识不转换、1标准系统自动转换)
|
||||
* @param tableName 表名
|
||||
* @param text label字段
|
||||
* @param code value 字段
|
||||
* @param condition 查询条件 ?
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@RequestMapping(value = "/loadTreeData", method = RequestMethod.GET)
|
||||
public Result<List<TreeSelectModel>> loadTreeData(@RequestParam(name="pid",required = false) String pid,@RequestParam(name="pidField") String pidField,
|
||||
@RequestParam(name="tableName") String tableName,
|
||||
@RequestParam(name="text") String text,
|
||||
@RequestParam(name="code") String code,
|
||||
@RequestParam(name="hasChildField") String hasChildField,
|
||||
@RequestParam(name="converIsLeafVal",defaultValue ="1") int converIsLeafVal,
|
||||
@RequestParam(name="condition") String condition,
|
||||
@RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
|
||||
Result<List<TreeSelectModel>> result = new Result<List<TreeSelectModel>>();
|
||||
|
||||
// 【QQYUN-9207】防止参数为空导致报错
|
||||
if (oConvertUtils.isEmpty(tableName) || oConvertUtils.isEmpty(text) || oConvertUtils.isEmpty(code)) {
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
|
||||
// 1.获取查询条件参数
|
||||
Map<String, String> query = null;
|
||||
if(oConvertUtils.isNotEmpty(condition)) {
|
||||
query = JSON.parseObject(condition, Map.class);
|
||||
}
|
||||
|
||||
// 2.返回查询结果
|
||||
List<TreeSelectModel> ls = sysDictService.queryTreeList(query,tableName, text, code, pidField, pid,hasChildField,converIsLeafVal);
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【APP接口】根据字典配置查询表字典数据(目前暂未找到调用的地方)
|
||||
* @param query
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
@GetMapping("/queryTableData")
|
||||
public Result<List<DictModel>> queryTableData(DictQuery query,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(value = "sign",required = false) String sign,HttpServletRequest request){
|
||||
Result<List<DictModel>> res = new Result<List<DictModel>>();
|
||||
List<DictModel> ls = this.sysDictService.queryDictTablePageList(query,pageSize,pageNo);
|
||||
res.setResult(ls);
|
||||
res.setSuccess(true);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:新增
|
||||
* @param sysDict
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:dict:add")
|
||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||
public Result<SysDict> add(@RequestBody SysDict sysDict) {
|
||||
Result<SysDict> result = new Result<SysDict>();
|
||||
try {
|
||||
sysDict.setCreateTime(new Date());
|
||||
sysDict.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
sysDictService.save(sysDict);
|
||||
result.success("保存成功!");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:编辑
|
||||
* @param sysDict
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:dict:edit")
|
||||
@RequestMapping(value = "/edit", method = { RequestMethod.PUT,RequestMethod.POST })
|
||||
public Result<SysDict> edit(@RequestBody SysDict sysDict) {
|
||||
Result<SysDict> result = new Result<SysDict>();
|
||||
SysDict sysdict = sysDictService.getById(sysDict.getId());
|
||||
if(sysdict==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
sysDict.setUpdateTime(new Date());
|
||||
boolean ok = sysDictService.updateById(sysDict);
|
||||
if(ok) {
|
||||
result.success("编辑成功!");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:删除
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:dict:delete")
|
||||
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
|
||||
@CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true)
|
||||
public Result<SysDict> delete(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysDict> result = new Result<SysDict>();
|
||||
boolean ok = sysDictService.removeById(id);
|
||||
if(ok) {
|
||||
result.success("删除成功!");
|
||||
}else{
|
||||
result.error500("删除失败!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:批量删除
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:dict:deleteBatch")
|
||||
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
|
||||
@CacheEvict(value= {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true)
|
||||
public Result<SysDict> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
Result<SysDict> result = new Result<SysDict>();
|
||||
if(oConvertUtils.isEmpty(ids)) {
|
||||
result.error500("参数不识别!");
|
||||
}else {
|
||||
sysDictService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:刷新缓存
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/refleshCache")
|
||||
public Result<?> refleshCache() {
|
||||
Result<?> result = new Result<SysDict>();
|
||||
//清空字典缓存
|
||||
// Set keys = redisTemplate.keys(CacheConstant.SYS_DICT_CACHE + "*");
|
||||
// Set keys7 = redisTemplate.keys(CacheConstant.SYS_ENABLE_DICT_CACHE + "*");
|
||||
// Set keys2 = redisTemplate.keys(CacheConstant.SYS_DICT_TABLE_CACHE + "*");
|
||||
// Set keys21 = redisTemplate.keys(CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE + "*");
|
||||
// Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
// Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||
// Set keys5 = redisTemplate.keys( "jmreport:cache:dict*");
|
||||
// Set keys6 = redisTemplate.keys( "jmreport:cache:dictTable*");
|
||||
// redisTemplate.delete(keys);
|
||||
// redisTemplate.delete(keys2);
|
||||
// redisTemplate.delete(keys21);
|
||||
// redisTemplate.delete(keys3);
|
||||
// redisTemplate.delete(keys4);
|
||||
// redisTemplate.delete(keys5);
|
||||
// redisTemplate.delete(keys6);
|
||||
// redisTemplate.delete(keys7);
|
||||
|
||||
//update-begin-author:liusq date:20230404 for: [issue/4358]springCache中的清除缓存的操作使用了“keys”
|
||||
redisUtil.removeAll(CacheConstant.SYS_DICT_CACHE);
|
||||
redisUtil.removeAll(CacheConstant.SYS_ENABLE_DICT_CACHE);
|
||||
redisUtil.removeAll(CacheConstant.SYS_DICT_TABLE_CACHE);
|
||||
redisUtil.removeAll(CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE);
|
||||
redisUtil.removeAll(CacheConstant.SYS_DEPARTS_CACHE);
|
||||
redisUtil.removeAll(CacheConstant.SYS_DEPART_IDS_CACHE);
|
||||
redisUtil.removeAll("jmreport:cache:dict");
|
||||
redisUtil.removeAll("jmreport:cache:dictTable");
|
||||
//update-end-author:liusq date:20230404 for: [issue/4358]springCache中的清除缓存的操作使用了“keys”
|
||||
|
||||
//update-begin---author:scott ---date:2024-06-18 for:【TV360X-1320】分配权限必须退出重新登录才生效,造成很多用户困扰---
|
||||
// 清除当前用户的授权缓存信息
|
||||
Subject currentUser = SecurityUtils.getSubject();
|
||||
if (currentUser.isAuthenticated()) {
|
||||
shiroRealm.clearCache(currentUser.getPrincipals());
|
||||
}
|
||||
//update-end---author:scott ---date::2024-06-18 for:【TV360X-1320】分配权限必须退出重新登录才生效,造成很多用户困扰---
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(SysDict sysDict,HttpServletRequest request) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysDict.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
// Step.1 组装查询条件
|
||||
QueryWrapper<SysDict> queryWrapper = QueryGenerator.initQueryWrapper(sysDict, request.getParameterMap());
|
||||
//Step.2 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
String selections = request.getParameter("selections");
|
||||
if(!oConvertUtils.isEmpty(selections)){
|
||||
queryWrapper.in("id",selections.split(","));
|
||||
}
|
||||
List<SysDictPage> pageList = new ArrayList<SysDictPage>();
|
||||
|
||||
List<SysDict> sysDictList = sysDictService.list(queryWrapper);
|
||||
for (SysDict dictMain : sysDictList) {
|
||||
SysDictPage vo = new SysDictPage();
|
||||
BeanUtils.copyProperties(dictMain, vo);
|
||||
// 查询机票
|
||||
List<SysDictItem> sysDictItemList = sysDictItemService.selectItemsByMainId(dictMain.getId());
|
||||
vo.setSysDictItemList(sysDictItemList);
|
||||
pageList.add(vo);
|
||||
}
|
||||
|
||||
// 导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "数据字典");
|
||||
// 注解对象Class
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysDictPage.class);
|
||||
// 自定义表格参数
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("数据字典列表", "导出人:"+user.getRealname(), "数据字典"));
|
||||
// 导出数据列表
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:dict:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 获取上传文件对象
|
||||
MultipartFile file = entity.getValue();
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(2);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
//导入Excel格式校验,看匹配的字段文本概率
|
||||
Boolean t = ExcelImportCheckUtil.check(file.getInputStream(), SysDictPage.class, params);
|
||||
if(t!=null && !t){
|
||||
throw new RuntimeException("导入Excel校验失败 !");
|
||||
}
|
||||
List<SysDictPage> list = ExcelImportUtil.importExcel(file.getInputStream(), SysDictPage.class, params);
|
||||
// 错误信息
|
||||
List<String> errorMessage = new ArrayList<>();
|
||||
int successLines = 0, errorLines = 0;
|
||||
for (int i=0;i< list.size();i++) {
|
||||
SysDict po = new SysDict();
|
||||
BeanUtils.copyProperties(list.get(i), po);
|
||||
po.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
try {
|
||||
Integer integer = sysDictService.saveMain(po, list.get(i).getSysDictItemList());
|
||||
if(integer>0){
|
||||
successLines++;
|
||||
//update-begin---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
}else if(integer == -1){
|
||||
errorLines++;
|
||||
errorMessage.add("字典名称:" + po.getDictName() + ",对应字典列表的字典项值不能为空,忽略导入。");
|
||||
}else{
|
||||
//update-end---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
errorLines++;
|
||||
int lineNumber = i + 1;
|
||||
//update-begin---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------
|
||||
if(oConvertUtils.isEmpty(po.getDictCode())){
|
||||
errorMessage.add("第 " + lineNumber + " 行:字典编码不能为空,忽略导入。");
|
||||
}else{
|
||||
errorMessage.add("第 " + lineNumber + " 行:字典编码已经存在,忽略导入。");
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------
|
||||
}
|
||||
} catch (Exception e) {
|
||||
errorLines++;
|
||||
int lineNumber = i + 1;
|
||||
errorMessage.add("第 " + lineNumber + " 行:字典编码已经存在,忽略导入。");
|
||||
}
|
||||
}
|
||||
return ImportExcelUtil.imporReturnRes(errorLines,successLines,errorMessage);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return Result.error("文件导入失败:"+e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.error("文件导入失败!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询被删除的列表
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/deleteList", method = RequestMethod.GET)
|
||||
public Result<List<SysDict>> deleteList(HttpServletRequest request) {
|
||||
Result<List<SysDict>> result = new Result<List<SysDict>>();
|
||||
String tenantId = TokenUtils.getTenantIdByRequest(request);
|
||||
List<SysDict> list = this.sysDictService.queryDeleteList(tenantId);
|
||||
result.setSuccess(true);
|
||||
result.setResult(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 物理删除
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/deletePhysic/{id}", method = RequestMethod.DELETE)
|
||||
public Result<?> deletePhysic(@PathVariable("id") String id) {
|
||||
try {
|
||||
sysDictService.deleteOneDictPhysically(id);
|
||||
return Result.ok("删除成功!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error("删除失败!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 逻辑删除的字段,进行取回
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/back/{id}", method = RequestMethod.PUT)
|
||||
public Result<?> back(@PathVariable("id") String id) {
|
||||
try {
|
||||
sysDictService.updateDictDelFlag(0,id);
|
||||
return Result.ok("操作成功!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error("操作失败!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* VUEN-2584【issue】平台sql注入漏洞几个问题
|
||||
* 部分特殊函数 可以将查询结果混夹在错误信息中,导致数据库的信息暴露
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler(java.sql.SQLException.class)
|
||||
public Result<?> handleSQLException(Exception e){
|
||||
String msg = e.getMessage();
|
||||
String extractvalue = "extractvalue";
|
||||
String updatexml = "updatexml";
|
||||
if(msg!=null && (msg.toLowerCase().indexOf(extractvalue)>=0 || msg.toLowerCase().indexOf(updatexml)>=0)){
|
||||
return Result.error("校验失败,sql解析异常!");
|
||||
}
|
||||
return Result.error("校验失败,sql解析异常!" + msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据应用id获取字典列表和详情
|
||||
* @param request
|
||||
*/
|
||||
@GetMapping("/getDictListByLowAppId")
|
||||
public Result<List<SysDictVo>> getDictListByLowAppId(HttpServletRequest request){
|
||||
String lowAppId = oConvertUtils.getString(TokenUtils.getLowAppIdByRequest(request));
|
||||
List<SysDictVo> list = sysDictService.getDictListByLowAppId(lowAppId);
|
||||
return Result.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加字典
|
||||
* @param sysDictVo
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/addDictByLowAppId")
|
||||
public Result<String> addDictByLowAppId(@RequestBody SysDictVo sysDictVo,HttpServletRequest request){
|
||||
String lowAppId = oConvertUtils.getString(TokenUtils.getLowAppIdByRequest(request));
|
||||
String tenantId = oConvertUtils.getString(TokenUtils.getTenantIdByRequest(request));
|
||||
sysDictVo.setLowAppId(lowAppId);
|
||||
sysDictVo.setTenantId(oConvertUtils.getInteger(tenantId, null));
|
||||
sysDictService.addDictByLowAppId(sysDictVo);
|
||||
return Result.ok("添加成功");
|
||||
}
|
||||
|
||||
@PutMapping("/editDictByLowAppId")
|
||||
public Result<String> editDictByLowAppId(@RequestBody SysDictVo sysDictVo,HttpServletRequest request){
|
||||
String lowAppId = oConvertUtils.getString(TokenUtils.getLowAppIdByRequest(request));
|
||||
sysDictVo.setLowAppId(lowAppId);
|
||||
sysDictService.editDictByLowAppId(sysDictVo);
|
||||
return Result.ok("编辑成功");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,186 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysDictItem;
|
||||
import org.jeecg.modules.system.service.ISysDictItemService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @Author zhangweijian
|
||||
* @since 2018-12-28
|
||||
*/
|
||||
@Tag(name = "数据字典")
|
||||
@RestController
|
||||
@RequestMapping("/sys/dictItem")
|
||||
@Slf4j
|
||||
public class SysDictItemController {
|
||||
|
||||
@Autowired
|
||||
private ISysDictItemService sysDictItemService;
|
||||
|
||||
/**
|
||||
* @功能:查询字典数据
|
||||
* @param sysDictItem
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
public Result<IPage<SysDictItem>> queryPageList(SysDictItem sysDictItem,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
|
||||
Result<IPage<SysDictItem>> result = new Result<IPage<SysDictItem>>();
|
||||
QueryWrapper<SysDictItem> queryWrapper = QueryGenerator.initQueryWrapper(sysDictItem, req.getParameterMap());
|
||||
queryWrapper.orderByAsc("sort_order");
|
||||
Page<SysDictItem> page = new Page<SysDictItem>(pageNo, pageSize);
|
||||
IPage<SysDictItem> pageList = sysDictItemService.page(page, queryWrapper);
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:新增
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:dict:item:add")
|
||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||
@CacheEvict(value= {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true)
|
||||
public Result<SysDictItem> add(@RequestBody SysDictItem sysDictItem) {
|
||||
Result<SysDictItem> result = new Result<SysDictItem>();
|
||||
try {
|
||||
sysDictItem.setCreateTime(new Date());
|
||||
sysDictItemService.save(sysDictItem);
|
||||
result.success("保存成功!");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:编辑
|
||||
* @param sysDictItem
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:dict:item:edit")
|
||||
@RequestMapping(value = "/edit", method = { RequestMethod.PUT,RequestMethod.POST })
|
||||
@CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true)
|
||||
public Result<SysDictItem> edit(@RequestBody SysDictItem sysDictItem) {
|
||||
Result<SysDictItem> result = new Result<SysDictItem>();
|
||||
SysDictItem sysdict = sysDictItemService.getById(sysDictItem.getId());
|
||||
if(sysdict==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
sysDictItem.setUpdateTime(new Date());
|
||||
boolean ok = sysDictItemService.updateById(sysDictItem);
|
||||
//TODO 返回false说明什么?
|
||||
if(ok) {
|
||||
result.success("编辑成功!");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:删除字典数据
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:dict:item:delete")
|
||||
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
|
||||
@CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true)
|
||||
public Result<SysDictItem> delete(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysDictItem> result = new Result<SysDictItem>();
|
||||
SysDictItem joinSystem = sysDictItemService.getById(id);
|
||||
if(joinSystem==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
boolean ok = sysDictItemService.removeById(id);
|
||||
if(ok) {
|
||||
result.success("删除成功!");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @功能:批量删除字典数据
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:dict:item:deleteBatch")
|
||||
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
|
||||
@CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true)
|
||||
public Result<SysDictItem> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
Result<SysDictItem> result = new Result<SysDictItem>();
|
||||
if(ids==null || "".equals(ids.trim())) {
|
||||
result.error500("参数不识别!");
|
||||
}else {
|
||||
this.sysDictItemService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典值重复校验
|
||||
* @param sysDictItem
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/dictItemCheck", method = RequestMethod.GET)
|
||||
@Operation(summary = "字典重复校验接口")
|
||||
public Result<Object> doDictItemCheck(SysDictItem sysDictItem, HttpServletRequest request) {
|
||||
Long num = Long.valueOf(0);
|
||||
LambdaQueryWrapper<SysDictItem> queryWrapper = new LambdaQueryWrapper<SysDictItem>();
|
||||
queryWrapper.eq(SysDictItem::getItemValue,sysDictItem.getItemValue());
|
||||
queryWrapper.eq(SysDictItem::getDictId,sysDictItem.getDictId());
|
||||
if (StringUtils.isNotBlank(sysDictItem.getId())) {
|
||||
// 编辑页面校验
|
||||
queryWrapper.ne(SysDictItem::getId,sysDictItem.getId());
|
||||
}
|
||||
num = sysDictItemService.count(queryWrapper);
|
||||
if (num == 0) {
|
||||
// 该值可用
|
||||
return Result.ok("该值可用!");
|
||||
} else {
|
||||
// 该值不可用
|
||||
log.info("该值不可用,系统中已存在!");
|
||||
return Result.error("该值不可用,系统中已存在!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,213 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.util.FillRuleUtil;
|
||||
import org.jeecg.modules.system.entity.SysFillRule;
|
||||
import org.jeecg.modules.system.service.ISysFillRuleService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Description: 填值规则
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2019-11-07
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Tag(name = "填值规则")
|
||||
@RestController
|
||||
@RequestMapping("/sys/fillRule")
|
||||
public class SysFillRuleController extends JeecgController<SysFillRule, ISysFillRuleService> {
|
||||
@Autowired
|
||||
private ISysFillRuleService sysFillRuleService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysFillRule
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "填值规则-分页列表查询")
|
||||
@Operation(summary = "填值规则-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(SysFillRule sysFillRule,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<SysFillRule> queryWrapper = QueryGenerator.initQueryWrapper(sysFillRule, req.getParameterMap());
|
||||
Page<SysFillRule> page = new Page<>(pageNo, pageSize);
|
||||
IPage<SysFillRule> pageList = sysFillRuleService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试 ruleCode
|
||||
*
|
||||
* @param ruleCode
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/testFillRule")
|
||||
public Result testFillRule(@RequestParam("ruleCode") String ruleCode) {
|
||||
Object result = FillRuleUtil.executeRule(ruleCode, new JSONObject());
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysFillRule
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "填值规则-添加")
|
||||
@Operation(summary = "填值规则-添加")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysFillRule sysFillRule) {
|
||||
sysFillRuleService.save(sysFillRule);
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysFillRule
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "填值规则-编辑")
|
||||
@Operation(summary = "填值规则-编辑")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysFillRule sysFillRule) {
|
||||
sysFillRuleService.updateById(sysFillRule);
|
||||
return Result.ok("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "填值规则-通过id删除")
|
||||
@Operation(summary = "填值规则-通过id删除")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
sysFillRuleService.removeById(id);
|
||||
return Result.ok("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "填值规则-批量删除")
|
||||
@Operation(summary = "填值规则-批量删除")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
this.sysFillRuleService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "填值规则-通过id查询")
|
||||
@Operation(summary = "填值规则-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
SysFillRule sysFillRule = sysFillRuleService.getById(id);
|
||||
return Result.ok(sysFillRule);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param sysFillRule
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysFillRule sysFillRule) {
|
||||
return super.exportXls(request, sysFillRule, SysFillRule.class, "填值规则");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysFillRule.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 ruleCode 执行自定义填值规则
|
||||
*
|
||||
* @param ruleCode 要执行的填值规则编码
|
||||
* @param formData 表单数据,可根据表单数据的不同生成不同的填值结果
|
||||
* @return 运行后的结果
|
||||
*/
|
||||
@PutMapping("/executeRuleByCode/{ruleCode}")
|
||||
public Result executeByRuleCode(@PathVariable("ruleCode") String ruleCode, @RequestBody JSONObject formData) {
|
||||
Object result = FillRuleUtil.executeRule(ruleCode, formData);
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量通过 ruleCode 执行自定义填值规则
|
||||
*
|
||||
* @param ruleData 要执行的填值规则JSON数组:
|
||||
* 示例: { "commonFormData": {}, rules: [ { "ruleCode": "xxx", "formData": null } ] }
|
||||
* @return 运行后的结果,返回示例: [{"ruleCode": "order_num_rule", "result": "CN2019111117212984"}]
|
||||
*
|
||||
*/
|
||||
@PutMapping("/executeRuleByCodeBatch")
|
||||
public Result executeByRuleCodeBatch(@RequestBody JSONObject ruleData) {
|
||||
JSONObject commonFormData = ruleData.getJSONObject("commonFormData");
|
||||
JSONArray rules = ruleData.getJSONArray("rules");
|
||||
// 遍历 rules ,批量执行规则
|
||||
JSONArray results = new JSONArray(rules.size());
|
||||
for (int i = 0; i < rules.size(); i++) {
|
||||
JSONObject rule = rules.getJSONObject(i);
|
||||
String ruleCode = rule.getString("ruleCode");
|
||||
JSONObject formData = rule.getJSONObject("formData");
|
||||
// 如果没有传递 formData,就用common的
|
||||
if (formData == null) {
|
||||
formData = commonFormData;
|
||||
}
|
||||
// 执行填值规则
|
||||
Object result = FillRuleUtil.executeRule(ruleCode, formData);
|
||||
JSONObject obj = new JSONObject(rules.size());
|
||||
obj.put("ruleCode", ruleCode);
|
||||
obj.put("result", result);
|
||||
results.add(obj);
|
||||
}
|
||||
return Result.ok(results);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,152 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.system.entity.SysFormFile;
|
||||
import org.jeecg.modules.system.service.ISysFormFileService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Description: 表单评论文件
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2022-07-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Tag(name = "表单评论文件")
|
||||
@RestController
|
||||
@RequestMapping("/sys/formFile")
|
||||
public class SysFormFileController extends JeecgController<SysFormFile, ISysFormFileService> {
|
||||
@Autowired
|
||||
private ISysFormFileService sysFormFileService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysFormFile
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "表单评论文件-分页列表查询")
|
||||
@Operation(summary = "表单评论文件-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(SysFormFile sysFormFile,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<SysFormFile> queryWrapper = QueryGenerator.initQueryWrapper(sysFormFile, req.getParameterMap());
|
||||
Page<SysFormFile> page = new Page<SysFormFile>(pageNo, pageSize);
|
||||
IPage<SysFormFile> pageList = sysFormFileService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysFormFile
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "表单评论文件-添加")
|
||||
@Operation(summary = "表单评论文件-添加")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysFormFile sysFormFile) {
|
||||
sysFormFileService.save(sysFormFile);
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysFormFile
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "表单评论文件-编辑")
|
||||
@Operation(summary = "表单评论文件-编辑")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysFormFile sysFormFile) {
|
||||
sysFormFileService.updateById(sysFormFile);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "表单评论文件-通过id删除")
|
||||
@Operation(summary = "表单评论文件-通过id删除")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
sysFormFileService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "表单评论文件-批量删除")
|
||||
@Operation(summary = "表单评论文件-批量删除")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
this.sysFormFileService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "表单评论文件-通过id查询")
|
||||
@Operation(summary = "表单评论文件-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
SysFormFile sysFormFile = sysFormFileService.getById(id);
|
||||
return Result.OK(sysFormFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param sysFormFile
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysFormFile sysFormFile) {
|
||||
return super.exportXls(request, sysFormFile, SysFormFile.class, "表单评论文件");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysFormFile.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysGatewayRoute;
|
||||
import org.jeecg.modules.system.service.ISysGatewayRouteService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: gateway路由管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2020-05-26
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name = "gateway路由管理")
|
||||
@RestController
|
||||
@RequestMapping("/sys/gatewayRoute")
|
||||
@Slf4j
|
||||
public class SysGatewayRouteController extends JeecgController<SysGatewayRoute, ISysGatewayRouteService> {
|
||||
|
||||
@Autowired
|
||||
private ISysGatewayRouteService sysGatewayRouteService;
|
||||
|
||||
@PostMapping(value = "/updateAll")
|
||||
public Result<?> updateAll(@RequestBody JSONObject json) {
|
||||
sysGatewayRouteService.updateAll(json);
|
||||
return Result.ok("操作成功!");
|
||||
}
|
||||
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(SysGatewayRoute sysGatewayRoute) {
|
||||
LambdaQueryWrapper<SysGatewayRoute> query = new LambdaQueryWrapper<>();
|
||||
List<SysGatewayRoute> ls = sysGatewayRouteService.list(query);
|
||||
JSONArray array = new JSONArray();
|
||||
for(SysGatewayRoute rt: ls){
|
||||
JSONObject obj = (JSONObject) JSONObject.toJSON(rt);
|
||||
if(oConvertUtils.isNotEmpty(rt.getPredicates())){
|
||||
obj.put("predicates", JSONArray.parseArray(rt.getPredicates()));
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(rt.getFilters())){
|
||||
obj.put("filters", JSONArray.parseArray(rt.getFilters()));
|
||||
}
|
||||
array.add(obj);
|
||||
}
|
||||
return Result.ok(array);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/clearRedis")
|
||||
public Result<?> clearRedis() {
|
||||
sysGatewayRouteService.clearRedis();
|
||||
return Result.ok("清除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:getway:delete")
|
||||
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
sysGatewayRouteService.deleteById(id);
|
||||
return Result.ok("删除路由成功");
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user