前端和后台,分别拆分成两个独立项目,便于维护

This commit is contained in:
zhangdaiscott
2022-08-12 09:56:53 +08:00
parent d70806947d
commit d135f32b7b
1985 changed files with 5 additions and 130529 deletions

View File

@ -0,0 +1,4 @@
*.js linguist-language=Java
*.css linguist-language=Java
*.html linguist-language=Java
*.vue linguist-language=Java

View File

@ -0,0 +1,16 @@
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER jeecgos@163.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /jeecg-boot/config/jeecg/
WORKDIR /jeecg-boot
EXPOSE 8080
ADD ./src/main/resources/jeecg ./config/jeecg
ADD ./target/jeecg-boot-module-system-3.4.0.jar ./
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.4.0.jar

View File

@ -0,0 +1,58 @@
<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-boot-parent</artifactId>
<version>3.4.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jeecg-boot-module-system</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.boot</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-boot-starter</artifactId>
</dependency>
<!-- DEMO 示例模块 -->
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-module-demo</artifactId>
<version>${jeecgboot.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--SpringCloud运行环境 ,值改为true跳过SpringBoot启动打包插件 -->
<skip>${skip.springboot.maven}</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,18 @@
package org.jeecg;
import org.jeecgframework.codegenerate.window.CodeWindow;
/**
* @Title: 单表代码生成器入口
* @Author 张代浩
* @site www.jeecg.com
* @Version:V1.0.1
*/
public class JeecgOneGUI {
/** 使用手册: http://doc.jeecg.com/2684691 */
public static void main(String[] args) {
new CodeWindow().pack();
}
}

View File

@ -0,0 +1,81 @@
package org.jeecg;
import java.util.ArrayList;
import java.util.List;
import org.jeecgframework.codegenerate.generate.impl.CodeGenerateOneToMany;
import org.jeecgframework.codegenerate.generate.pojo.onetomany.MainTableVo;
import org.jeecgframework.codegenerate.generate.pojo.onetomany.SubTableVo;
/**
* 代码生成器入口【一对多】
* @Author 张代浩
* @site www.jeecg.com
*
*/
public class JeecgOneToMainUtil {
/**
* 一对多(父子表)数据模型,生成方法
* @param args
*/
public static void main(String[] args) {
//第一步:设置主表配置
MainTableVo mainTable = new MainTableVo();
//表名
mainTable.setTableName("jeecg_order_main");
//实体名
mainTable.setEntityName("GuiTestOrderMain");
//包名
mainTable.setEntityPackage("gui");
//描述
mainTable.setFtlDescription("GUI订单管理");
//第二步:设置子表集合配置
List<SubTableVo> subTables = new ArrayList<SubTableVo>();
//[1].子表一
SubTableVo po = new SubTableVo();
//表名
po.setTableName("jeecg_order_customer");
//实体名
po.setEntityName("GuiTestOrderCustom");
//包名
po.setEntityPackage("gui");
//描述
po.setFtlDescription("客户明细");
//子表外键参数配置
/*说明:
* a) 子表引用主表主键ID作为外键外键字段必须以_ID结尾;
* b) 主表和子表的外键字段名字必须相同除主键ID外;
* c) 多个外键字段,采用逗号分隔;
*/
po.setForeignKeys(new String[]{"order_id"});
subTables.add(po);
//[2].子表二
SubTableVo po2 = new SubTableVo();
//表名
po2.setTableName("jeecg_order_ticket");
//实体名
po2.setEntityName("GuiTestOrderTicket");
//包名
po2.setEntityPackage("gui");
//描述
po2.setFtlDescription("产品明细");
//子表外键参数配置
/*说明:
* a) 子表引用主表主键ID作为外键外键字段必须以_ID结尾;
* b) 主表和子表的外键字段名字必须相同除主键ID外;
* c) 多个外键字段,采用逗号分隔;
*/
po2.setForeignKeys(new String[]{"order_id"});
subTables.add(po2);
mainTable.setSubTables(subTables);
//第三步:一对多(父子表)数据模型,代码生成
try {
new CodeGenerateOneToMany(mainTable,subTables).generateCodeFile(null);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,46 @@
package org.jeecg;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* 单体启动类
* 报错提醒: 未集成mongo报错可以打开启动类上面的注释 exclude={MongoAutoConfiguration.class}
*/
@Slf4j
@SpringBootApplication
//@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class})
public class JeecgSystemApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(JeecgSystemApplication.class);
}
public static void main(String[] args) throws UnknownHostException {
ConfigurableApplicationContext application = SpringApplication.run(JeecgSystemApplication.class, args);
Environment env = application.getEnvironment();
String ip = InetAddress.getLocalHost().getHostAddress();
String port = env.getProperty("server.port");
String path = oConvertUtils.getString(env.getProperty("server.servlet.context-path"));
log.info("\n----------------------------------------------------------\n\t" +
"Application Jeecg-Boot is running! Access URLs:\n\t" +
"Local: \t\thttp://localhost:" + port + path + "/\n\t" +
"External: \thttp://" + ip + ":" + port + path + "/\n\t" +
"Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
"----------------------------------------------------------");
}
}

View File

@ -0,0 +1,50 @@
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
*/
@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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,69 @@
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 javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* 自定义积木报表鉴权(如果不进行自定义,则所有请求不做权限控制)
* * 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 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;
}
}

View File

@ -0,0 +1,663 @@
package org.jeecg.modules.api.controller;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*;
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){
return sysBaseApi.getUserByName(username);
}
/**
* 根据用户id查询用户信息
* @param id
* @return
*/
@GetMapping("/getUserById")
LoginUser getUserById(@RequestParam("id") String id){
return sysBaseApi.getUserById(id);
}
/**
* 通过用户账号查询角色集合
* @param username
* @return
*/
@GetMapping("/getRolesByUsername")
List<String> getRolesByUsername(@RequestParam("username") String username){
return sysBaseApi.getRolesByUsername(username);
}
/**
* 通过用户账号查询部门集合
* @param username
* @return 部门 id
*/
@GetMapping("/getDepartIdsByUsername")
List<String> getDepartIdsByUsername(@RequestParam("username") String username){
return sysBaseApi.getDepartIdsByUsername(username);
}
/**
* 通过用户账号查询部门 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<LoginUser> 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) int 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<LoginUser> 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 username
* @return
*/
@GetMapping("/getUserPermissionSet")
public Set<String> getUserPermissionSet(@RequestParam("username") String username){
return sysBaseApi.getUserPermissionSet(username);
}
//-----
/**
* 判断是否有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 username
* @return
*/
@GetMapping("/queryUserAuths")
public Set<String> queryUserAuths(@RequestParam("username") String username){
return sysUserService.getUserPermissionsSet(username);
}
/**
* 通过部门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);
}
/**
* 根据字典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);
}
/**
* 根据字典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 table
* @param text
* @param code
* @return
*/
@GetMapping("/queryTableDictItemsByCode")
List<DictModel> queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code){
return sysBaseApi.queryTableDictItemsByCode(table, 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);
}
/**
* 【接口签名验证】
* 49 字典表的 翻译,可批量
*
* @param table
* @param text
* @param code
* @param keys 多个用逗号分割
* @return
*/
@GetMapping("/translateDictFromTableByKeys")
public List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys) {
return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys);
}
/**
* 发送模板信息
* @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);
}
}

View File

@ -0,0 +1,111 @@
package org.jeecg.modules.cas.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.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());
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);
}
}

View File

@ -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();
}
}

View File

@ -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\">未能够识别出目标 &#39;ST-5-1g-9cNES6KXNRwq-GuRET103sm0-DESKTOP-VKLS8B3&#39;票根</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);
}
}

View File

@ -0,0 +1,145 @@
package org.jeecg.modules.message.controller;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.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);
}
}

View File

@ -0,0 +1,180 @@
package org.jeecg.modules.message.controller;
import java.util.Arrays;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.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());
return result.error500("发送消息出错!");
}
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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){
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,111 @@
package org.jeecg.modules.message.handle.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
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 javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
/**
* @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;
@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-authortaoyan date:20200811 for:配置类数据获取
if(oConvertUtils.isEmpty(emailFrom)){
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
setEmailFrom(staticConfig.getEmailFrom());
}
//update-end-authortaoyan 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(email==null || "".equals(email)){
continue;
}
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());
}
}
log.info("邮件内容:"+ content);
sendMsg(email, title, 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;
}
}

View File

@ -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);
}
}

View File

@ -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("发短信");
}
}

View File

@ -0,0 +1,129 @@
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.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 javax.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.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());
}
}
}
}

View File

@ -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("发微信消息模板");
}
}

View File

@ -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);
}
}
}

View File

@ -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> {
}

View File

@ -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);
}

View File

@ -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>

View File

@ -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>

View File

@ -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> {
}

View File

@ -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);
}

View File

@ -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 {
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,37 @@
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发布订阅方式发送消息)
* @author: jeecg-boot
*/
@Slf4j
@Component
public class SocketHandler implements JeecgRedisListener {
@Autowired
private WebSocket webSocket;
@Override
public void onMessage(BaseMap map) {
log.info("【SocketHandler消息】Redis Listerer:" + map.toString());
String userId = map.get("userId");
String message = map.get("message");
if (ObjectUtil.isNotEmpty(userId)) {
webSocket.pushMessage(userId, message);
//app端消息推送
webSocket.pushMessage(userId+CommonSendStatus.APP_SESSION_SUFFIX, message);
} else {
webSocket.pushMessage(message);
}
}
}

View File

@ -0,0 +1,52 @@
package org.jeecg.modules.message.websocket;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.WebsocketConst;
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;
}
}

View File

@ -0,0 +1,168 @@
package org.jeecg.modules.message.websocket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.annotation.Resource;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.constant.WebsocketConst;
import org.jeecg.common.modules.redis.client.JeecgRedisClient;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
/**
* @Author scott
* @Date 2019/11/29 9:41
* @Description: 此注解相当于设置访问URL
*/
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}")
public class WebSocket {
private Session session;
/**
* 用户ID
*/
private String userId;
private static final String REDIS_TOPIC_NAME = "socketHandler";
@Resource
private JeecgRedisClient jeecgRedisClient;
/**
* 缓存 webSocket连接到单机服务class中整体方案支持集群
*/
private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
/**
* 线程安全Map
*/
private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam(value = "userId") String userId) {
try {
//TODO 通过header中获取token进行check
this.session = session;
this.userId = userId;
webSockets.add(this);
sessionPool.put(userId, session);
log.info("【websocket消息】有新的连接总数为:" + webSockets.size());
} catch (Exception e) {
}
}
@OnClose
public void onClose() {
try {
webSockets.remove(this);
sessionPool.remove(this.userId);
log.info("【websocket消息】连接断开总数为:" + webSockets.size());
} catch (Exception e) {
}
}
/**
* 服务端推送消息
*
* @param userId
* @param message
*/
public void pushMessage(String userId, String message) {
Session session = sessionPool.get(userId);
if (session != null && session.isOpen()) {
try {
//update-begin-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
synchronized (session){
log.info("【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) {
e.printStackTrace();
}
}
}
/**
* 服务器端推送消息
*/
public void pushMessage(String message) {
try {
webSockets.forEach(ws -> ws.session.getAsyncRemote().sendText(message));
} catch (Exception e) {
e.printStackTrace();
}
}
@OnMessage
public void onMessage(String message) {
//todo 现在有个定时任务刷,应该去掉
log.debug("【websocket消息】收到客户端消息:" + message);
JSONObject obj = new JSONObject();
//业务类型
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
//消息内容
obj.put(WebsocketConst.MSG_TXT, "心跳响应");
//update-begin-author:taoyan date:20220308 for: 消息通知长连接启动心跳机制后端代码小bug #3473
for (WebSocket webSocket : webSockets) {
webSocket.pushMessage(obj.toJSONString());
}
//update-end-author:taoyan date:20220308 for: 消息通知长连接启动心跳机制后端代码小bug #3473
}
/**
* 后台发送消息到redis
*
* @param message
*/
public void sendMessage(String message) {
log.info("【websocket消息】广播消息:" + message);
BaseMap baseMap = new BaseMap();
baseMap.put("userId", "");
baseMap.put("message", message);
jeecgRedisClient.sendMessage(REDIS_TOPIC_NAME, baseMap);
}
/**
* 此为单点消息
*
* @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(REDIS_TOPIC_NAME, baseMap);
}
/**
* 此为单点消息(多人)
*
* @param userIds
* @param message
*/
public void sendMessage(String[] userIds, String message) {
for (String userId : userIds) {
sendMessage(userId, message);
}
}
}

View File

@ -0,0 +1,123 @@
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 javax.servlet.http.HttpServletRequest;
import javax.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);
}
@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获取磁盘信息
}

View File

@ -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当前的qpsredis内部较实时的每秒执行的命令数");
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 + '\'' + '}';
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,47 @@
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 ;
}

View File

@ -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;
}
}

View File

@ -0,0 +1,129 @@
package org.jeecg.modules.monitor.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.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.constant.CommonConstant;
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.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详细信息
*/
@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;
}
}

View File

@ -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;
// }
//}

View File

@ -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);
// }
//}

View File

@ -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);
}

View File

@ -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;
}
}
}

View File

@ -0,0 +1,95 @@
package org.jeecg.modules.oss.controller;
import javax.servlet.http.HttpServletRequest;
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")
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;
}
}

View File

@ -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;
}

View File

@ -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> {
}

View File

@ -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 IOException;
/**
* oss文件删除
* @param ossFile OSSFile对象
* @return
*/
boolean delete(OssFile ossFile);
}

View File

@ -0,0 +1,48 @@
package org.jeecg.modules.oss.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.util.CommonUtils;
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 IOException {
String fileName = multipartFile.getOriginalFilename();
fileName = CommonUtils.getFileName(fileName);
OssFile ossFile = new OssFile();
ossFile.setFileName(fileName);
String url = OssBootUtil.upload(multipartFile,"upload/test");
//update-begin--Author:scott Date:20201227 forJT-361【文件预览】阿里云原生域名可以文件预览自己映射域名kkfileview提示文件下载失败-------------------
// 返回阿里云原生域名前缀URL
ossFile.setUrl(OssBootUtil.getOriginalUrl(url));
//update-end--Author:scott Date:20201227 forJT-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;
}
}

View File

@ -0,0 +1,283 @@
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.annotations.Api;
import io.swagger.annotations.ApiOperation;
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.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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @Description: 定时任务在线管理
* @Author: jeecg-boot
* @Date: 2019-01-02
* @Version:V1.0
*/
@RestController
@RequestMapping("/sys/quartzJob")
@Slf4j
@Api(tags = "定时任务接口")
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")
@RequestMapping(value = "/add", method = RequestMethod.POST)
public Result<?> add(@RequestBody QuartzJob quartzJob) {
quartzJobService.saveAndScheduleJob(quartzJob);
return Result.ok("创建定时任务成功");
}
/**
* 更新定时任务
*
* @param quartzJob
* @return
*/
//@RequiresRoles("admin")
@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")
@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")
@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")
@GetMapping(value = "/pause")
@ApiOperation(value = "停止定时任务")
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")
@GetMapping(value = "/resume")
@ApiOperation(value = "启动定时任务")
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")
@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("执行成功!");
}
}

View File

@ -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;
}

View File

@ -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()+"---");
}
}

View File

@ -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()));
}
}

View File

@ -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));
}
}

View File

@ -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);
}

View File

@ -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>

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -0,0 +1,396 @@
package org.jeecg.modules.system.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.exception.JeecgBootException;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.RestUtil;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.ServletServerHttpRequest;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
/**
* <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 miniominio 阿里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) {
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: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);
}
String filePath = uploadpath + File.separator + imgPath;
File file = new File(filePath);
if(!file.exists()){
response.setStatus(404);
throw new RuntimeException("文件["+imgPath+"]不存在..");
}
// 设置强制下载不打开
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);
}
/**
* 中转HTTP请求解决跨域问题
*
* @param url 必填:请求地址
* @return
*/
@RequestMapping("/transitRESTful")
public Result transitRestful(@RequestParam("url") String url, HttpServletRequest request) {
try {
ServletServerHttpRequest httpRequest = new ServletServerHttpRequest(request);
// 中转请求method、body
HttpMethod method = httpRequest.getMethod();
JSONObject params;
try {
params = JSON.parseObject(JSON.toJSONString(httpRequest.getBody()));
} catch (Exception e) {
params = new JSONObject();
}
// 中转请求问号参数
JSONObject variables = JSON.parseObject(JSON.toJSONString(request.getParameterMap()));
variables.remove("url");
// 在 headers 里传递Token
String token = TokenUtils.getTokenByRequest(request);
HttpHeaders headers = new HttpHeaders();
headers.set("X-Access-Token", token);
// 发送请求
String httpUrl = URLDecoder.decode(url, "UTF-8");
ResponseEntity<String> response = RestUtil.request(httpUrl, method, headers , variables, params, String.class);
// 封装返回结果
Result<Object> result = new Result<>();
int statusCode = response.getStatusCodeValue();
result.setCode(statusCode);
result.setSuccess(statusCode == 200);
String responseBody = response.getBody();
try {
// 尝试将返回结果转为JSON
Object json = JSON.parse(responseBody);
result.setResult(json);
} catch (Exception e) {
// 转成JSON失败直接返回原始数据
result.setResult(responseBody);
}
return result;
} catch (Exception e) {
log.debug("中转HTTP请求失败", e);
return Result.error(e.getMessage());
}
}
}

View File

@ -0,0 +1,87 @@
package org.jeecg.modules.system.controller;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.util.SqlInjectionUtil;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.jeecg.modules.system.model.DuplicateCheckVo;
import org.jeecg.modules.system.security.DictQueryBlackListHandler;
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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
/**
* @Title: DuplicateCheckAction
* @Description: 重复校验工具
* @Author 张代浩
* @Date 2019-03-25
* @Version V1.0
*/
@Slf4j
@RestController
@RequestMapping("/sys/duplicate")
@Api(tags="重复校验")
public class DuplicateCheckController {
@Autowired
SysDictMapper sysDictMapper;
@Autowired
DictQueryBlackListHandler dictQueryBlackListHandler;
/**
* 校验数据是否在系统中是否存在
*
* @return
*/
@RequestMapping(value = "/check", method = RequestMethod.GET)
@ApiOperation("重复校验接口")
public Result<String> doDuplicateCheck(DuplicateCheckVo duplicateCheckVo, HttpServletRequest request) {
Long num = null;
log.info("----duplicate check------"+ duplicateCheckVo.toString());
//关联表字典举例sys_user,realname,id
//SQL注入校验只限制非法串改数据库
final String[] sqlInjCheck = {duplicateCheckVo.getTableName(),duplicateCheckVo.getFieldName()};
SqlInjectionUtil.filterContent(sqlInjCheck);
// update-begin-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志
if(StringUtils.isEmpty(duplicateCheckVo.getFieldVal())){
Result rs = new Result();
rs.setCode(500);
rs.setSuccess(true);
rs.setMessage("数据为空,不作处理!");
return rs;
}
//update-begin-author:taoyan date:20220329 for: VUEN-223【安全漏洞】当前被攻击的接口
String checkSql = duplicateCheckVo.getTableName() + SymbolConstant.COMMA + duplicateCheckVo.getFieldName() + SymbolConstant.COMMA;
if(!dictQueryBlackListHandler.isPass(checkSql)){
return Result.error(dictQueryBlackListHandler.getError());
}
//update-end-author:taoyan date:20220329 for: VUEN-223【安全漏洞】当前被攻击的接口
// update-end-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志
if (StringUtils.isNotBlank(duplicateCheckVo.getDataId())) {
// [2].编辑页面校验
num = sysDictMapper.duplicateCheckCountSql(duplicateCheckVo);
} else {
// [1].添加页面校验
num = sysDictMapper.duplicateCheckCountSqlNoDataId(duplicateCheckVo);
}
if (num == null || num == 0) {
// 该值可用
return Result.ok("该值可用!");
} else {
// 该值不可用
log.info("该值不可用,系统中已存在!");
return Result.error("该值不可用,系统中已存在!");
}
}
}

View File

@ -0,0 +1,648 @@
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.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
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.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.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 javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* @Author scott
* @since 2018-12-17
*/
@RestController
@RequestMapping("/sys")
@Api(tags="用户登录")
@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 ISysTenantService sysTenantService;
@Autowired
private ISysDictService sysDictService;
@Resource
private BaseCommonService baseCommonService;
private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
@ApiOperation("登录接口")
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){
Result<JSONObject> result = new Result<JSONObject>();
String username = sysLoginModel.getUsername();
String password = sysLoginModel.getPassword();
//update-begin--Author:scott Date:20190805 for暂时注释掉密码加密逻辑有点问题
//前端密码加密,后端进行密码解密
//password = AesEncryptUtil.desEncrypt(sysLoginModel.getPassword().replaceAll("%2B", "\\+")).trim();//密码解密
//update-begin--Author:scott Date:20190805 for暂时注释掉密码加密逻辑有点问题
//update-begin-author:taoyan date:20190828 for:校验验证码
String captcha = sysLoginModel.getCaptcha();
if(captcha==null){
result.error500("验证码无效");
return result;
}
String lowerCaseCaptcha = captcha.toLowerCase();
String realKey = Md5Util.md5Encode(lowerCaseCaptcha+sysLoginModel.getCheckKey(), "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;
}
//update-end-author:taoyan date:20190828 for:校验验证码
//1. 校验用户是否有效
//update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bugif条件永远为false
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUser::getUsername,username);
SysUser sysUser = sysUserService.getOne(queryWrapper);
//update-end-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bugif条件永远为false
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)) {
result.error500("用户名或密码错误");
return result;
}
//用户登录信息
userInfo(sysUser, result);
//update-begin--Author:liusq Date:20210126 for登录成功删除redis中的验证码
redisUtil.del(realKey);
//update-begin--Author:liusq Date:20210126 for登录成功删除redis中的验证码
LoginUser loginUser = new LoginUser();
BeanUtils.copyProperties(sysUser, loginUser);
baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
//update-end--Author:wangshuai Date:20200714 for登录日志没有记录人员
return result;
}
/**
* 【vue3专用】获取用户信息
*/
@GetMapping("/user/getUserInfo")
public Result<JSONObject> getUserInfo(HttpServletRequest request){
Result<JSONObject> result = new Result<JSONObject>();
String username = JwtUtil.getUserNameByToken(request);
if(oConvertUtils.isNotEmpty(username)) {
// 根据用户名查询用户信息
SysUser sysUser = sysUserService.getUserByName(username);
JSONObject obj=new JSONObject();
//update-begin---author:scott ---date:2022-06-20 forvue3前端支持自定义首页-----------
String version = request.getHeader(CommonConstant.VERSION);
//update-begin---author:liusq ---date:2022-06-29 for接口返回值修改同步修改这里的判断逻辑-----------
SysRoleIndex roleIndex = sysUserService.getDynamicIndexByUserRole(username, version);
if (oConvertUtils.isNotEmpty(version) && roleIndex != null && oConvertUtils.isNotEmpty(roleIndex.getUrl())) {
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 forvue3前端支持自定义首页--------------
obj.put("userInfo",sysUser);
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
result.setResult(obj);
result.success("");
}
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();
this.sysUserService.updateUserDepart(username, orgCode);
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) {
Result<String> result = new Result<String>();
String mobile = jsonObject.get("mobile").toString();
//手机号模式 登录模式: "2" 注册模式: "1"
String smsmode=jsonObject.get("smsmode").toString();
log.info(mobile);
if(oConvertUtils.isEmpty(mobile)){
result.setMessage("手机号不允许为空!");
result.setSuccess(false);
return result;
}
Object object = redisUtil.get(mobile);
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 = 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;
}
//验证码10分钟内有效
redisUtil.set(mobile, captcha, 600);
//update-begin--Author:scott Date:20190812 forissues#391
//result.setResult(captcha);
//update-end--Author:scott Date:20190812 forissues#391
result.setSuccess(true);
} catch (ClientException e) {
e.printStackTrace();
result.error500(" 短信接口未配置,请联系管理员!");
return result;
}
return result;
}
/**
* 手机号登录接口
*
* @param jsonObject
* @return
*/
@ApiOperation("手机号登录接口")
@PostMapping("/phoneLogin")
public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject) {
Result<JSONObject> result = new Result<JSONObject>();
String phone = jsonObject.getString("mobile");
//校验用户有效性
SysUser sysUser = sysUserService.getUserByPhone(phone);
result = sysUserService.checkUserIsEffective(sysUser);
if(!result.isSuccess()) {
return result;
}
String smscode = jsonObject.getString("captcha");
Object code = redisUtil.get(phone);
if (!smscode.equals(code)) {
result.setMessage("手机验证码错误");
return result;
}
//用户信息
userInfo(sysUser, result);
//添加日志
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) {
String username = sysUser.getUsername();
String syspassword = sysUser.getPassword();
// 获取用户部门信息
JSONObject obj = new JSONObject(new LinkedHashMap<>());
// 生成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);
// update-begin--Author:sunjianlei Date:20210802 for获取用户租户信息
String tenantIds = sysUser.getRelTenantIds();
if (oConvertUtils.isNotEmpty(tenantIds)) {
List<Integer> tenantIdList = new ArrayList<>();
for(String id: tenantIds.split(SymbolConstant.COMMA)){
tenantIdList.add(Integer.valueOf(id));
}
// 该方法仅查询有效的租户如果返回0个就说明所有的租户均无效。
List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
if (tenantList.size() == 0) {
result.error500("与该用户关联的租户均已被冻结,无法登录!");
return result;
} else {
obj.put("tenantList", tenantList);
}
}
// update-end--Author:sunjianlei Date:20210802 for获取用户租户信息
obj.put("userInfo", sysUser);
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());
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());
}
// update-end--Author:wangshuai Date:20200805 for如果用戶为选择部门数据库为存在上一次登录部门则取一条存进去
obj.put("multi_depart", 2);
}
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
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
*/
@ApiOperation("获取验证码")
@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();
String realKey = Md5Util.md5Encode(lowerCaseCode+key, "utf-8");
log.info("获取验证码Redis checkCode = {}key = {}", code, key);
redisUtil.set(realKey, lowerCaseCode, 60);
//返回前端
String base64 = RandImageUtil.generate(code);
res.setSuccess(true);
res.setResult(base64);
} catch (Exception e) {
res.error500("获取验证码出错"+e.getMessage());
e.printStackTrace();
}
return res;
}
/**
* 切换菜单表为vue3的表
*/
@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();
//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)) {
result.error500("用户名或密码错误");
return result;
}
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);
}
//update-end-author:taoyan date:20220117 for: JTC-1068【app】新建用户没有设置部门及角色点击登录提示暂未归属部一直在登录页面 使用手机号登录 可正常
}
JSONObject obj = new JSONObject();
//用户登录信息
obj.put("userInfo", sysUser);
// 生成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();
}
/**
* 获取登录二维码
*/
@ApiOperation(value = "获取登录二维码", notes = "获取登录二维码")
@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);
}
/**
* 扫码二维码
*/
@ApiOperation(value = "扫码登录二维码", notes = "扫码登录二维码")
@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
*/
@ApiOperation(value = "获取用户扫码后Token", notes = "获取用户扫码后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);
}
}

View File

@ -0,0 +1,509 @@
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.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.RedisUtil;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.message.websocket.WebSocket;
import org.jeecg.modules.system.entity.SysAnnouncement;
import org.jeecg.modules.system.entity.SysAnnouncementSend;
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
import org.jeecg.modules.system.service.ISysAnnouncementService;
import org.jeecg.modules.system.service.impl.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.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.jeecg.common.constant.CommonConstant.ANNOUNCEMENT_SEND_STATUS_1;
/**
* @Title: Controller
* @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;
/**
* 分页列表查询
* @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) {
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);
//update-begin-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC故注释此段代码
//排序逻辑 处理
// String column = req.getParameter("column");
// String order = req.getParameter("order");
// if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
// if("asc".equals(order)) {
// queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
// }else {
// queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
// }
// }
//update-end-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC故注释此段代码
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)) {
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, 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) {
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
String userId = sysUser.getId();
// 1.将系统消息补充到用户通告阅读标记表中
LambdaQueryWrapper<SysAnnouncement> querySaWrapper = new LambdaQueryWrapper<SysAnnouncement>();
//全部人员
querySaWrapper.eq(SysAnnouncement::getMsgType,CommonConstant.MSG_TYPE_ALL);
//未删除
querySaWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
//已发布
querySaWrapper.eq(SysAnnouncement::getSendStatus, CommonConstant.HAS_SEND);
//新注册用户不看结束通知
querySaWrapper.ge(SysAnnouncement::getEndTime, sysUser.getCreateTime());
//update-begin--Author:liusq Date:20210108 for[JT-424] 【开源issue】bug处理--------------------
querySaWrapper.notInSql(SysAnnouncement::getId,"select annt_id from sys_announcement_send where user_id='"+userId+"'");
//update-begin--Author:liusq Date:20210108 for [JT-424] 【开源issue】bug处理--------------------
List<SysAnnouncement> announcements = sysAnnouncementService.list(querySaWrapper);
if(announcements.size()>0) {
for(int i=0;i<announcements.size();i++) {
//update-begin--Author:wangshuai Date:20200803 for 通知公告消息重复LOWCOD-759--------------------
//因为websocket没有判断是否存在这个用户要是判断会出现问题故在此判断逻辑
LambdaQueryWrapper<SysAnnouncementSend> query = new LambdaQueryWrapper<>();
query.eq(SysAnnouncementSend::getAnntId,announcements.get(i).getId());
query.eq(SysAnnouncementSend::getUserId,userId);
SysAnnouncementSend one = sysAnnouncementSendService.getOne(query);
if(null==one){
log.info("listByUser接口新增了SysAnnouncementSendpageSize{}"+pageSize);
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
announcementSend.setAnntId(announcements.get(i).getId());
announcementSend.setUserId(userId);
announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
sysAnnouncementSendService.save(announcementSend);
log.info("announcementSend.toString()",announcementSend.toString());
}
//update-end--Author:wangshuai Date:20200803 for 通知公告消息重复LOWCOD-759------------
}
}
// 2.查询用户未读的系统消息
Page<SysAnnouncement> anntMsgList = new Page<SysAnnouncement>(0, pageSize);
//通知公告消息
anntMsgList = sysAnnouncementService.querySysCementPageByUserId(anntMsgList,userId,"1");
Page<SysAnnouncement> sysMsgList = new Page<SysAnnouncement>(0, pageSize);
//系统消息
sysMsgList = sysAnnouncementService.querySysCementPageByUserId(sysMsgList,userId,"2");
Map<String,Object> sysMsgMap = new HashMap(5);
sysMsgMap.put("sysMsgList", sysMsgList.getRecords());
sysMsgMap.put("sysMsgTotal", sysMsgList.getTotal());
sysMsgMap.put("anntMsgList", anntMsgList.getRecords());
sysMsgMap.put("anntMsgTotal", anntMsgList.getTotal());
result.setSuccess(true);
result.setResult(sysMsgMap);
return result;
}
/**
* 导出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;
}
}

View File

@ -0,0 +1,256 @@
package org.jeecg.modules.system.controller;
import java.util.Arrays;
import java.util.Date;
import javax.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");
//issues/3331 SQL injection vulnerability
SqlInjectionUtil.filterContent(column);
SqlInjectionUtil.filterContent(order);
if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
if(DataBaseConstant.SQL_ASC.equals(order)) {
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
}else {
queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(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());
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.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;
}
}

View File

@ -0,0 +1,517 @@
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.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.SqlInjectionUtil;
import org.jeecg.common.util.oConvertUtils;
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 javax.servlet.http.HttpServletRequest;
import javax.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>>();
//--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) {
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) {
// 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 = SqlInjectionUtil.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());
}
}
}

View File

@ -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.annotations.Api;
import io.swagger.annotations.ApiOperation;
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 javax.servlet.http.HttpServletRequest;
import javax.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
@Api(tags = "编码校验规则")
@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 = "编码校验规则-分页列表查询")
@ApiOperation(value = "编码校验规则-分页列表查询", notes = "编码校验规则-分页列表查询")
@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校验传入的值")
@ApiOperation(value = "编码校验规则-通过Code校验传入的值", notes = "编码校验规则-通过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 = "编码校验规则-添加")
@ApiOperation(value = "编码校验规则-添加", notes = "编码校验规则-添加")
@PostMapping(value = "/add")
public Result add(@RequestBody SysCheckRule sysCheckRule) {
sysCheckRuleService.save(sysCheckRule);
return Result.ok("添加成功!");
}
/**
* 编辑
*
* @param sysCheckRule
* @return
*/
@AutoLog(value = "编码校验规则-编辑")
@ApiOperation(value = "编码校验规则-编辑", notes = "编码校验规则-编辑")
@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删除")
@ApiOperation(value = "编码校验规则-通过id删除", notes = "编码校验规则-通过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 = "编码校验规则-批量删除")
@ApiOperation(value = "编码校验规则-批量删除", notes = "编码校验规则-批量删除")
@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查询")
@ApiOperation(value = "编码校验规则-通过id查询", notes = "编码校验规则-通过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);
}
}

View File

@ -0,0 +1,98 @@
package org.jeecg.modules.system.controller;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.jeecg.common.api.vo.Result;
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>>();
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);
List<SysDataLog> list = service.list(queryWrapper);
if(list==null||list.size()<=0) {
result.error500("未找到版本信息");
}else {
result.setResult(list);
result.setSuccess(true);
}
return result;
}
}

View File

@ -0,0 +1,191 @@
package org.jeecg.modules.system.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
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.dynamic.db.DataSourceCachePool;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.List;
/**
* @Description: 多数据源管理
* @Author: jeecg-boot
* @Date: 2019-12-25
* @Version: V1.0
*/
@Slf4j
@Api(tags = "多数据源管理")
@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 = "多数据源管理-分页列表查询")
@ApiOperation(value = "多数据源管理-分页列表查询", notes = "多数据源管理-分页列表查询")
//@RequiresRoles("admin")
@GetMapping(value = "/list")
public Result<?> queryPageList(
SysDataSource sysDataSource,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req
) {
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) {
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 = "多数据源管理-添加")
@ApiOperation(value = "多数据源管理-添加", notes = "多数据源管理-添加")
@PostMapping(value = "/add")
public Result<?> add(@RequestBody SysDataSource sysDataSource) {
return sysDataSourceService.saveDataSource(sysDataSource);
}
/**
* 编辑
*
* @param sysDataSource
* @return
*/
@AutoLog(value = "多数据源管理-编辑")
@ApiOperation(value = "多数据源管理-编辑", notes = "多数据源管理-编辑")
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
public Result<?> edit(@RequestBody SysDataSource sysDataSource) {
return sysDataSourceService.editDataSource(sysDataSource);
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "多数据源管理-通过id删除")
@ApiOperation(value = "多数据源管理-通过id删除", notes = "多数据源管理-通过id删除")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name = "id") String id) {
return sysDataSourceService.deleteDataSource(id);
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "多数据源管理-批量删除")
@ApiOperation(value = "多数据源管理-批量删除", notes = "多数据源管理-批量删除")
@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查询")
@ApiOperation(value = "多数据源管理-通过id查询", notes = "多数据源管理-通过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) {
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);
}
}

View File

@ -0,0 +1,529 @@
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.RequiresRoles;
import org.jeecg.common.api.vo.Result;
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.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.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 javax.servlet.http.HttpServletRequest;
import javax.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);
}
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
*/
//@RequiresRoles({"admin"})
@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
*/
//@RequiresRoles({"admin"})
@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
*/
//@RequiresRoles({"admin"})
@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 {
boolean ok = sysDepartService.delete(id);
if(ok) {
//清除部门树内存
//FindsDepartsChildrenUtil.clearSysDepartTreeList();
// FindsDepartsChildrenUtil.clearDepartIdModel();
result.success("删除成功!");
}
}
return result;
}
/**
* 批量删除 根据前端请求的多个ID,对数据库执行删除相关部门数据的操作
*
* @param ids
* @return
*/
//@RequiresRoles({"admin"})
@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) {
// Step.1 组装查询条件
QueryWrapper<SysDepart> queryWrapper = QueryGenerator.initQueryWrapper(sysDepart, request.getParameterMap());
//Step.2 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());
}
});
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "部门列表");
mv.addObject(NormalExcelConstants.CLASS, SysDepart.class);
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("部门列表数据", "导出人:"+user.getRealname(), "导出信息"));
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
return mv;
}
/**
* 通过excel导入数据
* 部门导入方案1: 通过机构编码来计算出部门的父级ID,维护上下级关系;
* 部门导入方案2: 你也可以改造下程序,机构编码直接导入,先不设置父ID;全部导入后,写一个sql,补下父ID;
*
* @param request
* @param response
* @return
*/
//@RequiresRoles({"admin"})
@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;
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 {
// 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());
} else {
sysDepart.setParentId("");
}
}catch (Exception e) {
//没有查找到parentDept
}
}else{
sysDepart.setParentId("");
}
//update-begin---author:liusq Date:20210223 for批量导入部门以后不能追加下一级部门 #2245------------
sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
//update-end---author:liusq Date:20210223 for批量导入部门以后不能追加下一级部门 #2245------------
sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
//update-begin---author:wangshuai ---date:20220105 for[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
if(oConvertUtils.isEmpty(sysDepart.getOrgCategory())){
sysDepart.setOrgCategory("1");
}
//update-end---author:wangshuai ---date:20220105 for[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
num++;
}
//清空部门缓存
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
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;
}
}

View File

@ -0,0 +1,328 @@
package org.jeecg.modules.system.controller;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.shiro.SecurityUtils;
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.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 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.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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/**
* @Description: 部门权限表
* @Author: jeecg-boot
* @Date: 2020-02-11
* @Version: V1.0
*/
@Slf4j
@Api(tags="部门权限表")
@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
*/
@ApiOperation(value="部门权限表-分页列表查询", notes="部门权限表-分页列表查询")
@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
*/
@ApiOperation(value="部门权限表-添加", notes="部门权限表-添加")
@PostMapping(value = "/add")
public Result<?> add(@RequestBody SysDepartPermission sysDepartPermission) {
sysDepartPermissionService.save(sysDepartPermission);
return Result.ok("添加成功!");
}
/**
* 编辑
*
* @param sysDepartPermission
* @return
*/
@ApiOperation(value="部门权限表-编辑", notes="部门权限表-编辑")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> edit(@RequestBody SysDepartPermission sysDepartPermission) {
sysDepartPermissionService.updateById(sysDepartPermission);
return Result.ok("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@ApiOperation(value="部门权限表-通过id删除", notes="部门权限表-通过id删除")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
sysDepartPermissionService.removeById(id);
return Result.ok("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@ApiOperation(value="部门权限表-批量删除", notes="部门权限表-批量删除")
@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
*/
@ApiOperation(value="部门权限表-通过id查询", notes="部门权限表-通过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 {
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.orderByAsc(SysPermission::getSortNo);
query.inSql(SysPermission::getId,"select permission_id from sys_depart_permission where depart_id='"+departId+"'");
List<SysPermission> list = sysPermissionService.list(query);
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);
}
}
}
}
}

View File

@ -0,0 +1,305 @@
package org.jeecg.modules.system.controller;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.shiro.SecurityUtils;
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;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/**
* @Description: 部门角色
* @Author: jeecg-boot
* @Date: 2020-02-12
* @Version: V1.0
*/
@Slf4j
@Api(tags="部门角色")
@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
*/
@ApiOperation(value="部门角色-分页列表查询", notes="部门角色-分页列表查询")
@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);
//我的部门,选中部门只能看当前部门下的角色
queryWrapper.eq("depart_id",deptId);
IPage<SysDepartRole> pageList = sysDepartRoleService.page(page, queryWrapper);
return Result.ok(pageList);
}
/**
* 添加
*
* @param sysDepartRole
* @return
*/
//@RequiresRoles({"admin"})
@ApiOperation(value="部门角色-添加", notes="部门角色-添加")
@PostMapping(value = "/add")
public Result<?> add(@RequestBody SysDepartRole sysDepartRole) {
sysDepartRoleService.save(sysDepartRole);
return Result.ok("添加成功!");
}
/**
* 编辑
*
* @param sysDepartRole
* @return
*/
//@RequiresRoles({"admin"})
@ApiOperation(value="部门角色-编辑", notes="部门角色-编辑")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> edit(@RequestBody SysDepartRole sysDepartRole) {
sysDepartRoleService.updateById(sysDepartRole);
return Result.ok("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
//@RequiresRoles({"admin"})
@AutoLog(value = "部门角色-通过id删除")
@ApiOperation(value="部门角色-通过id删除", notes="部门角色-通过id删除")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
sysDepartRoleService.removeById(id);
return Result.ok("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
//@RequiresRoles({"admin"})
@AutoLog(value = "部门角色-批量删除")
@ApiOperation(value="部门角色-批量删除", notes="部门角色-批量删除")
@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
*/
@ApiOperation(value="部门角色-通过id查询", notes="部门角色-通过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
*/
//@RequiresRoles({"admin"})
@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);
}
}

View File

@ -0,0 +1,617 @@
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.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.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.SqlInjectionUtil;
import org.jeecg.common.util.oConvertUtils;
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.security.DictQueryBlackListHandler;
import org.jeecg.modules.system.service.ISysDictItemService;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.vo.SysDictPage;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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 DictQueryBlackListHandler dictQueryBlackListHandler;
@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>>();
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>>();
//update-begin-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
if(!dictQueryBlackListHandler.isPass(dictCode)){
return result.error500(dictQueryBlackListHandler.getError());
}
//update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
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) {
log.info(" 加载字典表数据,加载关键字: "+ keyword);
Result<List<DictModel>> result = new Result<List<DictModel>>();
//update-begin-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
if(!dictQueryBlackListHandler.isPass(dictCode)){
return result.error500(dictQueryBlackListHandler.getError());
}
//update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
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("操作失败");
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<>();
//update-begin-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
if(!dictQueryBlackListHandler.isPass(dictCode)){
return result.error500(dictQueryBlackListHandler.getError());
}
//update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
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 加载树形数据
*/
@SuppressWarnings("unchecked")
@RequestMapping(value = "/loadTreeData", method = RequestMethod.GET)
public Result<List<TreeSelectModel>> loadTreeData(@RequestParam(name="pid") String pid,@RequestParam(name="pidField") String pidField,
@RequestParam(name="tableName") String tbname,
@RequestParam(name="text") String text,
@RequestParam(name="code") String code,
@RequestParam(name="hasChildField") String hasChildField,
@RequestParam(name="condition") String condition,
@RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
Result<List<TreeSelectModel>> result = new Result<List<TreeSelectModel>>();
Map<String, String> query = null;
if(oConvertUtils.isNotEmpty(condition)) {
query = JSON.parseObject(condition, Map.class);
}
// SQL注入漏洞 sign签名校验(表名,label字段,val字段,条件)
String dictCode = tbname+","+text+","+code+","+condition;
SqlInjectionUtil.filterContent(dictCode);
List<TreeSelectModel> ls = sysDictService.queryTreeList(query,tbname, text, code, pidField, pid,hasChildField);
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>>();
// SQL注入漏洞 sign签名校验
String dictCode = query.getTable()+","+query.getText()+","+query.getCode();
SqlInjectionUtil.filterContent(dictCode);
List<DictModel> ls = this.sysDictService.queryDictTablePageList(query,pageSize,pageNo);
res.setResult(ls);
res.setSuccess(true);
return res;
}
/**
* @功能:新增
* @param sysDict
* @return
*/
//@RequiresRoles({"admin"})
@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
*/
//@RequiresRoles({"admin"})
@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
*/
//@RequiresRoles({"admin"})
@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
*/
//@RequiresRoles({"admin"})
@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);
return result;
}
/**
* 导出excel
*
* @param request
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(SysDict sysDict,HttpServletRequest request) {
// Step.1 组装查询条件
QueryWrapper<SysDict> queryWrapper = QueryGenerator.initQueryWrapper(sysDict, request.getParameterMap());
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
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
*/
//@RequiresRoles({"admin"})
@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() {
Result<List<SysDict>> result = new Result<List<SysDict>>();
List<SysDict> list = this.sysDictService.queryDeleteList();
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("操作失败!");
}
}
}

View File

@ -0,0 +1,185 @@
package org.jeecg.modules.system.controller;
import java.util.Arrays;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
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
*/
@Api(tags = "数据字典")
@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
*/
//@RequiresRoles({"admin"})
@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
*/
//@RequiresRoles({"admin"})
@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
*/
//@RequiresRoles({"admin"})
@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
*/
//@RequiresRoles({"admin"})
@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)
@ApiOperation("字典重复校验接口")
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("该值不可用,系统中已存在!");
}
}
}

View File

@ -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.annotations.Api;
import io.swagger.annotations.ApiOperation;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
/**
* @Description: 填值规则
* @Author: jeecg-boot
* @Date: 2019-11-07
* @Version: V1.0
*/
@Slf4j
@Api(tags = "填值规则")
@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 = "填值规则-分页列表查询")
@ApiOperation(value = "填值规则-分页列表查询", notes = "填值规则-分页列表查询")
@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 = "填值规则-添加")
@ApiOperation(value = "填值规则-添加", notes = "填值规则-添加")
@PostMapping(value = "/add")
public Result<?> add(@RequestBody SysFillRule sysFillRule) {
sysFillRuleService.save(sysFillRule);
return Result.ok("添加成功!");
}
/**
* 编辑
*
* @param sysFillRule
* @return
*/
@AutoLog(value = "填值规则-编辑")
@ApiOperation(value = "填值规则-编辑", notes = "填值规则-编辑")
@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删除")
@ApiOperation(value = "填值规则-通过id删除", notes = "填值规则-通过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 = "填值规则-批量删除")
@ApiOperation(value = "填值规则-批量删除", notes = "填值规则-批量删除")
@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查询")
@ApiOperation(value = "填值规则-通过id查询", notes = "填值规则-通过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);
}
}

View File

@ -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.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresRoles;
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
*/
@Api(tags = "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
*/
//@RequiresRoles({"admin"})
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
sysGatewayRouteService.deleteById(id);
return Result.ok("删除路由成功");
}
}

View File

@ -0,0 +1,123 @@
package org.jeecg.modules.system.controller;
import java.util.Arrays;
import javax.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.SysLog;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.service.ISysLogService;
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;
/**
* <p>
* 系统日志表 前端控制器
* </p>
*
* @Author zhangweijian
* @since 2018-12-26
*/
@RestController
@RequestMapping("/sys/log")
@Slf4j
public class SysLogController {
@Autowired
private ISysLogService sysLogService;
/**
* 全部清除
*/
private static final String ALL_ClEAR = "allclear";
/**
* @功能:查询日志记录
* @param syslog
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
Result<IPage<SysLog>> result = new Result<IPage<SysLog>>();
QueryWrapper<SysLog> queryWrapper = QueryGenerator.initQueryWrapper(syslog, req.getParameterMap());
Page<SysLog> page = new Page<SysLog>(pageNo, pageSize);
//日志关键词
String keyWord = req.getParameter("keyWord");
if(oConvertUtils.isNotEmpty(keyWord)) {
queryWrapper.like("log_content",keyWord);
}
//TODO 过滤逻辑处理
//TODO begin、end逻辑处理
//TODO 一个强大的功能,前端传一个字段字符串,后台只返回这些字符串对应的字段
//创建时间/创建人的赋值
IPage<SysLog> pageList = sysLogService.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 id
* @return
*/
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public Result<SysLog> delete(@RequestParam(name="id",required=true) String id) {
Result<SysLog> result = new Result<SysLog>();
SysLog sysLog = sysLogService.getById(id);
if(sysLog==null) {
result.error500("未找到对应实体");
}else {
boolean ok = sysLogService.removeById(id);
if(ok) {
result.success("删除成功!");
}
}
return result;
}
/**
* @功能:批量,全部清空日志记录
* @param ids
* @return
*/
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
public Result<SysRole> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
Result<SysRole> result = new Result<SysRole>();
if(ids==null || "".equals(ids.trim())) {
result.error500("参数不识别!");
}else {
if(ALL_ClEAR.equals(ids)) {
this.sysLogService.removeAll();
result.success("清除成功!");
}
this.sysLogService.removeByIds(Arrays.asList(ids.split(",")));
result.success("删除成功!");
}
return result;
}
}

View File

@ -0,0 +1,942 @@
package org.jeecg.modules.system.controller;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.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.RequiresRoles;
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.RoleIndexConfigEnum;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.Md5Util;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.JeecgBaseConfig;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.model.SysPermissionTree;
import org.jeecg.modules.system.model.TreeModel;
import org.jeecg.modules.system.service.*;
import org.jeecg.modules.system.util.PermissionDataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
* 菜单权限表 前端控制器
* </p>
*
* @Author scott
* @since 2018-12-21
*/
@Slf4j
@RestController
@RequestMapping("/sys/permission")
public class SysPermissionController {
@Autowired
private ISysPermissionService sysPermissionService;
@Autowired
private ISysRolePermissionService sysRolePermissionService;
@Autowired
private ISysPermissionDataRuleService sysPermissionDataRuleService;
@Autowired
private ISysDepartPermissionService sysDepartPermissionService;
@Autowired
private ISysUserService sysUserService;
@Autowired
private JeecgBaseConfig jeecgBaseConfig;
@Autowired
private BaseCommonService baseCommonService;
@Autowired
private ISysRoleIndexService sysRoleIndexService;
/**
* 子菜单
*/
private static final String CHILDREN = "children";
/**
* 加载数据节点
*
* @return
*/
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<List<SysPermissionTree>> list() {
long start = System.currentTimeMillis();
Result<List<SysPermissionTree>> result = new Result<>();
try {
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.orderByAsc(SysPermission::getSortNo);
List<SysPermission> list = sysPermissionService.list(query);
List<SysPermissionTree> treeList = new ArrayList<>();
getTreeList(treeList, list, null);
result.setResult(treeList);
result.setSuccess(true);
log.info("======获取全部菜单数据=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return result;
}
/*update_begin author:wuxianquan date:20190908 for:先查询一级菜单,当用户点击展开菜单时加载子菜单 */
/**
* 系统菜单列表(一级菜单)
*
* @return
*/
@RequestMapping(value = "/getSystemMenuList", method = RequestMethod.GET)
public Result<List<SysPermissionTree>> getSystemMenuList() {
long start = System.currentTimeMillis();
Result<List<SysPermissionTree>> result = new Result<>();
try {
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
query.eq(SysPermission::getMenuType,CommonConstant.MENU_TYPE_0);
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.orderByAsc(SysPermission::getSortNo);
List<SysPermission> list = sysPermissionService.list(query);
List<SysPermissionTree> sysPermissionTreeList = new ArrayList<SysPermissionTree>();
for(SysPermission sysPermission : list){
SysPermissionTree sysPermissionTree = new SysPermissionTree(sysPermission);
sysPermissionTreeList.add(sysPermissionTree);
}
result.setResult(sysPermissionTreeList);
result.setSuccess(true);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
log.info("======获取一级菜单数据=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
return result;
}
/**
* 查询子菜单
* @param parentId
* @return
*/
@RequestMapping(value = "/getSystemSubmenu", method = RequestMethod.GET)
public Result<List<SysPermissionTree>> getSystemSubmenu(@RequestParam("parentId") String parentId){
Result<List<SysPermissionTree>> result = new Result<>();
try{
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
query.eq(SysPermission::getParentId,parentId);
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.orderByAsc(SysPermission::getSortNo);
List<SysPermission> list = sysPermissionService.list(query);
List<SysPermissionTree> sysPermissionTreeList = new ArrayList<SysPermissionTree>();
for(SysPermission sysPermission : list){
SysPermissionTree sysPermissionTree = new SysPermissionTree(sysPermission);
sysPermissionTreeList.add(sysPermissionTree);
}
result.setResult(sysPermissionTreeList);
result.setSuccess(true);
}catch (Exception e){
log.error(e.getMessage(), e);
}
return result;
}
/*update_end author:wuxianquan date:20190908 for:先查询一级菜单,当用户点击展开菜单时加载子菜单 */
// update_begin author:sunjianlei date:20200108 for: 新增批量根据父ID查询子级菜单的接口 -------------
/**
* 查询子菜单
*
* @param parentIds 父ID多个采用半角逗号分割
* @return 返回 key-value 的 Map
*/
@GetMapping("/getSystemSubmenuBatch")
public Result getSystemSubmenuBatch(@RequestParam("parentIds") String parentIds) {
try {
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
List<String> parentIdList = Arrays.asList(parentIds.split(","));
query.in(SysPermission::getParentId, parentIdList);
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.orderByAsc(SysPermission::getSortNo);
List<SysPermission> list = sysPermissionService.list(query);
Map<String, List<SysPermissionTree>> listMap = new HashMap(5);
for (SysPermission item : list) {
String pid = item.getParentId();
if (parentIdList.contains(pid)) {
List<SysPermissionTree> mapList = listMap.get(pid);
if (mapList == null) {
mapList = new ArrayList<>();
}
mapList.add(new SysPermissionTree(item));
listMap.put(pid, mapList);
}
}
return Result.ok(listMap);
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error("批量查询子菜单失败:" + e.getMessage());
}
}
// update_end author:sunjianlei date:20200108 for: 新增批量根据父ID查询子级菜单的接口 -------------
// /**
// * 查询用户拥有的菜单权限和按钮权限(根据用户账号)
// *
// * @return
// */
// @RequestMapping(value = "/queryByUser", method = RequestMethod.GET)
// public Result<JSONArray> queryByUser(HttpServletRequest req) {
// Result<JSONArray> result = new Result<>();
// try {
// String username = req.getParameter("username");
// List<SysPermission> metaList = sysPermissionService.queryByUser(username);
// JSONArray jsonArray = new JSONArray();
// this.getPermissionJsonArray(jsonArray, metaList, null);
// result.setResult(jsonArray);
// result.success("查询成功");
// } catch (Exception e) {
// result.error500("查询失败:" + e.getMessage());
// log.error(e.getMessage(), e);
// }
// return result;
// }
/**
* 查询用户拥有的菜单权限和按钮权限
*
* @return
*/
@RequestMapping(value = "/getUserPermissionByToken", method = RequestMethod.GET)
//@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX)
public Result<?> getUserPermissionByToken(HttpServletRequest request) {
Result<JSONObject> result = new Result<JSONObject>();
try {
//直接获取当前用户不适用前端token
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if (oConvertUtils.isEmpty(loginUser)) {
return Result.error("请登录系统!");
}
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
//添加首页路由
//update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
if(!PermissionDataUtil.hasIndexPage(metaList)){
SysPermission indexMenu = sysPermissionService.list(new LambdaQueryWrapper<SysPermission>().eq(SysPermission::getName,"首页")).get(0);
metaList.add(0,indexMenu);
}
//update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
//update-begin--Author:zyf Date:20220425 for:自定义首页地址 LOWCOD-1578
String version = request.getHeader(CommonConstant.VERSION);
//update-begin---author:liusq ---date:2022-06-29 for接口返回值修改同步修改这里的判断逻辑-----------
SysRoleIndex roleIndex= sysUserService.getDynamicIndexByUserRole(loginUser.getUsername(),version);
//update-end---author:liusq ---date:2022-06-29 for接口返回值修改同步修改这里的判断逻辑-----------
//update-end--Author:zyf Date:20220425 for自定义首页地址 LOWCOD-1578
if(roleIndex!=null){
List<SysPermission> menus = metaList.stream().filter(sysPermission -> "首页".equals(sysPermission.getName())).collect(Collectors.toList());
//update-begin---author:liusq ---date:2022-06-29 for设置自定义首页地址和组件----------
String component = roleIndex.getComponent();
String routeUrl = roleIndex.getUrl();
boolean route = roleIndex.isRoute();
if(oConvertUtils.isNotEmpty(routeUrl)){
menus.get(0).setComponent(component);
menus.get(0).setRoute(route);
menus.get(0).setUrl(routeUrl);
}else{
menus.get(0).setComponent(component);
}
//update-end---author:liusq ---date:2022-06-29 for设置自定义首页地址和组件-----------
}
JSONObject json = new JSONObject();
JSONArray menujsonArray = new JSONArray();
this.getPermissionJsonArray(menujsonArray, metaList, null);
//一级菜单下的子菜单全部是隐藏路由,则一级菜单不显示
this.handleFirstLevelMenuHidden(menujsonArray);
JSONArray authjsonArray = new JSONArray();
this.getAuthJsonArray(authjsonArray, metaList);
//查询所有的权限
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2);
//query.eq(SysPermission::getStatus, "1");
List<SysPermission> allAuthList = sysPermissionService.list(query);
JSONArray allauthjsonArray = new JSONArray();
this.getAllAuthJsonArray(allauthjsonArray, allAuthList);
//路由菜单
json.put("menu", menujsonArray);
//按钮权限(用户拥有的权限集合)
json.put("auth", authjsonArray);
//全部权限配置集合(按钮权限,访问权限)
json.put("allAuth", allauthjsonArray);
json.put("sysSafeMode", jeecgBaseConfig.getSafeMode());
result.setResult(json);
} catch (Exception e) {
result.error500("查询失败:" + e.getMessage());
log.error(e.getMessage(), e);
}
return result;
}
/**
* 【vue3专用】获取
* 1、查询用户拥有的按钮/表单访问权限
* 2、所有权限 (菜单权限配置)
* 3、系统安全模式 (开启则online报表的数据源必填)
*/
@RequestMapping(value = "/getPermCode", method = RequestMethod.GET)
public Result<?> getPermCode() {
try {
// 直接获取当前用户
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if (oConvertUtils.isEmpty(loginUser)) {
return Result.error("请登录系统!");
}
// 获取当前用户的权限集合
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
// 按钮权限(用户拥有的权限集合)
List<String> codeList = metaList.stream()
.filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType()) && CommonConstant.STATUS_1.equals(permission.getStatus()))
.collect(ArrayList::new, (list, permission) -> list.add(permission.getPerms()), ArrayList::addAll);
//
JSONArray authArray = new JSONArray();
this.getAuthJsonArray(authArray, metaList);
// 查询所有的权限
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2);
List<SysPermission> allAuthList = sysPermissionService.list(query);
JSONArray allAuthArray = new JSONArray();
this.getAllAuthJsonArray(allAuthArray, allAuthList);
JSONObject result = new JSONObject();
// 所拥有的权限编码
result.put("codeList", codeList);
//按钮权限(用户拥有的权限集合)
result.put("auth", authArray);
//全部权限配置集合(按钮权限,访问权限)
result.put("allAuth", allAuthArray);
// 系统安全模式
result.put("sysSafeMode", jeecgBaseConfig.getSafeMode());
return Result.OK(result);
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error("查询失败:" + e.getMessage());
}
}
/**
* 添加菜单
* @param permission
* @return
*/
//@RequiresRoles({ "admin" })
@RequestMapping(value = "/add", method = RequestMethod.POST)
public Result<SysPermission> add(@RequestBody SysPermission permission) {
Result<SysPermission> result = new Result<SysPermission>();
try {
permission = PermissionDataUtil.intelligentProcessData(permission);
sysPermissionService.addPermission(permission);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑菜单
* @param permission
* @return
*/
//@RequiresRoles({ "admin" })
@RequestMapping(value = "/edit", method = { RequestMethod.PUT, RequestMethod.POST })
public Result<SysPermission> edit(@RequestBody SysPermission permission) {
Result<SysPermission> result = new Result<>();
try {
permission = PermissionDataUtil.intelligentProcessData(permission);
sysPermissionService.editPermission(permission);
result.success("修改成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 删除菜单
* @param id
* @return
*/
//@RequiresRoles({ "admin" })
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public Result<SysPermission> delete(@RequestParam(name = "id", required = true) String id) {
Result<SysPermission> result = new Result<>();
try {
sysPermissionService.deletePermission(id);
result.success("删除成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500(e.getMessage());
}
return result;
}
/**
* 批量删除菜单
* @param ids
* @return
*/
//@RequiresRoles({ "admin" })
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
public Result<SysPermission> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
Result<SysPermission> result = new Result<>();
try {
String[] arr = ids.split(",");
for (String id : arr) {
if (oConvertUtils.isNotEmpty(id)) {
sysPermissionService.deletePermission(id);
}
}
result.success("删除成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("删除成功!");
}
return result;
}
/**
* 获取全部的权限树
*
* @return
*/
@RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
public Result<Map<String, Object>> queryTreeList() {
Result<Map<String, Object>> result = new Result<>();
// 全部权限ids
List<String> ids = new ArrayList<>();
try {
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.orderByAsc(SysPermission::getSortNo);
List<SysPermission> list = sysPermissionService.list(query);
for (SysPermission sysPer : list) {
ids.add(sysPer.getId());
}
List<TreeModel> treeList = new ArrayList<>();
getTreeModelList(treeList, list, null);
Map<String, Object> resMap = new HashMap<String, Object>(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;
}
/**
* 异步加载数据节点 [接口是废的,没有用到]
*
* @return
*/
@RequestMapping(value = "/queryListAsync", method = RequestMethod.GET)
public Result<List<TreeModel>> queryAsync(@RequestParam(name = "pid", required = false) String parentId) {
Result<List<TreeModel>> result = new Result<>();
try {
List<TreeModel> list = sysPermissionService.queryListByParentId(parentId);
if (list == null || list.size() <= 0) {
result.error500("未找到角色信息");
} else {
result.setResult(list);
result.setSuccess(true);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return result;
}
/**
* 查询角色授权
*
* @return
*/
@RequestMapping(value = "/queryRolePermission", method = RequestMethod.GET)
public Result<List<String>> queryRolePermission(@RequestParam(name = "roleId", required = true) String roleId) {
Result<List<String>> result = new Result<>();
try {
List<SysRolePermission> list = sysRolePermissionService.list(new QueryWrapper<SysRolePermission>().lambda().eq(SysRolePermission::getRoleId, roleId));
result.setResult(list.stream().map(sysRolePermission -> String.valueOf(sysRolePermission.getPermissionId())).collect(Collectors.toList()));
result.setSuccess(true);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return result;
}
/**
* 保存角色授权
*
* @return
*/
@RequestMapping(value = "/saveRolePermission", method = RequestMethod.POST)
//@RequiresRoles({ "admin" })
public Result<String> saveRolePermission(@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.sysRolePermissionService.saveRolePermission(roleId, permissionIds, lastPermissionIds);
//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]用户管理角色授权添加敏感日志------------
result.success("保存成功!");
log.info("======角色授权成功=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
} catch (Exception e) {
result.error500("授权失败!");
log.error(e.getMessage(), e);
}
return result;
}
private void getTreeList(List<SysPermissionTree> treeList, List<SysPermission> metaList, SysPermissionTree temp) {
for (SysPermission permission : metaList) {
String tempPid = permission.getParentId();
SysPermissionTree tree = new SysPermissionTree(permission);
if (temp == null && oConvertUtils.isEmpty(tempPid)) {
treeList.add(tree);
if (!tree.getIsLeaf()) {
getTreeList(treeList, metaList, tree);
}
} else if (temp != null && tempPid != null && tempPid.equals(temp.getId())) {
temp.getChildren().add(tree);
if (!tree.getIsLeaf()) {
getTreeList(treeList, metaList, tree);
}
}
}
}
private void getTreeModelList(List<TreeModel> treeList, List<SysPermission> metaList, TreeModel temp) {
for (SysPermission permission : metaList) {
String tempPid = permission.getParentId();
TreeModel tree = new TreeModel(permission);
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);
}
}
}
}
/**
* 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示
* @param jsonArray
*/
private void handleFirstLevelMenuHidden(JSONArray jsonArray) {
jsonArray = jsonArray.stream().map(obj -> {
JSONObject returnObj = new JSONObject();
JSONObject jsonObj = (JSONObject)obj;
if(jsonObj.containsKey(CHILDREN)){
JSONArray childrens = jsonObj.getJSONArray(CHILDREN);
childrens = childrens.stream().filter(arrObj -> !"true".equals(((JSONObject) arrObj).getString("hidden"))).collect(Collectors.toCollection(JSONArray::new));
if(childrens==null || childrens.size()==0){
jsonObj.put("hidden",true);
//vue3版本兼容代码
JSONObject meta = new JSONObject();
meta.put("hideMenu",true);
jsonObj.put("meta", meta);
}
}
return returnObj;
}).collect(Collectors.toCollection(JSONArray::new));
}
/**
* 获取权限JSON数组
* @param jsonArray
* @param allList
*/
private void getAllAuthJsonArray(JSONArray jsonArray,List<SysPermission> allList) {
JSONObject json = null;
for (SysPermission permission : allList) {
json = new JSONObject();
json.put("action", permission.getPerms());
json.put("status", permission.getStatus());
//1显示2禁用
json.put("type", permission.getPermsType());
json.put("describe", permission.getName());
jsonArray.add(json);
}
}
/**
* 获取权限JSON数组
* @param jsonArray
* @param metaList
*/
private void getAuthJsonArray(JSONArray jsonArray,List<SysPermission> metaList) {
for (SysPermission permission : metaList) {
if(permission.getMenuType()==null) {
continue;
}
JSONObject json = null;
if(permission.getMenuType().equals(CommonConstant.MENU_TYPE_2) &&CommonConstant.STATUS_1.equals(permission.getStatus())) {
json = new JSONObject();
json.put("action", permission.getPerms());
json.put("type", permission.getPermsType());
json.put("describe", permission.getName());
jsonArray.add(json);
}
}
}
/**
* 获取菜单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(json==null) {
continue;
}
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"))) {
// 类型( 0一级菜单 1子菜单 2按钮 )
if (permission.getMenuType().equals(CommonConstant.MENU_TYPE_2)) {
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);
}
// 类型( 0一级菜单 1子菜单 2按钮 )
} else if (permission.getMenuType().equals(CommonConstant.MENU_TYPE_1) || permission.getMenuType().equals(CommonConstant.MENU_TYPE_0)) {
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);
}
}
}
}
}
/**
* 根据菜单配置生成路由json
* @param permission
* @return
*/
private JSONObject getPermissionJsonObject(SysPermission permission) {
JSONObject json = new JSONObject();
// 类型(0一级菜单 1子菜单 2按钮)
if (permission.getMenuType().equals(CommonConstant.MENU_TYPE_2)) {
//json.put("action", permission.getPerms());
//json.put("type", permission.getPermsType());
//json.put("describe", permission.getName());
return null;
} else if (permission.getMenuType().equals(CommonConstant.MENU_TYPE_0) || permission.getMenuType().equals(CommonConstant.MENU_TYPE_1)) {
json.put("id", permission.getId());
if (permission.isRoute()) {
//表示生成路由
json.put("route", "1");
} else {
//表示不生成路由
json.put("route", "0");
}
if (isWwwHttpUrl(permission.getUrl())) {
json.put("path", Md5Util.md5Encode(permission.getUrl(), "utf-8"));
} else {
json.put("path", permission.getUrl());
}
// 重要规则路由name (通过URL生成路由name,路由name供前端开发页面跳转使用)
if (oConvertUtils.isNotEmpty(permission.getComponentName())) {
json.put("name", permission.getComponentName());
} else {
json.put("name", urlToRouteName(permission.getUrl()));
}
JSONObject meta = new JSONObject();
// 是否隐藏路由,默认都是显示的
if (permission.isHidden()) {
json.put("hidden", true);
//vue3版本兼容代码
meta.put("hideMenu",true);
}
// 聚合路由
if (permission.isAlwaysShow()) {
json.put("alwaysShow", true);
}
json.put("component", permission.getComponent());
// 由用户设置是否缓存页面 用布尔值
if (permission.isKeepAlive()) {
meta.put("keepAlive", true);
} else {
meta.put("keepAlive", false);
}
/*update_begin author:wuxianquan date:20190908 for:往菜单信息里添加外链菜单打开方式 */
//外链菜单打开方式
if (permission.isInternalOrExternal()) {
meta.put("internalOrExternal", true);
} else {
meta.put("internalOrExternal", false);
}
/* update_end author:wuxianquan date:20190908 for: 往菜单信息里添加外链菜单打开方式*/
meta.put("title", permission.getName());
//update-begin--Author:scott Date:20201015 for路由缓存问题关闭了tab页时再打开就不刷新 #842
String component = permission.getComponent();
if(oConvertUtils.isNotEmpty(permission.getComponentName()) || oConvertUtils.isNotEmpty(component)){
meta.put("componentName", oConvertUtils.getString(permission.getComponentName(),component.substring(component.lastIndexOf("/")+1)));
}
//update-end--Author:scott Date:20201015 for路由缓存问题关闭了tab页时再打开就不刷新 #842
if (oConvertUtils.isEmpty(permission.getParentId())) {
// 一级菜单跳转地址
json.put("redirect", permission.getRedirect());
if (oConvertUtils.isNotEmpty(permission.getIcon())) {
meta.put("icon", permission.getIcon());
}
} else {
if (oConvertUtils.isNotEmpty(permission.getIcon())) {
meta.put("icon", permission.getIcon());
}
}
if (isWwwHttpUrl(permission.getUrl())) {
meta.put("url", permission.getUrl());
}
// update-begin--Author:sunjianlei Date:20210918 for新增适配vue3项目的隐藏tab功能
if (permission.isHideTab()) {
meta.put("hideTab", true);
}
// update-end--Author:sunjianlei Date:20210918 for新增适配vue3项目的隐藏tab功能
json.put("meta", meta);
}
return json;
}
/**
* 判断是否外网URL 例如: http://localhost:8080/jeecg-boot/swagger-ui.html#/ 支持特殊格式: {{
* window._CONFIG['domianURL'] }}/druid/ {{ JS代码片段 }}前台解析会自动执行JS代码片段
*
* @return
*/
private boolean isWwwHttpUrl(String url) {
boolean flag = url != null && (url.startsWith(CommonConstant.HTTP_PROTOCOL) || url.startsWith(CommonConstant.HTTPS_PROTOCOL) || url.startsWith(SymbolConstant.DOUBLE_LEFT_CURLY_BRACKET));
if (flag) {
return true;
}
return false;
}
/**
* 通过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("/", "-");
// 特殊标记
url = url.replace(":", "@");
return url;
} else {
return null;
}
}
/**
* 根据菜单id来获取其对应的权限数据
*
* @param sysPermissionDataRule
* @return
*/
@RequestMapping(value = "/getPermRuleListByPermId", method = RequestMethod.GET)
public Result<List<SysPermissionDataRule>> getPermRuleListByPermId(SysPermissionDataRule sysPermissionDataRule) {
List<SysPermissionDataRule> permRuleList = sysPermissionDataRuleService.getPermRuleListByPermId(sysPermissionDataRule.getPermissionId());
Result<List<SysPermissionDataRule>> result = new Result<>();
result.setSuccess(true);
result.setResult(permRuleList);
return result;
}
/**
* 添加菜单权限数据
*
* @param sysPermissionDataRule
* @return
*/
//@RequiresRoles({ "admin" })
@RequestMapping(value = "/addPermissionRule", method = RequestMethod.POST)
public Result<SysPermissionDataRule> addPermissionRule(@RequestBody SysPermissionDataRule sysPermissionDataRule) {
Result<SysPermissionDataRule> result = new Result<SysPermissionDataRule>();
try {
sysPermissionDataRule.setCreateTime(new Date());
sysPermissionDataRuleService.savePermissionDataRule(sysPermissionDataRule);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
//@RequiresRoles({ "admin" })
@RequestMapping(value = "/editPermissionRule", method = { RequestMethod.PUT, RequestMethod.POST })
public Result<SysPermissionDataRule> editPermissionRule(@RequestBody SysPermissionDataRule sysPermissionDataRule) {
Result<SysPermissionDataRule> result = new Result<SysPermissionDataRule>();
try {
sysPermissionDataRuleService.saveOrUpdate(sysPermissionDataRule);
result.success("更新成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 删除菜单权限数据
*
* @param id
* @return
*/
//@RequiresRoles({ "admin" })
@RequestMapping(value = "/deletePermissionRule", method = RequestMethod.DELETE)
public Result<SysPermissionDataRule> deletePermissionRule(@RequestParam(name = "id", required = true) String id) {
Result<SysPermissionDataRule> result = new Result<SysPermissionDataRule>();
try {
sysPermissionDataRuleService.deletePermissionDataRule(id);
result.success("删除成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 查询菜单权限数据
*
* @param sysPermissionDataRule
* @return
*/
@RequestMapping(value = "/queryPermissionRule", method = RequestMethod.GET)
public Result<List<SysPermissionDataRule>> queryPermissionRule(SysPermissionDataRule sysPermissionDataRule) {
Result<List<SysPermissionDataRule>> result = new Result<>();
try {
List<SysPermissionDataRule> permRuleList = sysPermissionDataRuleService.queryPermissionRule(sysPermissionDataRule);
result.setResult(permRuleList);
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 部门权限表
* @param departId
* @return
*/
@RequestMapping(value = "/queryDepartPermission", method = RequestMethod.GET)
public Result<List<String>> queryDepartPermission(@RequestParam(name = "departId", required = true) String departId) {
Result<List<String>> result = new Result<>();
try {
List<SysDepartPermission> list = sysDepartPermissionService.list(new QueryWrapper<SysDepartPermission>().lambda().eq(SysDepartPermission::getDepartId, departId));
result.setResult(list.stream().map(sysDepartPermission -> String.valueOf(sysDepartPermission.getPermissionId())).collect(Collectors.toList()));
result.setSuccess(true);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return result;
}
/**
* 保存部门授权
*
* @return
*/
@RequestMapping(value = "/saveDepartPermission", method = RequestMethod.POST)
//@RequiresRoles({ "admin" })
public Result<String> saveDepartPermission(@RequestBody JSONObject json) {
long start = System.currentTimeMillis();
Result<String> result = new Result<>();
try {
String departId = json.getString("departId");
String permissionIds = json.getString("permissionIds");
String lastPermissionIds = json.getString("lastpermissionIds");
this.sysDepartPermissionService.saveDepartPermission(departId, permissionIds, lastPermissionIds);
result.success("保存成功!");
log.info("======部门授权成功=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
} catch (Exception e) {
result.error500("授权失败!");
log.error(e.getMessage(), e);
}
return result;
}
}

View File

@ -0,0 +1,284 @@
package org.jeecg.modules.system.controller;
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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.quartz.service.IQuartzJobService;
import org.jeecg.modules.system.entity.SysPosition;
import org.jeecg.modules.system.service.ISysPositionService;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @Description: 职务表
* @Author: jeecg-boot
* @Date: 2019-09-19
* @Version: V1.0
*/
@Slf4j
@Api(tags = "职务表")
@RestController
@RequestMapping("/sys/position")
public class SysPositionController {
@Autowired
private ISysPositionService sysPositionService;
/**
* 分页列表查询
*
* @param sysPosition
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@AutoLog(value = "职务表-分页列表查询")
@ApiOperation(value = "职务表-分页列表查询", notes = "职务表-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<SysPosition>> queryPageList(SysPosition sysPosition,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<SysPosition>> result = new Result<IPage<SysPosition>>();
QueryWrapper<SysPosition> queryWrapper = QueryGenerator.initQueryWrapper(sysPosition, req.getParameterMap());
Page<SysPosition> page = new Page<SysPosition>(pageNo, pageSize);
IPage<SysPosition> pageList = sysPositionService.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}
/**
* 添加
*
* @param sysPosition
* @return
*/
@AutoLog(value = "职务表-添加")
@ApiOperation(value = "职务表-添加", notes = "职务表-添加")
@PostMapping(value = "/add")
public Result<SysPosition> add(@RequestBody SysPosition sysPosition) {
Result<SysPosition> result = new Result<SysPosition>();
try {
sysPositionService.save(sysPosition);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑
*
* @param sysPosition
* @return
*/
@AutoLog(value = "职务表-编辑")
@ApiOperation(value = "职务表-编辑", notes = "职务表-编辑")
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
public Result<SysPosition> edit(@RequestBody SysPosition sysPosition) {
Result<SysPosition> result = new Result<SysPosition>();
SysPosition sysPositionEntity = sysPositionService.getById(sysPosition.getId());
if (sysPositionEntity == null) {
result.error500("未找到对应实体");
} else {
boolean ok = sysPositionService.updateById(sysPosition);
//TODO 返回false说明什么
if (ok) {
result.success("修改成功!");
}
}
return result;
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "职务表-通过id删除")
@ApiOperation(value = "职务表-通过id删除", notes = "职务表-通过id删除")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
try {
sysPositionService.removeById(id);
} catch (Exception e) {
log.error("删除失败", e.getMessage());
return Result.error("删除失败!");
}
return Result.ok("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "职务表-批量删除")
@ApiOperation(value = "职务表-批量删除", notes = "职务表-批量删除")
@DeleteMapping(value = "/deleteBatch")
public Result<SysPosition> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
Result<SysPosition> result = new Result<SysPosition>();
if (ids == null || "".equals(ids.trim())) {
result.error500("参数不识别!");
} else {
this.sysPositionService.removeByIds(Arrays.asList(ids.split(",")));
result.success("删除成功!");
}
return result;
}
/**
* 通过id查询
*
* @param id
* @return
*/
@AutoLog(value = "职务表-通过id查询")
@ApiOperation(value = "职务表-通过id查询", notes = "职务表-通过id查询")
@GetMapping(value = "/queryById")
public Result<SysPosition> queryById(@RequestParam(name = "id", required = true) String id) {
Result<SysPosition> result = new Result<SysPosition>();
SysPosition sysPosition = sysPositionService.getById(id);
if (sysPosition == null) {
result.error500("未找到对应实体");
} else {
result.setResult(sysPosition);
result.setSuccess(true);
}
return result;
}
/**
* 导出excel
*
* @param request
* @param response
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
// Step.1 组装查询条件
QueryWrapper<SysPosition> queryWrapper = null;
try {
String paramsStr = request.getParameter("paramsStr");
if (oConvertUtils.isNotEmpty(paramsStr)) {
String deString = URLDecoder.decode(paramsStr, "UTF-8");
SysPosition sysPosition = JSON.parseObject(deString, SysPosition.class);
queryWrapper = QueryGenerator.initQueryWrapper(sysPosition, request.getParameterMap());
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<SysPosition> pageList = sysPositionService.list(queryWrapper);
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "职务表列表");
mv.addObject(NormalExcelConstants.CLASS, SysPosition.class);
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)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<Object> listSysPositions = ExcelImportUtil.importExcel(file.getInputStream(), SysPosition.class, params);
List<String> list = ImportExcelUtil.importDateSave(listSysPositions, ISysPositionService.class, errorMessage,CommonConstant.SQL_INDEX_UNIQ_CODE);
errorLines+=list.size();
successLines+=(listSysPositions.size()-errorLines);
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error("文件导入失败:" + e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return ImportExcelUtil.imporReturnRes(errorLines,successLines,errorMessage);
}
/**
* 通过code查询
*
* @param code
* @return
*/
@AutoLog(value = "职务表-通过code查询")
@ApiOperation(value = "职务表-通过code查询", notes = "职务表-通过code查询")
@GetMapping(value = "/queryByCode")
public Result<SysPosition> queryByCode(@RequestParam(name = "code", required = true) String code) {
Result<SysPosition> result = new Result<SysPosition>();
QueryWrapper<SysPosition> queryWrapper = new QueryWrapper<SysPosition>();
queryWrapper.eq("code",code);
SysPosition sysPosition = sysPositionService.getOne(queryWrapper);
if (sysPosition == null) {
result.error500("未找到对应实体");
} else {
result.setResult(sysPosition);
result.setSuccess(true);
}
return result;
}
}

View File

@ -0,0 +1,413 @@
package org.jeecg.modules.system.controller;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.system.query.QueryGenerator;
import org.jeecg.common.util.PmsUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysPermission;
import org.jeecg.modules.system.entity.SysPermissionDataRule;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.entity.SysRolePermission;
import org.jeecg.modules.system.model.TreeModel;
import org.jeecg.modules.system.service.ISysPermissionDataRuleService;
import org.jeecg.modules.system.service.ISysPermissionService;
import org.jeecg.modules.system.service.ISysRolePermissionService;
import org.jeecg.modules.system.service.ISysRoleService;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import org.jeecg.common.system.vo.LoginUser;
import org.apache.shiro.SecurityUtils;
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 lombok.extern.slf4j.Slf4j;
/**
* <p>
* 角色表 前端控制器
* </p>
*
* @Author scott
* @since 2018-12-19
*/
@RestController
@RequestMapping("/sys/role")
@Slf4j
public class SysRoleController {
@Autowired
private ISysRoleService sysRoleService;
@Autowired
private ISysPermissionDataRuleService sysPermissionDataRuleService;
@Autowired
private ISysRolePermissionService sysRolePermissionService;
@Autowired
private ISysPermissionService sysPermissionService;
/**
* 分页列表查询
* @param role
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<IPage<SysRole>> queryPageList(SysRole role,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
Page<SysRole> page = new Page<SysRole>(pageNo, pageSize);
IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}
/**
* 添加
* @param role
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
//@RequiresRoles({"admin"})
public Result<SysRole> add(@RequestBody SysRole role) {
Result<SysRole> result = new Result<SysRole>();
try {
role.setCreateTime(new Date());
sysRoleService.save(role);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑
* @param role
* @return
*/
//@RequiresRoles({"admin"})
@RequestMapping(value = "/edit",method = {RequestMethod.PUT,RequestMethod.POST})
public Result<SysRole> edit(@RequestBody SysRole role) {
Result<SysRole> result = new Result<SysRole>();
SysRole sysrole = sysRoleService.getById(role.getId());
if(sysrole==null) {
result.error500("未找到对应实体");
}else {
role.setUpdateTime(new Date());
boolean ok = sysRoleService.updateById(role);
//TODO 返回false说明什么
if(ok) {
result.success("修改成功!");
}
}
return result;
}
/**
* 通过id删除
* @param id
* @return
*/
//@RequiresRoles({"admin"})
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
sysRoleService.deleteRole(id);
return Result.ok("删除角色成功");
}
/**
* 批量删除
* @param ids
* @return
*/
//@RequiresRoles({"admin"})
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
public Result<SysRole> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
Result<SysRole> result = new Result<SysRole>();
if(oConvertUtils.isEmpty(ids)) {
result.error500("未选中角色!");
}else {
sysRoleService.deleteBatchRole(ids.split(","));
result.success("删除角色成功!");
}
return result;
}
/**
* 通过id查询
* @param id
* @return
*/
@RequestMapping(value = "/queryById", method = RequestMethod.GET)
public Result<SysRole> queryById(@RequestParam(name="id",required=true) String id) {
Result<SysRole> result = new Result<SysRole>();
SysRole sysrole = sysRoleService.getById(id);
if(sysrole==null) {
result.error500("未找到对应实体");
}else {
result.setResult(sysrole);
result.setSuccess(true);
}
return result;
}
@RequestMapping(value = "/queryall", method = RequestMethod.GET)
public Result<List<SysRole>> queryall() {
Result<List<SysRole>> result = new Result<>();
List<SysRole> list = sysRoleService.list();
if(list==null||list.size()<=0) {
result.error500("未找到角色信息");
}else {
result.setResult(list);
result.setSuccess(true);
}
return result;
}
/**
* 校验角色编码唯一
*/
@RequestMapping(value = "/checkRoleCode", method = RequestMethod.GET)
public Result<Boolean> checkUsername(String id,String roleCode) {
Result<Boolean> result = new Result<>();
//如果此参数为false则程序发生异常
result.setResult(true);
log.info("--验证角色编码是否唯一---id:"+id+"--roleCode:"+roleCode);
try {
SysRole role = null;
if(oConvertUtils.isNotEmpty(id)) {
role = sysRoleService.getById(id);
}
SysRole newRole = sysRoleService.getOne(new QueryWrapper<SysRole>().lambda().eq(SysRole::getRoleCode, roleCode));
if(newRole!=null) {
//如果根据传入的roleCode查询到信息了那么就需要做校验了。
if(role==null) {
//role为空=>新增模式=>只要roleCode存在则返回false
result.setSuccess(false);
result.setMessage("角色编码已存在");
return result;
}else if(!id.equals(newRole.getId())) {
//否则=>编辑模式=>判断两者ID是否一致-
result.setSuccess(false);
result.setMessage("角色编码已存在");
return result;
}
}
} catch (Exception e) {
result.setSuccess(false);
result.setResult(false);
result.setMessage(e.getMessage());
return result;
}
result.setSuccess(true);
return result;
}
/**
* 导出excel
* @param request
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(SysRole sysRole,HttpServletRequest request) {
// Step.1 组装查询条件
QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(sysRole, request.getParameterMap());
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<SysRole> pageList = sysRoleService.list(queryWrapper);
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME,"角色列表");
mv.addObject(NormalExcelConstants.CLASS,SysRole.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 {
return sysRoleService.importExcelCheckRoleCode(file, params);
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error("文件导入失败:" + e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
return Result.error("文件导入失败!");
}
/**
* 查询数据规则数据
*/
@GetMapping(value = "/datarule/{permissionId}/{roleId}")
public Result<?> loadDatarule(@PathVariable("permissionId") String permissionId,@PathVariable("roleId") String roleId) {
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<SysRolePermission> query = new LambdaQueryWrapper<SysRolePermission>()
.eq(SysRolePermission::getPermissionId, permissionId)
.isNotNull(SysRolePermission::getDataRuleIds)
.eq(SysRolePermission::getRoleId,roleId);
SysRolePermission sysRolePermission = sysRolePermissionService.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<SysRolePermission> query = new LambdaQueryWrapper<SysRolePermission>()
.eq(SysRolePermission::getPermissionId, permissionId)
.eq(SysRolePermission::getRoleId,roleId);
SysRolePermission sysRolePermission = sysRolePermissionService.getOne(query);
if(sysRolePermission==null) {
return Result.error("请先保存角色菜单权限!");
}else {
sysRolePermission.setDataRuleIds(dataRuleIds);
this.sysRolePermissionService.updateById(sysRolePermission);
}
} catch (Exception e) {
log.error("SysRoleController.saveDatarule()发生异常:" + e.getMessage(),e);
return Result.error("保存失败");
}
return Result.ok("保存成功!");
}
/**
* 用户角色授权功能,查询菜单权限树
* @param request
* @return
*/
@RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
public Result<Map<String,Object>> queryTreeList(HttpServletRequest request) {
Result<Map<String,Object>> result = new Result<>();
//全部权限ids
List<String> ids = new ArrayList<>();
try {
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.orderByAsc(SysPermission::getSortNo);
List<SysPermission> list = sysPermissionService.list(query);
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);
}
}
}
}
}

View File

@ -0,0 +1,171 @@
package org.jeecg.modules.system.controller;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.modules.system.entity.SysRoleIndex;
import org.jeecg.modules.system.service.ISysRoleIndexService;
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;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/**
* @Description: 角色首页配置
* @Author: jeecg-boot
* @Date: 2022-03-25
* @Version: V1.0
*/
@Slf4j
@Api(tags = "角色首页配置")
@RestController
@RequestMapping("/sys/sysRoleIndex")
public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRoleIndexService> {
@Autowired
private ISysRoleIndexService sysRoleIndexService;
/**
* 分页列表查询
*
* @param sysRoleIndex
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@AutoLog(value = "角色首页配置-分页列表查询")
@ApiOperation(value = "角色首页配置-分页列表查询", notes = "角色首页配置-分页列表查询")
@GetMapping(value = "/list")
public Result<?> queryPageList(SysRoleIndex sysRoleIndex,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<SysRoleIndex> queryWrapper = QueryGenerator.initQueryWrapper(sysRoleIndex, req.getParameterMap());
Page<SysRoleIndex> page = new Page<SysRoleIndex>(pageNo, pageSize);
IPage<SysRoleIndex> pageList = sysRoleIndexService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param sysRoleIndex
* @return
*/
@AutoLog(value = "角色首页配置-添加")
@ApiOperation(value = "角色首页配置-添加", notes = "角色首页配置-添加")
@PostMapping(value = "/add")
//@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX)
public Result<?> add(@RequestBody SysRoleIndex sysRoleIndex,HttpServletRequest request) {
sysRoleIndexService.save(sysRoleIndex);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param sysRoleIndex
* @return
*/
@AutoLog(value = "角色首页配置-编辑")
@ApiOperation(value = "角色首页配置-编辑", notes = "角色首页配置-编辑")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
//@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX)
public Result<?> edit(@RequestBody SysRoleIndex sysRoleIndex,HttpServletRequest request) {
sysRoleIndexService.updateById(sysRoleIndex);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "角色首页配置-通过id删除")
@ApiOperation(value = "角色首页配置-通过id删除", notes = "角色首页配置-通过id删除")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
sysRoleIndexService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "角色首页配置-批量删除")
@ApiOperation(value = "角色首页配置-批量删除", notes = "角色首页配置-批量删除")
@DeleteMapping(value = "/deleteBatch")
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
this.sysRoleIndexService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
@AutoLog(value = "角色首页配置-通过id查询")
@ApiOperation(value = "角色首页配置-通过id查询", notes = "角色首页配置-通过id查询")
@GetMapping(value = "/queryById")
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
SysRoleIndex sysRoleIndex = sysRoleIndexService.getById(id);
return Result.OK(sysRoleIndex);
}
/**
* 导出excel
*
* @param request
* @param sysRoleIndex
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, SysRoleIndex sysRoleIndex) {
return super.exportXls(request, sysRoleIndex, SysRoleIndex.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, SysRoleIndex.class);
}
/**
* 通过code查询
*
* @param roleCode
* @return
*/
@AutoLog(value = "角色首页配置-通过code查询")
@ApiOperation(value = "角色首页配置-通过code查询", notes = "角色首页配置-通过code查询")
@GetMapping(value = "/queryByCode")
//@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX)
public Result<?> queryByCode(@RequestParam(name = "roleCode", required = true) String roleCode,HttpServletRequest request) {
SysRoleIndex sysRoleIndex = sysRoleIndexService.getOne(new LambdaQueryWrapper<SysRoleIndex>().eq(SysRoleIndex::getRoleCode, roleCode));
return Result.OK(sysRoleIndex);
}
}

View File

@ -0,0 +1,223 @@
package org.jeecg.modules.system.controller;
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.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.PermissionData;
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.oConvertUtils;
import org.jeecg.modules.system.entity.SysTenant;
import org.jeecg.modules.system.service.ISysTenantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* 租户配置信息
* @author: jeecg-boot
*/
@Slf4j
@RestController
@RequestMapping("/sys/tenant")
public class SysTenantController {
@Autowired
private ISysTenantService sysTenantService;
/**
* 获取列表数据
* @param sysTenant
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@PermissionData(pageComponent = "system/TenantList")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<IPage<SysTenant>> queryPageList(SysTenant sysTenant,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
Result<IPage<SysTenant>> result = new Result<IPage<SysTenant>>();
//---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
Date beginDate=null;
Date endDate=null;
if(oConvertUtils.isNotEmpty(sysTenant)) {
beginDate=sysTenant.getBeginDate();
endDate=sysTenant.getEndDate();
sysTenant.setBeginDate(null);
sysTenant.setEndDate(null);
}
//---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
QueryWrapper<SysTenant> queryWrapper = QueryGenerator.initQueryWrapper(sysTenant, req.getParameterMap());
//---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
if(oConvertUtils.isNotEmpty(sysTenant)){
queryWrapper.ge(oConvertUtils.isNotEmpty(beginDate),"begin_date",beginDate);
queryWrapper.le(oConvertUtils.isNotEmpty(endDate),"end_date",endDate);
}
//---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
Page<SysTenant> page = new Page<SysTenant>(pageNo, pageSize);
IPage<SysTenant> pageList = sysTenantService.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}
/**
* 添加
* @param
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public Result<SysTenant> add(@RequestBody SysTenant sysTenant) {
Result<SysTenant> result = new Result();
if(sysTenantService.getById(sysTenant.getId())!=null){
return result.error500("该编号已存在!");
}
try {
sysTenantService.save(sysTenant);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑
* @param
* @return
*/
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
public Result<SysTenant> edit(@RequestBody SysTenant tenant) {
Result<SysTenant> result = new Result();
SysTenant sysTenant = sysTenantService.getById(tenant.getId());
if(sysTenant==null) {
return result.error500("未找到对应实体");
}
boolean ok = sysTenantService.updateById(tenant);
if(ok) {
result.success("修改成功!");
}
return result;
}
/**
* 通过id删除
* @param id
* @return
*/
@RequestMapping(value = "/delete", method ={RequestMethod.DELETE, RequestMethod.POST})
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
sysTenantService.removeTenantById(id);
return Result.ok("删除成功");
}
/**
* 批量删除
* @param ids
* @return
*/
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
Result<?> result = new Result<>();
if(oConvertUtils.isEmpty(ids)) {
result.error500("未选中租户!");
}else {
String[] ls = ids.split(",");
// 过滤掉已被引用的租户
List<Integer> idList = new ArrayList<>();
for (String id : ls) {
Long userCount = sysTenantService.countUserLinkTenant(id);
if (userCount == 0) {
idList.add(Integer.parseInt(id));
}
}
if (idList.size() > 0) {
sysTenantService.removeByIds(idList);
if (ls.length == idList.size()) {
result.success("删除成功!");
} else {
result.success("部分删除成功!(被引用的租户无法删除)");
}
}else {
result.error500("选择的租户都已被引用,无法删除!");
}
}
return result;
}
/**
* 通过id查询
* @param id
* @return
*/
@RequestMapping(value = "/queryById", method = RequestMethod.GET)
public Result<SysTenant> queryById(@RequestParam(name="id",required=true) String id) {
Result<SysTenant> result = new Result<SysTenant>();
SysTenant sysTenant = sysTenantService.getById(id);
if(sysTenant==null) {
result.error500("未找到对应实体");
}else {
result.setResult(sysTenant);
result.setSuccess(true);
}
return result;
}
/**
* 查询有效的 租户数据
* @return
*/
@RequestMapping(value = "/queryList", method = RequestMethod.GET)
public Result<List<SysTenant>> queryList(@RequestParam(name="ids",required=false) String ids) {
Result<List<SysTenant>> result = new Result<List<SysTenant>>();
LambdaQueryWrapper<SysTenant> query = new LambdaQueryWrapper<>();
query.eq(SysTenant::getStatus, 1);
if(oConvertUtils.isNotEmpty(ids)){
query.in(SysTenant::getId, ids.split(","));
}
//此处查询忽略时间条件
List<SysTenant> ls = sysTenantService.list(query);
result.setSuccess(true);
result.setResult(ls);
return result;
}
/**
* 查询当前用户的所有有效租户 【当前用于vue3版本】
* @return
*/
@RequestMapping(value = "/getCurrentUserTenant", method = RequestMethod.GET)
public Result<Map<String,Object>> getCurrentUserTenant() {
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
try {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String tenantIds = sysUser.getRelTenantIds();
Map<String,Object> map = new HashMap(5);
if (oConvertUtils.isNotEmpty(tenantIds)) {
List<Integer> tenantIdList = new ArrayList<>();
for(String id: tenantIds.split(SymbolConstant.COMMA)){
tenantIdList.add(Integer.valueOf(id));
}
// 该方法仅查询有效的租户如果返回0个就说明所有的租户均无效。
List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
map.put("list", tenantList);
}
result.setSuccess(true);
result.setResult(map);
}catch(Exception e) {
log.error(e.getMessage(), e);
result.error500("查询失败!");
}
return result;
}
}

View File

@ -0,0 +1,68 @@
package org.jeecg.modules.system.controller;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.MinioUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.oss.entity.OssFile;
import org.jeecg.modules.oss.service.IOssFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
/**
* minio文件上传示例
* @author: jeecg-boot
*/
@Slf4j
@RestController
@RequestMapping("/sys/upload")
public class SysUploadController {
@Autowired
private IOssFileService ossFileService;
/**
* 上传
* @param request
*/
@PostMapping(value = "/uploadMinio")
public Result<?> uploadMinio(HttpServletRequest request) {
Result<?> result = new Result<>();
String bizPath = request.getParameter("biz");
//LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
boolean flag = oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"));
if (flag) {
throw new JeecgBootException("上传目录bizPath格式非法");
}
if(oConvertUtils.isEmpty(bizPath)){
bizPath = "";
}
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
// 获取上传文件对象
MultipartFile file = multipartRequest.getFile("file");
// 获取文件名
String orgName = file.getOriginalFilename();
orgName = CommonUtils.getFileName(orgName);
String fileUrl = MinioUtil.upload(file,bizPath);
if(oConvertUtils.isEmpty(fileUrl)){
return Result.error("上传失败,请检查配置信息是否正确!");
}
//保存文件信息
OssFile minioFile = new OssFile();
minioFile.setFileName(orgName);
minioFile.setUrl(fileUrl);
ossFileService.save(minioFile);
result.setMessage(fileUrl);
result.setSuccess(true);
return result;
}
}

View File

@ -0,0 +1,265 @@
package org.jeecg.modules.system.controller;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysUserAgent;
import org.jeecg.modules.system.service.ISysUserAgentService;
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.beans.factory.annotation.Value;
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.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.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;
/**
* @Title: Controller
* @Description: 用户代理人设置
* @Author: jeecg-boot
* @Date: 2019-04-17
* @Version: V1.0
*/
@RestController
@RequestMapping("/sys/sysUserAgent")
@Slf4j
public class SysUserAgentController {
@Autowired
private ISysUserAgentService sysUserAgentService;
@Value("${jeecg.path.upload}")
private String upLoadPath;
/**
* 分页列表查询
* @param sysUserAgent
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@GetMapping(value = "/list")
public Result<IPage<SysUserAgent>> queryPageList(SysUserAgent sysUserAgent,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<SysUserAgent>> result = new Result<IPage<SysUserAgent>>();
QueryWrapper<SysUserAgent> queryWrapper = QueryGenerator.initQueryWrapper(sysUserAgent, req.getParameterMap());
Page<SysUserAgent> page = new Page<SysUserAgent>(pageNo, pageSize);
IPage<SysUserAgent> pageList = sysUserAgentService.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}
/**
* 添加
* @param sysUserAgent
* @return
*/
@PostMapping(value = "/add")
public Result<SysUserAgent> add(@RequestBody SysUserAgent sysUserAgent) {
Result<SysUserAgent> result = new Result<SysUserAgent>();
try {
sysUserAgentService.save(sysUserAgent);
result.success("代理人设置成功!");
} catch (Exception e) {
log.error(e.getMessage(),e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑
* @param sysUserAgent
* @return
*/
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<SysUserAgent> edit(@RequestBody SysUserAgent sysUserAgent) {
Result<SysUserAgent> result = new Result<SysUserAgent>();
SysUserAgent sysUserAgentEntity = sysUserAgentService.getById(sysUserAgent.getId());
if(sysUserAgentEntity==null) {
result.error500("未找到对应实体");
}else {
boolean ok = sysUserAgentService.updateById(sysUserAgent);
//TODO 返回false说明什么
if(ok) {
result.success("代理人设置成功!");
}
}
return result;
}
/**
* 通过id删除
* @param id
* @return
*/
@DeleteMapping(value = "/delete")
public Result<SysUserAgent> delete(@RequestParam(name="id",required=true) String id) {
Result<SysUserAgent> result = new Result<SysUserAgent>();
SysUserAgent sysUserAgent = sysUserAgentService.getById(id);
if(sysUserAgent==null) {
result.error500("未找到对应实体");
}else {
boolean ok = sysUserAgentService.removeById(id);
if(ok) {
result.success("删除成功!");
}
}
return result;
}
/**
* 批量删除
* @param ids
* @return
*/
@DeleteMapping(value = "/deleteBatch")
public Result<SysUserAgent> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
Result<SysUserAgent> result = new Result<SysUserAgent>();
if(ids==null || "".equals(ids.trim())) {
result.error500("参数不识别!");
}else {
this.sysUserAgentService.removeByIds(Arrays.asList(ids.split(",")));
result.success("删除成功!");
}
return result;
}
/**
* 通过id查询
* @param id
* @return
*/
@GetMapping(value = "/queryById")
public Result<SysUserAgent> queryById(@RequestParam(name="id",required=true) String id) {
Result<SysUserAgent> result = new Result<SysUserAgent>();
SysUserAgent sysUserAgent = sysUserAgentService.getById(id);
if(sysUserAgent==null) {
result.error500("未找到对应实体");
}else {
result.setResult(sysUserAgent);
result.setSuccess(true);
}
return result;
}
/**
* 通过userName查询
* @param userName
* @return
*/
@GetMapping(value = "/queryByUserName")
public Result<SysUserAgent> queryByUserName(@RequestParam(name="userName",required=true) String userName) {
Result<SysUserAgent> result = new Result<SysUserAgent>();
LambdaQueryWrapper<SysUserAgent> queryWrapper = new LambdaQueryWrapper<SysUserAgent>();
queryWrapper.eq(SysUserAgent::getUserName, userName);
SysUserAgent sysUserAgent = sysUserAgentService.getOne(queryWrapper);
if(sysUserAgent==null) {
result.error500("未找到对应实体");
}else {
result.setResult(sysUserAgent);
result.setSuccess(true);
}
return result;
}
/**
* 导出excel
*
* @param sysUserAgent
* @param request
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(SysUserAgent sysUserAgent,HttpServletRequest request) {
// Step.1 组装查询条件
QueryWrapper<SysUserAgent> queryWrapper = QueryGenerator.initQueryWrapper(sysUserAgent, request.getParameterMap());
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<SysUserAgent> pageList = sysUserAgentService.list(queryWrapper);
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "用户代理人设置列表");
mv.addObject(NormalExcelConstants.CLASS, SysUserAgent.class);
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
ExportParams exportParams = new ExportParams("用户代理人设置列表数据", "导出人:"+user.getRealname(), "导出信息");
exportParams.setImageBasePath(upLoadPath);
mv.addObject(NormalExcelConstants.PARAMS, exportParams);
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<SysUserAgent> listSysUserAgents = ExcelImportUtil.importExcel(file.getInputStream(), SysUserAgent.class, params);
for (SysUserAgent sysUserAgentExcel : listSysUserAgents) {
sysUserAgentService.save(sysUserAgentExcel);
}
return Result.ok("文件导入成功!数据行数:" + listSysUserAgents.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("文件导入失败!");
}
}

View File

@ -0,0 +1,130 @@
package org.jeecg.modules.system.controller;
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.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
import org.jeecg.modules.system.vo.SysUserOnlineVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @Description: 在线用户
* @Author: chenli
* @Date: 2020-06-07
* @Version: V1.0
*/
@RestController
@RequestMapping("/sys/online")
@Slf4j
public class SysUserOnlineController {
@Autowired
private RedisUtil redisUtil;
@Autowired
public RedisTemplate redisTemplate;
@Autowired
public ISysUserService userService;
@Autowired
private SysBaseApiImpl sysBaseApi;
@Resource
private BaseCommonService baseCommonService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<Page<SysUserOnlineVO>> list(@RequestParam(name="username", required=false) String username,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*");
List<SysUserOnlineVO> onlineList = new ArrayList<SysUserOnlineVO>();
for (String key : keys) {
String token = (String)redisUtil.get(key);
if (StringUtils.isNotEmpty(token)) {
SysUserOnlineVO online = new SysUserOnlineVO();
online.setToken(token);
//TODO 改成一次性查询
LoginUser loginUser = sysBaseApi.getUserByName(JwtUtil.getUsername(token));
if (loginUser != null) {
//update-begin---author:wangshuai ---date:20220104 for[JTC-382]在线用户查询无效------------
//验证用户名是否与传过来的用户名相同
boolean isMatchUsername=true;
//判断用户名是否为空并且当前循环的用户不包含传过来的用户名那么就设成false
if(oConvertUtils.isNotEmpty(username) && !loginUser.getUsername().contains(username)){
isMatchUsername = false;
}
if(isMatchUsername){
BeanUtils.copyProperties(loginUser, online);
onlineList.add(online);
}
//update-end---author:wangshuai ---date:20220104 for[JTC-382]在线用户查询无效------------
}
}
}
Collections.reverse(onlineList);
Page<SysUserOnlineVO> page = new Page<SysUserOnlineVO>(pageNo, pageSize);
int count = onlineList.size();
List<SysUserOnlineVO> pages = new ArrayList<>();
// 计算当前页第一条数据的下标
int currId = pageNo > 1 ? (pageNo - 1) * pageSize : 0;
for (int i = 0; i < pageSize && i < count - currId; i++) {
pages.add(onlineList.get(currId + i));
}
page.setSize(pageSize);
page.setCurrent(pageNo);
page.setTotal(count);
// 计算分页总页数
page.setPages(count % 10 == 0 ? count / 10 : count / 10 + 1);
page.setRecords(pages);
Result<Page<SysUserOnlineVO>> result = new Result<Page<SysUserOnlineVO>>();
result.setSuccess(true);
result.setResult(page);
return result;
}
/**
* 强退用户
*/
@RequestMapping(value = "/forceLogout",method = RequestMethod.POST)
public Result<Object> forceLogout(@RequestBody SysUserOnlineVO online) {
//用户退出逻辑
if(oConvertUtils.isEmpty(online.getToken())) {
return Result.error("退出登录失败!");
}
String username = JwtUtil.getUsername(online.getToken());
LoginUser sysUser = sysBaseApi.getUserByName(username);
if(sysUser!=null) {
baseCommonService.addLog("强制: "+sysUser.getRealname()+"退出成功!", CommonConstant.LOG_TYPE_1, null,sysUser);
log.info(" 强制 "+sysUser.getRealname()+"退出成功! ");
//清空用户登录Token缓存
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + online.getToken());
//清空用户登录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无效!");
}
}
}

View File

@ -0,0 +1,270 @@
package org.jeecg.modules.system.controller;
import com.alibaba.fastjson.JSONObject;
import com.jeecg.dingtalk.api.core.response.Response;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.config.thirdapp.ThirdAppConfig;
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* 第三方App对接
* @author: jeecg-boot
*/
@Slf4j
@RestController("thirdAppController")
@RequestMapping("/sys/thirdApp")
public class ThirdAppController {
@Autowired
ThirdAppConfig thirdAppConfig;
@Autowired
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
@Autowired
ThirdAppDingtalkServiceImpl dingtalkService;
/**
* 获取启用的系统
*/
@GetMapping("/getEnabledType")
public Result getEnabledType() {
Map<String, Boolean> enabledMap = new HashMap(5);
enabledMap.put("wechatEnterprise", thirdAppConfig.isWechatEnterpriseEnabled());
enabledMap.put("dingtalk", thirdAppConfig.isDingtalkEnabled());
return Result.OK(enabledMap);
}
/**
* 同步本地[用户]到【企业微信】
*
* @param ids
* @return
*/
@GetMapping("/sync/wechatEnterprise/user/toApp")
public Result syncWechatEnterpriseUserToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalUserToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("企业微信同步功能已禁用");
}
/**
* 同步【企业微信】[用户]到本地
*
* @param ids 作废
* @return
*/
@GetMapping("/sync/wechatEnterprise/user/toLocal")
public Result syncWechatEnterpriseUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
SyncInfoVo syncInfo = wechatEnterpriseService.syncThirdAppUserToLocal();
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("企业微信同步功能已禁用");
}
/**
* 同步本地[部门]到【企业微信】
*
* @param ids
* @return
*/
@GetMapping("/sync/wechatEnterprise/depart/toApp")
public Result syncWechatEnterpriseDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", null);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("企业微信同步功能已禁用");
}
/**
* 同步【企业微信】[部门]到本地
*
* @param ids
* @return
*/
@GetMapping("/sync/wechatEnterprise/depart/toLocal")
public Result syncWechatEnterpriseDepartToLocal(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
SyncInfoVo syncInfo = wechatEnterpriseService.syncThirdAppDepartmentToLocal(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("企业微信同步功能已禁用");
}
/**
* 同步本地[部门]到【钉钉】
*
* @param ids
* @return
*/
@GetMapping("/sync/dingtalk/depart/toApp")
public Result syncDingtalkDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isDingtalkEnabled()) {
SyncInfoVo syncInfo = dingtalkService.syncLocalDepartmentToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", null);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉同步功能已禁用");
}
/**
* 同步【钉钉】[部门]到本地
*
* @param ids
* @return
*/
@GetMapping("/sync/dingtalk/depart/toLocal")
public Result syncDingtalkDepartToLocal(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isDingtalkEnabled()) {
SyncInfoVo syncInfo = dingtalkService.syncThirdAppDepartmentToLocal(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉同步功能已禁用");
}
/**
* 同步本地[用户]到【钉钉】
*
* @param ids
* @return
*/
@GetMapping("/sync/dingtalk/user/toApp")
public Result syncDingtalkUserToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isDingtalkEnabled()) {
SyncInfoVo syncInfo = dingtalkService.syncLocalUserToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉同步功能已禁用");
}
/**
* 同步【钉钉】[用户]到本地
*
* @param ids 作废
* @return
*/
@GetMapping("/sync/dingtalk/user/toLocal")
public Result syncDingtalkUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isDingtalkEnabled()) {
SyncInfoVo syncInfo = dingtalkService.syncThirdAppUserToLocal();
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉同步功能已禁用");
}
/**
* 发送消息测试
*
* @return
*/
@PostMapping("/sendMessageTest")
public Result sendMessageTest(@RequestBody JSONObject params, HttpServletRequest request) {
/* 获取前台传递的参数 */
// 第三方app的类型
String app = params.getString("app");
// 是否发送给全部人
boolean sendAll = params.getBooleanValue("sendAll");
// 消息接收者传sys_user表的username字段多个用逗号分割
String receiver = params.getString("receiver");
// 消息内容
String content = params.getString("content");
String fromUser = JwtUtil.getUserNameByToken(request);
String title = "第三方APP消息测试";
MessageDTO message = new MessageDTO(fromUser, receiver, title, content);
message.setToAll(sendAll);
if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
JSONObject response = wechatEnterpriseService.sendMessageResponse(message, false);
return Result.OK(response);
}
return Result.error("企业微信已被禁用");
} else if (ThirdAppConfig.DINGTALK.equals(app)) {
if (thirdAppConfig.isDingtalkEnabled()) {
Response<String> response = dingtalkService.sendMessageResponse(message, false);
return Result.OK(response);
}
return Result.error("钉钉已被禁用");
}
return Result.error("不识别的第三方APP");
}
/**
* 撤回消息测试
*
* @return
*/
@PostMapping("/recallMessageTest")
public Result recallMessageTest(@RequestBody JSONObject params) {
/* 获取前台传递的参数 */
// 第三方app的类型
String app = params.getString("app");
// 消息id
String msgTaskId = params.getString("msg_task_id");
if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
return Result.error("企业微信不支持撤回消息");
}
return Result.error("企业微信已被禁用");
} else if (ThirdAppConfig.DINGTALK.equals(app)) {
if (thirdAppConfig.isDingtalkEnabled()) {
Response<JSONObject> response = dingtalkService.recallMessageResponse(msgTaskId);
if (response.isSuccess()) {
return Result.OK("撤回成功", response);
} else {
return Result.error("撤回失败:" + response.getErrcode() + "——" + response.getErrmsg(), response);
}
}
return Result.error("钉钉已被禁用");
}
return Result.error("不识别的第三方APP");
}
}

View File

@ -0,0 +1,419 @@
package org.jeecg.modules.system.controller;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xkcoding.justauth.AuthRequestFactory;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
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.PasswordUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.RestUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.thirdapp.ThirdAppConfig;
import org.jeecg.config.thirdapp.ThirdAppTypeItemVo;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.entity.SysThirdAccount;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.ThirdLoginModel;
import org.jeecg.modules.system.service.ISysThirdAccountService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
/**
* @Author scott
* @since 2018-12-17
*/
@Controller
@RequestMapping("/sys/thirdLogin")
@Slf4j
public class ThirdLoginController {
@Autowired
private ISysUserService sysUserService;
@Autowired
private ISysThirdAccountService sysThirdAccountService;
@Autowired
private BaseCommonService baseCommonService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private AuthRequestFactory factory;
@Autowired
ThirdAppConfig thirdAppConfig;
@Autowired
private ThirdAppWechatEnterpriseServiceImpl thirdAppWechatEnterpriseService;
@Autowired
private ThirdAppDingtalkServiceImpl thirdAppDingtalkService;
@RequestMapping("/render/{source}")
public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
log.info("第三方登录进入render" + source);
AuthRequest authRequest = factory.get(source);
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
log.info("第三方登录认证地址:" + authorizeUrl);
response.sendRedirect(authorizeUrl);
}
@RequestMapping("/{source}/callback")
public String loginThird(@PathVariable("source") String source, AuthCallback callback,ModelMap modelMap) {
log.info("第三方登录进入callback" + source + " params" + JSONObject.toJSONString(callback));
AuthRequest authRequest = factory.get(source);
AuthResponse response = authRequest.login(callback);
log.info(JSONObject.toJSONString(response));
Result<JSONObject> result = new Result<JSONObject>();
if(response.getCode()==2000) {
JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(response.getData()));
String username = data.getString("username");
String avatar = data.getString("avatar");
String uuid = data.getString("uuid");
//构造第三方登录信息存储对象
ThirdLoginModel tlm = new ThirdLoginModel(source, uuid, username, avatar);
//判断有没有这个人
//update-begin-author:wangshuai date:20201118 for:修改成查询第三方账户表
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<SysThirdAccount>();
query.eq(SysThirdAccount::getThirdUserUuid, uuid);
query.eq(SysThirdAccount::getThirdType, source);
List<SysThirdAccount> thridList = sysThirdAccountService.list(query);
SysThirdAccount user = null;
if(thridList==null || thridList.size()==0) {
//否则直接创建新账号
user = sysThirdAccountService.saveThirdUser(tlm);
}else {
//已存在 只设置用户名 不设置头像
user = thridList.get(0);
}
// 生成token
//update-begin-author:wangshuai date:20201118 for:从第三方登录查询是否存在用户id不存在绑定手机号
if(oConvertUtils.isNotEmpty(user.getSysUserId())) {
String sysUserId = user.getSysUserId();
SysUser sysUser = sysUserService.getById(sysUserId);
String token = saveToken(sysUser);
modelMap.addAttribute("token", token);
}else{
modelMap.addAttribute("token", "绑定手机号,"+""+uuid);
}
//update-end-author:wangshuai date:20201118 for:从第三方登录查询是否存在用户id不存在绑定手机号
//update-begin--Author:wangshuai Date:20200729 for接口在签名校验失败时返回失败的标识码 issues#1441--------------------
}else{
modelMap.addAttribute("token", "登录失败");
}
//update-end--Author:wangshuai Date:20200729 for接口在签名校验失败时返回失败的标识码 issues#1441--------------------
result.setSuccess(false);
result.setMessage("第三方登录异常,请联系管理员");
return "thirdLogin";
}
/**
* 创建新账号
* @param model
* @return
*/
@PostMapping("/user/create")
@ResponseBody
public Result<String> thirdUserCreate(@RequestBody ThirdLoginModel model) {
log.info("第三方登录创建新账号:" );
Result<String> res = new Result<>();
Object operateCode = redisUtil.get(CommonConstant.THIRD_LOGIN_CODE);
if(operateCode==null || !operateCode.toString().equals(model.getOperateCode())){
res.setSuccess(false);
res.setMessage("校验失败");
return res;
}
//创建新账号
//update-begin-author:wangshuai date:20201118 for:修改成从第三方登录查出来的user_id在查询用户表尽行token
SysThirdAccount user = sysThirdAccountService.saveThirdUser(model);
if(oConvertUtils.isNotEmpty(user.getSysUserId())){
String sysUserId = user.getSysUserId();
SysUser sysUser = sysUserService.getById(sysUserId);
// 生成token
String token = saveToken(sysUser);
//update-end-author:wangshuai date:20201118 for:修改成从第三方登录查出来的user_id在查询用户表尽行token
res.setResult(token);
res.setSuccess(true);
}
return res;
}
/**
* 绑定账号 需要设置密码 需要走一遍校验
* @param json
* @return
*/
@PostMapping("/user/checkPassword")
@ResponseBody
public Result<String> checkPassword(@RequestBody JSONObject json) {
Result<String> result = new Result<>();
Object operateCode = redisUtil.get(CommonConstant.THIRD_LOGIN_CODE);
if(operateCode==null || !operateCode.toString().equals(json.getString("operateCode"))){
result.setSuccess(false);
result.setMessage("校验失败");
return result;
}
String username = json.getString("uuid");
SysUser user = this.sysUserService.getUserByName(username);
if(user==null){
result.setMessage("用户未找到");
result.setSuccess(false);
return result;
}
String password = json.getString("password");
String salt = user.getSalt();
String passwordEncode = PasswordUtil.encrypt(user.getUsername(), password, salt);
if(!passwordEncode.equals(user.getPassword())){
result.setMessage("密码不正确");
result.setSuccess(false);
return result;
}
sysUserService.updateById(user);
result.setSuccess(true);
// 生成token
String token = saveToken(user);
result.setResult(token);
return result;
}
private String saveToken(SysUser user) {
// 生成token
String token = JwtUtil.sign(user.getUsername(), user.getPassword());
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
// 设置超时时间
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
return token;
}
/**
* 第三方登录回调接口
* @param token
* @param thirdType
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
@RequestMapping(value = "/getLoginUser/{token}/{thirdType}", method = RequestMethod.GET)
@ResponseBody
public Result<JSONObject> getThirdLoginUser(@PathVariable("token") String token,@PathVariable("thirdType") String thirdType) throws Exception {
Result<JSONObject> result = new Result<JSONObject>();
String username = JwtUtil.getUsername(token);
//1. 校验用户是否有效
SysUser sysUser = sysUserService.getUserByName(username);
result = sysUserService.checkUserIsEffective(sysUser);
if(!result.isSuccess()) {
return result;
}
//update-begin-author:wangshuai date:20201118 for:如果真实姓名和头像不存在就取第三方登录的
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
query.eq(SysThirdAccount::getSysUserId,sysUser.getId());
query.eq(SysThirdAccount::getThirdType,thirdType);
SysThirdAccount account = sysThirdAccountService.getOne(query);
if(oConvertUtils.isEmpty(sysUser.getRealname())){
sysUser.setRealname(account.getRealname());
}
if(oConvertUtils.isEmpty(sysUser.getAvatar())){
sysUser.setAvatar(account.getAvatar());
}
//update-end-author:wangshuai date:20201118 for:如果真实姓名和头像不存在就取第三方登录的
JSONObject obj = new JSONObject();
//用户登录信息
obj.put("userInfo", sysUser);
//token 信息
obj.put("token", token);
result.setResult(obj);
result.setSuccess(true);
result.setCode(200);
baseCommonService.addLog("用户名: " + username + ",登录成功[第三方用户]", CommonConstant.LOG_TYPE_1, null);
return result;
}
/**
* 第三方绑定手机号返回token
*
* @param jsonObject
* @return
*/
@ApiOperation("手机号登录接口")
@PostMapping("/bindingThirdPhone")
@ResponseBody
public Result<String> bindingThirdPhone(@RequestBody JSONObject jsonObject) {
Result<String> result = new Result<String>();
String phone = jsonObject.getString("mobile");
String thirdUserUuid = jsonObject.getString("thirdUserUuid");
// 校验验证码
String captcha = jsonObject.getString("captcha");
Object captchaCache = redisUtil.get(phone);
if (oConvertUtils.isEmpty(captcha) || !captcha.equals(captchaCache)) {
result.setMessage("验证码错误");
result.setSuccess(false);
return result;
}
//校验用户有效性
SysUser sysUser = sysUserService.getUserByPhone(phone);
if(sysUser != null){
// 存在用户,直接绑定
sysThirdAccountService.updateThirdUserId(sysUser,thirdUserUuid);
}else{
// 不存在手机号,创建用户
sysUser = sysThirdAccountService.createUser(phone,thirdUserUuid);
}
String token = saveToken(sysUser);
result.setSuccess(true);
result.setResult(token);
return result;
}
/**
* 企业微信/钉钉 OAuth2登录
*
* @param source
* @param state
* @return
*/
@ResponseBody
@GetMapping("/oauth2/{source}/login")
public String oauth2LoginCallback(@PathVariable("source") String source, @RequestParam("state") String state, HttpServletResponse response) throws Exception {
String url;
if (ThirdAppConfig.WECHAT_ENTERPRISE.equalsIgnoreCase(source)) {
ThirdAppTypeItemVo config = thirdAppConfig.getWechatEnterprise();
StringBuilder builder = new StringBuilder();
// 构造企业微信OAuth2登录授权地址
builder.append("https://open.weixin.qq.com/connect/oauth2/authorize");
// 企业的CorpID
builder.append("?appid=").append(config.getClientId());
// 授权后重定向的回调链接地址请使用urlencode对链接进行处理
String redirectUri = RestUtil.getBaseUrl() + "/sys/thirdLogin/oauth2/wechat_enterprise/callback";
builder.append("&redirect_uri=").append(URLEncoder.encode(redirectUri, "UTF-8"));
// 返回类型此时固定为code
builder.append("&response_type=code");
// 应用授权作用域。
// snsapi_base静默授权可获取成员的的基础信息UserId与DeviceId
builder.append("&scope=snsapi_base");
// 重定向后会带上state参数长度不可超过128个字节
builder.append("&state=").append(state);
// 终端使用此参数判断是否需要带上身份信息
builder.append("#wechat_redirect");
url = builder.toString();
} else if (ThirdAppConfig.DINGTALK.equalsIgnoreCase(source)) {
ThirdAppTypeItemVo config = thirdAppConfig.getDingtalk();
StringBuilder builder = new StringBuilder();
// 构造钉钉OAuth2登录授权地址
builder.append("https://login.dingtalk.com/oauth2/auth");
// 授权通过/拒绝后回调地址。
// 注意 需要与注册应用时登记的域名保持一致。
String redirectUri = RestUtil.getBaseUrl() + "/sys/thirdLogin/oauth2/dingtalk/callback";
builder.append("?redirect_uri=").append(URLEncoder.encode(redirectUri, "UTF-8"));
// 固定值为code。
// 授权通过后返回authCode。
builder.append("&response_type=code");
// 步骤一中创建的应用详情中获取。
// 企业内部应用client_id为应用的AppKey。
builder.append("&client_id=").append(config.getClientId());
// 授权范围,授权页面显示的授权信息以应用注册时配置的为准。
// openid授权后可获得用户userid
builder.append("&scope=openid");
// 跟随authCode原样返回。
builder.append("&state=").append(state);
//update-begin---author:wangshuai ---date:20220613 for[issues/I5BOUF]oauth2 钉钉无法登录------------
builder.append("&prompt=").append("consent");
//update-end---author:wangshuai ---date:20220613 for[issues/I5BOUF]oauth2 钉钉无法登录--------------
url = builder.toString();
} else {
return "不支持的source";
}
log.info("oauth2 login url:" + url);
response.sendRedirect(url);
return "login…";
}
/**
* 企业微信/钉钉 OAuth2登录回调
*
* @param code
* @param state
* @param response
* @return
*/
@ResponseBody
@GetMapping("/oauth2/{source}/callback")
public String oauth2LoginCallback(
@PathVariable("source") String source,
// 企业微信返回的code
@RequestParam(value = "code", required = false) String code,
// 钉钉返回的code
@RequestParam(value = "authCode", required = false) String authCode,
@RequestParam("state") String state,
HttpServletResponse response
) {
SysUser loginUser;
if (ThirdAppConfig.WECHAT_ENTERPRISE.equalsIgnoreCase(source)) {
log.info("【企业微信】OAuth2登录进入callbackcode=" + code + ", state=" + state);
loginUser = thirdAppWechatEnterpriseService.oauth2Login(code);
if (loginUser == null) {
return "登录失败";
}
} else if (ThirdAppConfig.DINGTALK.equalsIgnoreCase(source)) {
log.info("【钉钉】OAuth2登录进入callbackauthCode=" + authCode + ", state=" + state);
loginUser = thirdAppDingtalkService.oauth2Login(authCode);
if (loginUser == null) {
return "登录失败";
}
} else {
return "不支持的source";
}
try {
//update-begin-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
String redirect = "";
if (state.indexOf("?") > 0) {
String[] arr = state.split("\\?");
state = arr[0];
if(arr.length>1){
redirect = arr[1];
}
}
String token = saveToken(loginUser);
state += "/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8");
//update-begin---author:wangshuai ---date:20220613 for[issues/I5BOUF]oauth2 钉钉无法登录------------
state += "&thirdType=" + source;
//state += "&thirdType=" + "wechat_enterprise";
if (redirect != null && redirect.length() > 0) {
state += "&" + redirect;
}
//update-end-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
//update-end---author:wangshuai ---date:20220613 for[issues/I5BOUF]oauth2 钉钉无法登录------------
log.info("OAuth2登录重定向地址: " + state);
try {
response.sendRedirect(state);
return "ok";
} catch (IOException e) {
e.printStackTrace();
return "重定向失败";
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "解码失败";
}
}
}

View File

@ -0,0 +1,150 @@
package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
/**
* @Description: 系统通告表
* @Author: jeecg-boot
* @Date: 2019-01-02
* @Version: V1.0
*/
@Data
@TableName("sys_announcement")
public class SysAnnouncement implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.ASSIGN_ID)
private java.lang.String id;
/**
* 标题
*/
@Excel(name = "标题", width = 15)
private java.lang.String titile;
/**
* 内容
*/
@Excel(name = "内容", width = 30)
private java.lang.String msgContent;
/**
* 开始时间
*/
@Excel(name = "开始时间", width = 15, 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 startTime;
/**
* 结束时间
*/
@Excel(name = "结束时间", width = 15, 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 endTime;
/**
* 发布人
*/
@Excel(name = "发布人", width = 15)
private java.lang.String sender;
/**
* 优先级L低M中H高
*/
@Excel(name = "优先级", width = 15, dicCode = "priority")
@Dict(dicCode = "priority")
private java.lang.String priority;
/**
* 消息类型1:通知公告2:系统消息
*/
@Excel(name = "消息类型", width = 15, dicCode = "msg_category")
@Dict(dicCode = "msg_category")
private java.lang.String msgCategory;
/**
* 通告对象类型USER:指定用户ALL:全体用户)
*/
@Excel(name = "通告对象类型", width = 15, dicCode = "msg_type")
@Dict(dicCode = "msg_type")
private java.lang.String msgType;
/**
* 发布状态0未发布1已发布2已撤销
*/
@Excel(name = "发布状态", width = 15, dicCode = "send_status")
@Dict(dicCode = "send_status")
private java.lang.String sendStatus;
/**
* 发布时间
*/
@Excel(name = "发布时间", width = 15, 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 sendTime;
/**
* 撤销时间
*/
@Excel(name = "撤销时间", width = 15, 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 cancelTime;
/**
* 删除状态0正常1已删除
*/
private java.lang.String delFlag;
/**
* 创建人
*/
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.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;
/**
* 指定用户
**/
private java.lang.String userIds;
/**
* 业务类型(email:邮件 bpm:流程)
*/
private java.lang.String busType;
/**
* 业务id
*/
private java.lang.String busId;
/**
* 打开方式 组件component 路由url
*/
private java.lang.String openType;
/**
* 组件/路由 地址
*/
private java.lang.String openPage;
/**
* 摘要
*/
private java.lang.String msgAbstract;
/**
* 钉钉task_id用于撤回消息
*/
private java.lang.String dtTaskId;
}

View File

@ -0,0 +1,48 @@
package org.jeecg.modules.system.entity;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
/**
* @Description: 用户通告阅读标记表
* @Author: jeecg-boot
* @Date: 2019-02-21
* @Version: V1.0
*/
@Data
@TableName("sys_announcement_send")
public class SysAnnouncementSend implements Serializable {
private static final long serialVersionUID = 1L;
/**id*/
@TableId(type = IdType.ASSIGN_ID)
private java.lang.String id;
/**通告id*/
private java.lang.String anntId;
/**用户id*/
private java.lang.String userId;
/**阅读状态0未读1已读*/
private java.lang.String readFlag;
/**阅读时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private java.util.Date readTime;
/**创建人*/
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.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;
}

View File

@ -0,0 +1,66 @@
package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
/**
* @Description: 分类字典
* @Author: jeecg-boot
* @Date: 2019-05-29
* @Version: V1.0
*/
@Data
@TableName("sys_category")
public class SysCategory implements Serializable,Comparable<SysCategory>{
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
private java.lang.String id;
/**父级节点*/
private java.lang.String pid;
/**类型名称*/
@Excel(name = "类型名称", width = 15)
private java.lang.String name;
/**类型编码*/
@Excel(name = "类型编码", width = 15)
private java.lang.String code;
/**创建人*/
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.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;
/**所属部门*/
private java.lang.String sysOrgCode;
/**是否有子节点*/
@Excel(name = "是否有子节点(1:有)", width = 15)
private java.lang.String hasChild;
@Override
public int compareTo(SysCategory o) {
//比较条件我们定的是按照code的长度升序
// <0当前对象比传入对象小。
// =0当前对象等于传入对象。
// >0当前对象比传入对象大。
int s = this.code.length() - o.code.length();
return s;
}
@Override
public String toString() {
return "SysCategory [code=" + code + ", name=" + name + "]";
}
}

View File

@ -0,0 +1,88 @@
package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @Description: 编码校验规则
* @Author: jeecg-boot
* @Date: 2020-02-04
* @Version: V1.0
*/
@Data
@TableName("sys_check_rule")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "sys_check_rule对象", description = "编码校验规则")
public class SysCheckRule {
/**
* 主键id
*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键id")
private String id;
/**
* 规则名称
*/
@Excel(name = "规则名称", width = 15)
@ApiModelProperty(value = "规则名称")
private String ruleName;
/**
* 规则Code
*/
@Excel(name = "规则Code", width = 15)
@ApiModelProperty(value = "规则Code")
private String ruleCode;
/**
* 规则JSON
*/
@Excel(name = "规则JSON", width = 15)
@ApiModelProperty(value = "规则JSON")
private String ruleJson;
/**
* 规则描述
*/
@Excel(name = "规则描述", width = 15)
@ApiModelProperty(value = "规则描述")
private String ruleDescription;
/**
* 更新人
*/
@Excel(name = "更新人", width = 15)
@ApiModelProperty(value = "更新人")
private String updateBy;
/**
* 更新时间
*/
@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")
@ApiModelProperty(value = "更新时间")
private Date updateTime;
/**
* 创建人
*/
@Excel(name = "创建人", width = 15)
@ApiModelProperty(value = "创建人")
private String createBy;
/**
* 创建时间
*/
@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")
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@ -0,0 +1,75 @@
package org.jeecg.modules.system.entity;
import java.io.Serializable;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @Description: 系统数据日志
* @author: jeecg-boot
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class SysDataLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
/**
* id
*/
private String id;
/**
* 创建人登录名称
*/
private String createBy;
/**
* 创建日期
*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新人登录名称
*/
private String updateBy;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
/**
* 更新日期
*/
private Date updateTime;
/**
* 表名
*/
private String dataTable;
/**
* 数据ID
*/
private String dataId;
/**
* 数据内容
*/
private String dataContent;
/**
* 版本号
*/
private String dataVersion;
}

View File

@ -0,0 +1,120 @@
package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
/**
* @Description: 多数据源管理
* @Author: jeecg-boot
* @Date: 2019-12-25
* @Version: V1.0
*/
@Data
@TableName("sys_data_source")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "sys_data_source对象", description = "多数据源管理")
public class SysDataSource {
/**
* id
*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "id")
private java.lang.String id;
/**
* 数据源编码
*/
@Excel(name = "数据源编码", width = 15)
@ApiModelProperty(value = "数据源编码")
private java.lang.String code;
/**
* 数据源名称
*/
@Excel(name = "数据源名称", width = 15)
@ApiModelProperty(value = "数据源名称")
private java.lang.String name;
/**
* 描述
*/
@Excel(name = "备注", width = 15)
@ApiModelProperty(value = "备注")
private java.lang.String remark;
/**
* 数据库类型
*/
@Dict(dicCode = "database_type")
@Excel(name = "数据库类型", width = 15, dicCode = "database_type")
@ApiModelProperty(value = "数据库类型")
private java.lang.String dbType;
/**
* 驱动类
*/
@Excel(name = "驱动类", width = 15)
@ApiModelProperty(value = "驱动类")
private java.lang.String dbDriver;
/**
* 数据源地址
*/
@Excel(name = "数据源地址", width = 15)
@ApiModelProperty(value = "数据源地址")
private java.lang.String dbUrl;
/**
* 数据库名称
*/
@Excel(name = "数据库名称", width = 15)
@ApiModelProperty(value = "数据库名称")
private java.lang.String dbName;
/**
* 用户名
*/
@Excel(name = "用户名", width = 15)
@ApiModelProperty(value = "用户名")
private java.lang.String dbUsername;
/**
* 密码
*/
@Excel(name = "密码", width = 15)
@ApiModelProperty(value = "密码")
private java.lang.String dbPassword;
/**
* 创建人
*/
@ApiModelProperty(value = "创建人")
private java.lang.String createBy;
/**
* 创建日期
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private java.util.Date createTime;
/**
* 更新人
*/
@ApiModelProperty(value = "更新人")
private java.lang.String updateBy;
/**
* 更新日期
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private java.util.Date updateTime;
/**
* 所属部门
*/
@Excel(name = "所属部门", width = 15)
@ApiModelProperty(value = "所属部门")
private java.lang.String sysOrgCode;
}

View File

@ -0,0 +1,147 @@
package org.jeecg.modules.system.entity;
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;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
/**
* <p>
* 部门表
* <p>
*
* @Author Steve
* @Since 2019-01-22
*/
@Data
@TableName("sys_depart")
public class SysDepart implements Serializable {
private static final long serialVersionUID = 1L;
/**ID*/
@TableId(type = IdType.ASSIGN_ID)
private String id;
/**父机构ID*/
private String parentId;
/**机构/部门名称*/
@Excel(name="机构/部门名称",width=15)
private String departName;
/**英文名*/
@Excel(name="英文名",width=15)
private String departNameEn;
/**缩写*/
private String departNameAbbr;
/**排序*/
@Excel(name="排序",width=15)
private Integer departOrder;
/**描述*/
@Excel(name="描述",width=15)
private String description;
/**机构类别 1=公司2=组织机构3=岗位*/
@Excel(name="机构类别",width=15,dicCode="org_category")
private String orgCategory;
/**机构类型*/
private String orgType;
/**机构编码*/
@Excel(name="机构编码",width=15)
private String orgCode;
/**手机号*/
@Excel(name="手机号",width=15)
private String mobile;
/**传真*/
@Excel(name="传真",width=15)
private String fax;
/**地址*/
@Excel(name="地址",width=15)
private String address;
/**备注*/
@Excel(name="备注",width=15)
private String memo;
/**状态1启用0不启用*/
@Dict(dicCode = "depart_status")
private String status;
/**删除状态0正常1已删除*/
@Dict(dicCode = "del_flag")
private String delFlag;
/**对接企业微信的ID*/
private String qywxIdentifier;
/**创建人*/
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**更新人*/
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
//update-begin---author:wangshuai ---date:20200308 for[JTC-119]在部门管理菜单下设置部门负责人新增字段负责人ids和旧的负责人ids
/**部门负责人的ids*/
@TableField(exist = false)
private String directorUserIds;
/**旧的部门负责人的ids(用于比较删除和新增)*/
@TableField(exist = false)
private String oldDirectorUserIds;
//update-end---author:wangshuai ---date:20200308 for[JTC-119]新增字段负责人ids和旧的负责人ids
/**
* 重写equals方法
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
SysDepart depart = (SysDepart) o;
return Objects.equals(id, depart.id) &&
Objects.equals(parentId, depart.parentId) &&
Objects.equals(departName, depart.departName) &&
Objects.equals(departNameEn, depart.departNameEn) &&
Objects.equals(departNameAbbr, depart.departNameAbbr) &&
Objects.equals(departOrder, depart.departOrder) &&
Objects.equals(description, depart.description) &&
Objects.equals(orgCategory, depart.orgCategory) &&
Objects.equals(orgType, depart.orgType) &&
Objects.equals(orgCode, depart.orgCode) &&
Objects.equals(mobile, depart.mobile) &&
Objects.equals(fax, depart.fax) &&
Objects.equals(address, depart.address) &&
Objects.equals(memo, depart.memo) &&
Objects.equals(status, depart.status) &&
Objects.equals(delFlag, depart.delFlag) &&
Objects.equals(createBy, depart.createBy) &&
Objects.equals(createTime, depart.createTime) &&
Objects.equals(updateBy, depart.updateBy) &&
Objects.equals(updateTime, depart.updateTime);
}
/**
* 重写hashCode方法
*/
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), id, parentId, departName,
departNameEn, departNameAbbr, departOrder, description,orgCategory,
orgType, orgCode, mobile, fax, address, memo, status,
delFlag, createBy, createTime, updateBy, updateTime);
}
}

Some files were not shown because too many files have changed in this diff Show More