代码初始化提交。

This commit is contained in:
wangzhijiang
2024-02-20 09:33:24 +08:00
parent c66445edd4
commit 8abe03b22a
2184 changed files with 718173 additions and 0 deletions
@@ -0,0 +1,266 @@
<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>com.jero.boot</groupId>
<artifactId>laws-base</artifactId>
<version>2.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>laws-base-core</artifactId>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jeecg</id>
<name>jeecg Repository</name>
<url>https://maven.jeecg.org/nexus/content/repositories/jeecg</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<!--jero-tools-->
<dependency>
<groupId>com.jero.boot</groupId>
<artifactId>laws-base-tools</artifactId>
</dependency>
<!-- 代码生成核心包 -->
<dependency>
<groupId>com.jero.boot</groupId>
<artifactId>laws-base-generater-core</artifactId>
<version>${jero.version}</version>
</dependency>
<!--集成springmvc框架并实现自动配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>tomcat-embed-core</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
<exclusion>
<artifactId>tomcat-embed-el</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
<exclusion>
<artifactId>tomcat-embed-websocket</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--springboot2.3+ 需引入validation对应的包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- tomcat -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>${tomcat.version}</version>
<exclusions>
<exclusion>
<artifactId>tomcat-embed-core</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- commons -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons.version}</version>
</dependency>
<!-- freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- 动态数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-datasource-spring-boot-starter.version}</version>
</dependency>
<!-- 数据库驱动 -->
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
<scope>runtime</scope>
</dependency>
<!-- sqlserver-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>${sqljdbc4.version}</version>
<scope>runtime</scope>
</dependency>
<!-- oracle驱动 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${ojdbc6.version}</version>
<scope>runtime</scope>
</dependency>
<!-- postgresql驱动 -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Quartz定时任务 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!--JWT-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${java-jwt.version}</version>
</dependency>
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- shiro-redis -->
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>${shiro-redis.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j-spring-boot-starter.version}</version>
</dependency>
<!-- AutoPoi Excel工具类-->
<dependency>
<groupId>org.jeecgframework</groupId>
<artifactId>autopoi-web</artifactId>
<version>${autopoi-web.version}</version>
<exclusions>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- mini文件存储服务 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!-- 阿里云短信 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>${aliyun-java-sdk-dysmsapi.version}</version>
</dependency>
<!-- aliyun oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun.oss.version}</version>
</dependency>
<!-- 第三方登录 -->
<dependency>
<groupId>com.xkcoding.justauth</groupId>
<artifactId>justauth-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,145 @@
package com.jero.common.api;
import com.jero.common.system.vo.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface CommonAPI {
/**
* 1查询用户角色信息
* @param username
* @return
*/
Set<String> queryUserRoles(String username);
/**
* 2查询用户权限信息
* @param username
* @return
*/
Set<String> queryUserAuths(String username);
/**
* 3根据 id 查询数据库中存储的 DynamicDataSourceModel
*
* @param dbSourceId
* @return
*/
DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId);
/**
* 4根据 code 查询数据库中存储的 DynamicDataSourceModel
*
* @param dbSourceCode
* @return
*/
DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode);
/**
* 5根据用户账号查询用户信息
* @param username
* @return
*/
public LoginUser getUserByName(String username);
/**
* 6字典表的 翻译
* @param table
* @param text
* @param code
* @param key
* @return
*/
String translateDictFromTable(String table, String text, String code, String key);
/**
* 7普通字典的翻译
* @param code
* @param key
* @return
*/
String translateDict(String code, String key);
/**
* 8查询数据权限
* @return
*/
List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username);
/**
* 9查询用户信息
* @param username
* @return
*/
SysUserCacheInfo getCacheUser(String username);
/**
* 10获取数据字典
* @param code
* @return
*/
public List<DictModel> queryDictItemsByCode(String code);
/**
* 获取有效的数据字典项
* @param code
* @return
*/
public List<DictModel> queryEnableDictItemsByCode(String code);
/**
* 13获取表数据字典
* @param table
* @param text
* @param code
* @return
*/
List<DictModel> queryTableDictItemsByCode(String table, String text, String code);
/**
* 14 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割
* @param dictCodes 例如:user_status,sex
* @param keys 例如:1,2,0
* @return
*/
Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys);
/**
* 15 字典表的 翻译,可批量
* @param table
* @param text
* @param code
* @param keys 多个用逗号分割
* @return
*/
List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys);
/**
* 14获取全部字典
* @author lqt
* @date 2022/8/16 8:54
* @return JSONObject
*/
List<SysDictItemCore> getDictItemAll();;
/**
* 15通过查询指定table的 text code 获取字典值text
* @author lqt
* @date 2022/8/16 8:54
* @param table 表名
* @param text 文本
* @param code 编码
* @param key 键
* @return JSONObject
*/
String queryTableDictTextByKey(String table,String text,String code, String key);
String translateUserRealNameFromTable(String id);
List<DictModel> translateUserRealNameFromTableByKeys(String values);
}
@@ -0,0 +1,24 @@
package com.jero.common.api;
import com.jero.common.api.vo.OaWpsModel;
/**
* @Description: WPS通用接口
* @Author: wangshuai
* @Date:20200709
* @Version:V1.0
*/
public interface IWpsBaseAPI {
/*根据模板id获取模板信息*/
OaWpsModel getById(String id);
/*根据文件路径下载文件*/
void downloadOosFiles(String objectName, String basePath,String fileName);
/*WPS 设置数据存储,用于逻辑判断*/
void context(String type,String text);
/*删除WPS模板相关信息*/
void deleteById(String id);
}
@@ -0,0 +1,30 @@
package com.jero.common.api.dto;
import lombok.Data;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
/**
* 文件下载
* cloud api 用到的接口传输对象
*/
@Data
public class FileDownDTO implements Serializable {
private static final long serialVersionUID = 6749126258686446019L;
private String filePath;
private String uploadpath;
private String uploadType;
private transient HttpServletResponse response;
public FileDownDTO(){}
public FileDownDTO(String filePath, String uploadpath, String uploadType,HttpServletResponse response){
this.filePath = filePath;
this.uploadpath = uploadpath;
this.uploadType = uploadType;
this.response = response;
}
}
@@ -0,0 +1,55 @@
package com.jero.common.api.dto;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import java.io.Serializable;
/**
* 文件上传
* cloud api 用到的接口传输对象
*/
@Data
public class FileUploadDTO implements Serializable {
private static final long serialVersionUID = -4111953058578954386L;
private transient MultipartFile file;
private String bizPath;
private String uploadType;
private String customBucket;
public FileUploadDTO(){
}
/**
* 简单上传 构造器1
* @param file
* @param bizPath
* @param uploadType
*/
public FileUploadDTO(MultipartFile file,String bizPath,String uploadType){
this.file = file;
this.bizPath = bizPath;
this.uploadType = uploadType;
}
/**
* 申明桶 文件上传 构造器2
* @param file
* @param bizPath
* @param uploadType
* @param customBucket
*/
public FileUploadDTO(MultipartFile file,String bizPath,String uploadType,String customBucket){
this.file = file;
this.bizPath = bizPath;
this.uploadType = uploadType;
this.customBucket = customBucket;
}
}
@@ -0,0 +1,68 @@
package com.jero.common.api.dto;
import lombok.Data;
import com.jero.common.system.vo.LoginUser;
import java.io.Serializable;
import java.util.Date;
/**
* 日志对象
* cloud api 用到的接口传输对象
*/
@Data
public class LogDTO implements Serializable {
private static final long serialVersionUID = 8482720462943906924L;
/**内容*/
private String logContent;
/**日志类型(0:操作日志;1:登录日志;2:定时任务) */
private Integer logType;
/**操作类型(1:添加;2:修改;3:删除;) */
private Integer operateType;
/**登录用户 */
private transient LoginUser loginUser;
private String id;
private String createBy;
private Date createTime;
private Long costTime;
private String ip;
/**请求参数 */
private String requestParam;
/**请求类型*/
private String requestType;
/**请求路径*/
private String requestUrl;
/**请求方法 */
private String method;
/**操作人用户名称*/
private String username;
/**操作人用户账户*/
private String userid;
public LogDTO(){
}
public LogDTO(String logContent, Integer logType, Integer operatetype){
this.logContent = logContent;
this.logType = logType;
this.operateType = operatetype;
}
public LogDTO(String logContent, Integer logType, Integer operatetype, LoginUser loginUser){
this.logContent = logContent;
this.logType = logType;
this.operateType = operatetype;
this.loginUser = loginUser;
}
}
@@ -0,0 +1,41 @@
package com.jero.common.api.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* online 拦截器权限判断
* cloud api 用到的接口传输对象
*/
@Data
public class OnlineAuthDTO implements Serializable {
private static final long serialVersionUID = 1771827545416418203L;
/**
* 用户名
*/
private String username;
/**
* 可能的请求地址
*/
private List<String> possibleUrl;
/**
* online开发的菜单地址
*/
private String onlineFormUrl;
public OnlineAuthDTO(){
}
public OnlineAuthDTO(String username, List<String> possibleUrl, String onlineFormUrl){
this.username = username;
this.possibleUrl = possibleUrl;
this.onlineFormUrl = onlineFormUrl;
}
}
@@ -0,0 +1,43 @@
package com.jero.common.api.dto.message;
import lombok.Data;
import java.io.Serializable;
/**
* 带业务参数的消息
*/
@Data
public class BusMessageDTO extends MessageDTO implements Serializable {
private static final long serialVersionUID = 9104793287983367669L;
/**
* 业务类型
*/
private String busType;
/**
* 业务id
*/
private String busId;
public BusMessageDTO(){
}
/**
* 构造 带业务参数的消息
* @param fromUser
* @param toUser
* @param title
* @param msgContent
* @param msgCategory
* @param busType
* @param busId
*/
public BusMessageDTO(String fromUser, String toUser, String title, String msgContent, String msgCategory, String busType, String busId){
super(fromUser, toUser, title, msgContent, msgCategory);
this.busId = busId;
this.busType = busType;
}
}
@@ -0,0 +1,45 @@
package com.jero.common.api.dto.message;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
/**
* 带业务参数的模板消息
*/
@Data
public class BusTemplateMessageDTO extends TemplateMessageDTO implements Serializable {
private static final long serialVersionUID = -4277810906346929459L;
/**
* 业务类型
*/
private String busType;
/**
* 业务id
*/
private String busId;
public BusTemplateMessageDTO(){
}
/**
* 构造 带业务参数的模板消息
* @param fromUser
* @param toUser
* @param title
* @param templateParam
* @param templateCode
* @param busType
* @param busId
*/
public BusTemplateMessageDTO(String fromUser, String toUser, String title, Map<String, String> templateParam, String templateCode, String busType, String busId){
super(fromUser, toUser, title, templateParam, templateCode);
this.busId = busId;
this.busType = busType;
}
}
@@ -0,0 +1,69 @@
package com.jero.common.api.dto.message;
import lombok.Data;
import com.jero.common.constant.CommonConstant;
import java.io.Serializable;
/**
* 普通消息
*/
@Data
public class MessageDTO implements Serializable {
private static final long serialVersionUID = -5690444483968058442L;
/**
* 发送人(用户登录账户)
*/
protected String fromUser;
/**
* 发送给(用户登录账户)
*/
protected String toUser;
/**
* 消息主题
*/
protected String title;
/**
* 消息内容
*/
protected String content;
/**
* 消息类型 1:消息 2:系统消息
*/
protected String category;
public MessageDTO(){
}
/**
* 构造器1 系统消息
*/
public MessageDTO(String fromUser,String toUser,String title, String content){
this.fromUser = fromUser;
this.toUser = toUser;
this.title = title;
this.content = content;
//默认 都是2系统消息
this.category = CommonConstant.MSG_CATEGORY_2;
}
/**
* 构造器2 支持设置category 1:消息 2:系统消息
*/
public MessageDTO(String fromUser,String toUser,String title, String content, String category){
this.fromUser = fromUser;
this.toUser = toUser;
this.title = title;
this.content = content;
this.category = category;
}
}
@@ -0,0 +1,26 @@
package com.jero.common.api.dto.message;
import lombok.Data;
import java.util.Map;
/**
* @Author: liao
* @Date: 2023/10/17 11:19
* @Description: 发送消息
*/
@Data
public class SendMessageDTO {
/**
* 模板code
*/
private String templateCode;
/**
* 接收人id,多个以逗号分隔
*/
private String toUserId;
/**
* 对象例如 用户名:${username} map{"username":"张三"} 转换成 用户名:张三
*/
private Map<String, String> map;
}
@@ -0,0 +1,37 @@
package com.jero.common.api.dto.message;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
/**
* 消息模板dto
*/
@Data
public class TemplateDTO implements Serializable {
private static final long serialVersionUID = 5848247133907528650L;
/**
* 模板编码
*/
protected String templateCode;
/**
* 模板参数
*/
protected transient Map<String, String> templateParam;
/**
* 构造器 通过设置模板参数和模板编码 作为参数获取消息内容
*/
public TemplateDTO(String templateCode, Map<String, String> templateParam){
this.templateCode = templateCode;
this.templateParam = templateParam;
}
public TemplateDTO(){
}
}
@@ -0,0 +1,48 @@
package com.jero.common.api.dto.message;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
/**
* 模板消息
*/
@Data
public class TemplateMessageDTO extends TemplateDTO implements Serializable {
private static final long serialVersionUID = 411137565170647585L;
/**
* 发送人(用户登录账户)
*/
protected String fromUser;
/**
* 发送给(用户登录账户)
*/
protected String toUser;
/**
* 消息主题
*/
protected String title;
public TemplateMessageDTO(){
}
/**
* 构造器1 发模板消息用
*/
public TemplateMessageDTO(String fromUser, String toUser,String title, Map<String, String> templateParam, String templateCode){
super(templateCode, templateParam);
this.fromUser = fromUser;
this.toUser = toUser;
this.title = title;
}
}
@@ -0,0 +1,107 @@
package com.jero.common.api.vo;
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 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.io.Serializable;
import java.util.Date;
/**
* @Description: 文档
* @Author: jero-boot
* @Date: 2020-06-09
* @Version: V1.0
*/
@Data
@TableName("oa_wps_file")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "oa_wps_file对象", description = "文档")
public class OaWpsModel implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "id")
private String id;
/**
* name
*/
@Excel(name = "name", width = 15)
@ApiModelProperty(value = "name")
private String name;
/**
* version
*/
@Excel(name = "version", width = 15)
@ApiModelProperty(value = "version")
private Integer version;
/**
* size
*/
@Excel(name = "size", width = 15)
@ApiModelProperty(value = "size")
private Integer size;
/**
* downloadUrl
*/
@Excel(name = "downloadUrl", width = 15)
@ApiModelProperty(value = "downloadUrl")
private String downloadUrl;
/**
* deleted
*/
@Excel(name = "deleted", width = 15)
@ApiModelProperty(value = "deleted")
private String deleted;
/**
* canDelete
*/
@Excel(name = "canDelete", width = 15)
@ApiModelProperty(value = "canDelete")
private String canDelete;
/**
* 创建人
*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**
* 创建时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* 更新人
*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**
* 更新时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(value = "更新时间")
private Date updateTime;
/**
* 组织机构编码
*/
@ApiModelProperty(value = "组织机构编码")
private String sysOrgCode;
@TableField(exist = false)
private String userId;
}
@@ -0,0 +1,147 @@
package com.jero.common.api.vo;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.jero.common.util.MessageUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.jero.common.constant.CommonConstant;
import lombok.Data;
/**
* 接口返回数据格式
* @author scott
* @date 2019年1月19日
*/
@Data
@ApiModel(value="接口返回对象", description="接口返回对象")
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 成功标志
*/
@ApiModelProperty(value = "成功标志")
private boolean success = true;
/**
* 返回处理消息
*/
@ApiModelProperty(value = "返回处理消息")
private String message = "操作成功!";
/**
* 返回代码
*/
@ApiModelProperty(value = "返回代码")
private Integer code = 200;
/**
* 返回数据对象 data
*/
@ApiModelProperty(value = "返回数据对象")
private transient T result;
/**
* 时间戳
*/
@ApiModelProperty(value = "时间戳")
private long timestamp = System.currentTimeMillis();
public Result() {
// do other
}
public Result<T> success(String message) {
this.message = message;
this.code = CommonConstant.SC_OK_200;
this.success = true;
return this;
}
public static<T> Result<T> OK() {
Result<T> r = new Result<>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(MessageUtils.getMessage(ResultCommon.OK));
return r;
}
public static<T> Result<T> OK(String msg) {
Result<T> r = new Result<>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
msg = MessageUtils.getMessage(msg);
r.setMessage(msg);
return r;
}
public static<T> Result<T> OK(String msg, Object... args) {
Result<T> r = new Result<>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
msg = MessageUtils.getMessage(msg,args);
r.setMessage(msg);
return r;
}
public static<T> Result<T> OK(T data) {
Result<T> r = new Result<>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
return r;
}
public static<T> Result<T> OK(String msg, T data) {
Result<T> r = new Result<>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(msg);
r.setResult(data);
return r;
}
public static<T> Result<T> error(String msg, T data) {
Result<T> r = new Result<>();
r.setSuccess(false);
r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500);
r.setMessage(msg);
r.setResult(data);
return r;
}
public static<T> Result<T> error(String msg) {
msg = MessageUtils.getMessage(msg);
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
}
public static<T> Result<T> error(String msg, Object... args) {
msg = MessageUtils.getMessage(msg,args);
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
}
public static<T> Result<T> error(int code, String msg) {
Result<T> r = new Result<>();
r.setCode(code);
r.setMessage(msg);
r.setSuccess(false);
return r;
}
public Result<T> error500(String message) {
this.message = message;
this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
this.success = false;
return this;
}
/**
* 无权限访问返回结果
*/
public static Result<Object> noauth(String msg) {
return error(CommonConstant.SC_JERO_NO_AUTHZ, msg);
}
@JsonIgnore
private String onlTable;
}
@@ -0,0 +1,158 @@
package com.jero.common.api.vo;
/**
* @Author: liao
* @Date: 2023/8/24 14:01
* @Description: 返回常量
*/
public class ResultCommon {
private ResultCommon() {}
/**操作成功*/
public static final String OK = "message.ok";
/**操作失败*/
public static final String ERROR = "message.error";
/**编辑成功*/
public static final String EDIT_OK = "edit.ok";
/**编辑失败*/
public static final String EDIT_ERROR = "edit.error";
/**请选择数据*/
public static final String PLEASE_SELECT_DATA = "please.select.data";
/**删除成功*/
public static final String SUCCESSFULLY_DELETED = "successfully.deleted";
/**批量删除成功*/
public static final String SUCCESSFULLY_DELETED_IN_BULK = "successfully.deleted.in.bulk";
/**未找到对应数据*/
public static final String NO_CORRESPONDING_DATA_FOUND = "no.corresponding.data.found";
/**参数不识别*/
public static final String PARAMETER_NOT_RECOGNIZED = "parameter.not.recognized";
public static final String EMPTY_SOURCE = "message.empty.source"; // 来源不能为空
public static final String EMPTY_STANDARD_NUMBER = "message.empty.standard.number"; // 标准编号不能为空
public static final String EMPTY_STANDARD_NAME = "message.empty.standard.name"; // 标准名称不能为空
public static final String EMPTY_COMMON = "message.empty.common"; // {0}不能为空
public static final String EXIST_STANDARD_NUMBER = "message.exists.standard.number"; // 标准编号已经存在
public static final String NOT_EXIST_PARAM = "message.no.exists.param"; // 参数{0}不存在
public static final String NO_PERMISSION = "message.no.permission"; // 没有数据操作权限
public static final String SELECT_DATA = "message.select.data"; // 请选择数据
public static final String EXIST_SUB_FOLDERS = "message.exist.sub.folders"; // 文件夹下有子文件夹 ,该文件夹不允许删除
public static final String EXIST_SUB_FILES = "message.exist.sub.files"; // 文件夹下有文件不能删除
public static final String RMR_SET_QUALITY_OVER_TEN = "es.rmr.setQuality.overTen"; // 请最多选择10条
public static final String SUCCESSFULLY_CLEARED = "successfully.cleared"; // 清除成功
public static final String CANNOT_DUPLICATE_FAVORITES = "cannot.duplicate.favorites"; // 不能重复收藏
public static final String THE_TOPLEVEL_GROUP_CANNOT_BE_DELETED = "the.toplevel.group.cannot.be.deleted"; // 最高级组别不能删除
public static final String PLEASE_SELECT_PERSONNEL_AND_WORKGROUP = "please.select.personnel.and.workgroup"; // 请选择人员和工作组
public static final String NUMBER_WORK_NO_ALREADY_EXISTS = "number.work.no.already.exists"; // 工号已存在
public static final String NO_FILES_IMPORTED = "no.files.imported"; // 没有导入文件
public static final String PLEASE_SELECT_A_WORKGROUP_TO_IMPORT = "Please.select.a.workgroup.to.import"; // 请选择工作组进行导入
public static final String PLEASE_USE_A_FILE_WITH_THE_SUFFIX_XLS = "please.use.a.file.with.the.suffix.xls"; // 文件名格式不正确, 请使用后缀名为.xls的文件
public static final String IMPORT_DATA_CANNOT_BE_EMPTY = "import.data.cannot.be.empty"; // 导入数据不能为空
public static final String HEADER_INCONSISTENT_WITH_TEMPLATE = "header.inconsistent.with.template"; // 表头与模板不一致
public static final String PLEASE_SELECT_A_WORKGROUP_TO_EXPORT = "please.select.a.workgroup.for.export"; // 请选择工作组进行导出
public static final String THE_JOB_NUMBER_CANNOT_BE_EMPTY_EXPORT = "the.job.number.cannot.be.empty.export"; // 第{0}行,工号不能为空
public static final String THE_REAL_NAME_CANNOT_BE_EMPTY_EXPORT = "the.real.name.cannot.be.empty.export"; // 第{0}行,姓名不能为空
public static final String THE_REAL_NAME_AND_JOB_NUMBER_MISMATCH_EXPORT = "the.real.name.and.job.number.mismatch.export"; // 第{0}行,姓名与工号不匹配
public static final String JOB_NUMBER_DOES_NOT_EXIST_EXPORT = "job.number.does.not.exist.export"; // 第{0}行,工号不存在
public static final String DUPLICATE_JOB_NUMBER_EXPORT = "duplicate.job.number.export"; // 第{0}行,工号重复
public static final String CANNOT_CLOSE = "cannot.close"; // 不是待整改已过期的数据不能关闭
public static final String NO_CORRESPONDING_RECORD_FOUND = "no.corresponding.record.found"; // 没有找到对应的记录
public static final String PARAMETERS_CANNOT_BE_NULL = "parameters.cannot.be.null"; // 参数不能为空
public static final String ROOT_NODE_CANNOT_BE_EDITED = "root.node.cannot.be.edited"; // 根节点不能编辑
public static final String HORIZONTAL_TRANSGRESSION = "horizontal.transgression"; // 水平越权
public static final String NO_PERMISSIONS_PLEASE_SELECT = "horizontal.transgression.select"; // 暂无权限,请重新选择
public static final String SELECT_LEVEL_TWO_TREE_NODE = "select.level.two.tree.node"; // 请先选择二级及以下体系
public static final String EXPORT_ERROR = "export.error"; // 导出ZIP压缩包失败
public static final String IMPORT_ERROR = "import.error"; // 导入ZIP压缩包失败
public static final String PLEASE_UPLOAD_ZIP = "please.upload.zip.archive"; // 请上传Zip压缩包
public static final String TASK_HANDLER_ERROR = "task.handler.error"; // 只有处理人可以操作
public static final String NO_AUTH = "no.auth"; // 只有处理人可以操作
public static final String IMPORT_TEMPLATE_ERROR = "import.template.error"; // 导入模板错误
public static final String ZIP_CHARSET_ERROR = "zip.charset.error"; // zip压缩包编码错误
/**字段名称太长*/
public static final String TAG_ADD_ERROR_1 = "tag.add.error.1";
/**每张表最多有50个字段*/
public static final String TAG_ADD_ERROR_2 = "tag.add.error.2";
/**同一所属模块下,展示区域名称不能重复!*/
public static final String TAG_ERROR_1 = "tag.error.1";
/**该展示区域有关联数据,无法删除!*/
public static final String TAG_DELETE_ERROR_2 = "tag.delete.error.2";
/**包含固定字段,不可删除*/
public static final String TAG_DELETE_ERROR_3 = "tag.delete.error.3";
/**包含固定字段,不可编辑*/
public static final String TAG_EDIT_ERROR_1 = "tag.edit.error.1";
/**属性已存在,请检查*/
public static final String TAG_EDIT_ERROR_2 = "tag.edit.error.2";
/**标签已被引用,无法删除*/
public static final String DICT_DELETE_ERROR = "dict.delete.error";
public static final String FOLDER_ONLY_ONE = "folder.only.one";
public static final String YOU_HAVE_NOT_DATA_AUTH = "you.have.not.data.auth";
/**请输入检索内容*/
public static final String PLEASE_SEARCH_TO_IMPORT = "please.search.to.import";
/**
* 任务不存在
*/
public static final String TASK_NOT_EXISTS = "task.not.exists";
/**
* 只能催办待办任务
*/
public static final String TASK_URGING_ERROR = "task.urging.error";
/**
* 暂无该流程催办权限
*/
public static final String TASK_URGING_ERROR_2 = "task.urging.error.2";
/**
* 草稿不存在
*/
public static final String DRAFT_NOT_EXISTS = "draft.not.exists";
/**
* 企标编号已存在,需等待重新生成顺序号
*/
public static final String EN_STANDARD_NUMBER_CONFLICT = "en.standard.number.conflict";
/**
* 无效的企标计划
*/
public static final String INVALID_ESP = "invalid.esp";
/**
* 不可以编辑废止或封存状态的企标
*/
public static final String CAN_NOT_EDIT_ABOLISH_OR_ARCHIVE_ES = "can.not.edit.abolish.or.archive.es";
// ---------项目合规评估流程---------
/**
* 模块负责人不能为空
*/
public static final String ProjectAssess = "en.standard.number.conflict";
// ---------项目合规评估流程---------
}
@@ -0,0 +1,25 @@
package com.jero.common.api.vo;
/**
* @author LQT
* @date 2023/3/9 9:11
*/
public class ResultConstant {
private ResultConstant(){
}
public static final String OP_OK = "操作成功!";
public static final String DEL_OK = "删除成功!";
public static final String DEL_ERR = "删除失败!";
public static final String BATCH_DEL_OK = "批量删除成功!";
public static final String EN_WAS_NOT_FOUND = "未找到对应实体!";
}
@@ -0,0 +1,19 @@
package com.jero.common.api.vo;
import com.jero.common.api.dto.message.SendMessageDTO;
/**
* @Author: liao
* @Date: 2023/10/27 15:15
* @Description: 发送消息
*/
public interface SendMessageAPI {
/**
* @Author: liao
* @Date: 2023/10/27 15:13
* @Description: 根据模板发送消息
**/
void sendMessage(SendMessageDTO sendMessageDTO);
}
@@ -0,0 +1,219 @@
package com.jero.common.aspect;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.jero.common.api.dto.LogDTO;
import com.jero.common.api.vo.Result;
import com.jero.common.aspect.annotation.AutoLog;
import com.jero.common.constant.CommonConstant;
import com.jero.common.constant.enums.ModuleType;
import com.jero.common.system.vo.LoginUser;
import com.jero.common.util.IPUtils;
import com.jero.common.util.SpringContextUtils;
import com.jero.common.util.oConvertUtils;
import com.jero.modules.base.service.BaseCommonService;
import org.apache.poi.ss.formula.functions.T;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* 系统日志,切面处理类
*
* @Author scott
* @Date 2018年1月14日
*/
@Aspect
@Component
public class AutoLogAspect {
@Resource
private BaseCommonService baseCommonService;
@Pointcut("@annotation(com.jero.common.aspect.annotation.AutoLog)")
public void logPointCut() {
// do other
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
saveSysLog(point, time, result);
return result;
}
private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object obj) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogDTO dto = new LogDTO();
AutoLog syslog = method.getAnnotation(AutoLog.class);
if(syslog != null){
//update-begin-author:taoyan date:
String content = syslog.value();
if(syslog.module()== ModuleType.ONLINE){
content = getOnlineLogContent(obj, content);
}
//注解上的描述,操作日志内容
dto.setLogType(syslog.logType());
dto.setLogContent(content);
}
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
dto.setMethod(className + "." + methodName + "()");
//设置操作类型
if (dto.getLogType() == CommonConstant.LOG_TYPE_2) {
assert syslog != null;
dto.setOperateType(getOperateType(methodName, syslog.operateType()));
}
//获取request
HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
//请求的参数
dto.setRequestParam(getReqestParams(request,joinPoint));
//设置IP地址
dto.setIp(IPUtils.getIpAddr(request));
//获取登录用户信息
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if(sysUser!=null){
if ("admin".equals(sysUser.getUsername())){
return;
}
dto.setUserid(sysUser.getUsername());
dto.setUsername(sysUser.getRealname());
}
//耗时
dto.setCostTime(time);
dto.setCreateTime(new Date());
//保存系统日志
baseCommonService.addLog(dto);
}
/**
* 获取操作类型
*/
private int getOperateType(String methodName,int operateType) {
if (operateType > 0) {
return operateType;
}
if (methodName.startsWith("list") || methodName.startsWith("query")) {
return CommonConstant.OPERATE_TYPE_1;
}
if (methodName.startsWith("add") || methodName.startsWith("create")) {
return CommonConstant.OPERATE_TYPE_2;
}
if (methodName.startsWith("edit") || methodName.startsWith("update")) {
return CommonConstant.OPERATE_TYPE_3;
}
if (methodName.startsWith("delete") || methodName.startsWith("remove")) {
return CommonConstant.OPERATE_TYPE_4;
}
if (methodName.startsWith("import")) {
return CommonConstant.OPERATE_TYPE_5;
}
if (methodName.startsWith("export")) {
return CommonConstant.OPERATE_TYPE_6;
}
return CommonConstant.OPERATE_TYPE_1;
}
/**
* @Description: 获取请求参数
* @author: scott
* @date: 2020/4/16 0:10
* @param request: request
* @param joinPoint: joinPoint
* @Return: java.lang.String
*/
private String getReqestParams(HttpServletRequest request, JoinPoint joinPoint) {
String httpMethod = request.getMethod();
StringBuilder params = new StringBuilder();
List<String> list = Arrays.asList("POST","PUT","PATCH");
if (list.contains(httpMethod)) {
Object[] paramsArray = joinPoint.getArgs();
// java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
// https://my.oschina.net/mengzhang6/blog/2395893
Object[] arguments = new Object[paramsArray.length];
for (int i = 0; i < paramsArray.length; i++) {
if (paramsArray[i] instanceof BindingResult || paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile) {
//ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
//ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
continue;
}
arguments[i] = paramsArray[i];
}
//update-begin-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
PropertyFilter profilter = (o, name, value) -> value == null || value.toString().length() <= 500;
params = new StringBuilder(JSON.toJSONString(arguments, profilter));
//update-end-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
} else {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 请求的方法参数值
Object[] args = joinPoint.getArgs();
// 请求的方法参数名称
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
String[] paramNames = u.getParameterNames(method);
if (args != null && paramNames != null) {
for (int i = 0; i < args.length; i++) {
params.append(" ").append(paramNames[i]).append(": ").append(args[i]);
}
}
}
return params.toString();
}
/**
* online日志内容拼接
* @param obj
* @param content
* @return
*/
private String getOnlineLogContent(Object obj, String content){
if (obj instanceof Result){
Result<T> res = (Result)obj;
String msg = res.getMessage();
String tableName = res.getOnlTable();
if(oConvertUtils.isNotEmpty(tableName)){
content+=",表名:"+tableName;
}
if(res.isSuccess()){
content+= ","+(oConvertUtils.isEmpty(msg)?"操作成功":msg);
}else{
content+= ","+(oConvertUtils.isEmpty(msg)?"操作失败":msg);
}
}
return content;
}
}
@@ -0,0 +1,507 @@
package com.jero.common.aspect;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jero.common.api.CommonAPI;
import com.jero.common.api.vo.Result;
import com.jero.common.aspect.annotation.Dict;
import com.jero.common.constant.CacheConstant;
import com.jero.common.constant.CommonConstant;
import com.jero.common.system.vo.DictModel;
import com.jero.common.util.oConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
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.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @Description: 字典aop类
* @Author: dangzhenghui
* @Date: 2019-3-17 21:50
* @Version: 1.0
*/
@Aspect
@Component
@Slf4j
public class DictAspect {
@Autowired
private CommonAPI commonAPI;
@Autowired
public RedisTemplate<String,Object> redisTemplate;
private static final String SYS_CACHE_DICT_S_S = "sys:cache:dict::%s:%s";
// 定义切点Pointcut
@Pointcut("execution(public * com.jero.modules..*.*Controller.*(..))")
public void excudeService() {
// do other
}
@Pointcut("@annotation(com.jero.common.aspect.annotation.DictPoint)")
public void dictPointCut() {
}
@Around("excudeService()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
long time1=System.currentTimeMillis();
Object result = pjp.proceed();
long time2=System.currentTimeMillis();
log.debug("获取JSON数据 耗时:"+(time2-time1)+"ms");
long start=System.currentTimeMillis();
this.parseDictText(result);
long end=System.currentTimeMillis();
log.debug("注入字典到JSON数据 耗时"+(end-start)+"ms");
return result;
}
@Around("dictPointCut()")
public Object arround(ProceedingJoinPoint point) throws Throwable {
long time1 = System.currentTimeMillis();
Object result = point.proceed();
long time2 = System.currentTimeMillis();
log.debug("获取JSON数据 耗时:" + (time2 - time1) + "ms");
long start = System.currentTimeMillis();
this.parseMethodDictText(result);
long end = System.currentTimeMillis();
log.debug("解析注入JSON数据 耗时" + (end - start) + "ms");
return result;
}
/**
* 本方法针对返回对象为Result 的IPage的分页列表数据进行动态字典注入
* 字典注入实现 通过对实体类添加注解@dict 来标识需要的字典内容,字典分为单字典code即可 table字典 code table text配合使用与原来jero的用法相同
* 示例为SysUser 字段为sex 添加了注解@Dict(dicCode = "sex") 会在字典服务立马查出来对应的text 然后在请求list的时候将这个字典text,已字段名称加_dictText形式返回到前端
* 例输入当前返回值的就会多出一个sex_dictText字段
* {
* sex:1,
* sex_dictText:"男"
* }
* 前端直接取值sext_dictText在table里面无需再进行前端的字典转换了
* customRender:function (text) {
* if(text==1){
* return "男";
* }else if(text==2){
* return "女";
* }else{
* return text;
* }
* }
* 目前vue是这么进行字典渲染到table上的多了就很麻烦了 这个直接在服务端渲染完成前端可以直接用
* @param result
*/
private void parseDictText(Object result) {
if (result instanceof Result && ((Result) result).getResult() instanceof IPage) {
List<JSONObject> items = new ArrayList<>();
//step.1 筛选出加了 Dict 注解的字段列表
List<Field> dictFieldList = new ArrayList<>();
// 字典数据列表, key = 字典code,value=数据列表
Map<String, List<String>> dataListMap = new HashMap<>();
addItems((Result) result, items, dictFieldList, dataListMap);
//step.2 调用翻译方法,一次性翻译
Map<String, List<DictModel>> translText = this.translateAllDict(dataListMap);
//step.3 将翻译结果填充到返回结果里
putItems(items, dictFieldList, translText);
((IPage) ((Result) result).getResult()).setRecords(items);
}
}
private void putItems(List<JSONObject> items, List<Field> dictFieldList, Map<String, List<DictModel>> translText) {
for (JSONObject obj : items) {
for (Field field : dictFieldList) {
String code = field.getAnnotation(Dict.class).dicCode();
String text = field.getAnnotation(Dict.class).dicText();
String table = field.getAnnotation(Dict.class).dictTable();
String fieldDictCode = code;
if (!StringUtils.isEmpty(table)) {
fieldDictCode = String.format("%s,%s,%s", table, text, code);
}
String value = obj.getString(field.getName());
if (oConvertUtils.isNotEmpty(value)) {
List<DictModel> dictModels = translText.get(fieldDictCode);
if(dictModels==null || dictModels.isEmpty()){
continue;
}
String textValue = this.translDictText(dictModels, value);
log.debug(" 字典Val : " + textValue);
log.debug(" __翻译字典字段__ " + field.getName() + CommonConstant.DICT_TEXT_SUFFIX + " " + textValue);
// TODO-sun 测试输出,待删
log.debug(" ---- dictCode: " + fieldDictCode);
log.debug(" ---- value: " + value);
log.debug(" ----- text: " + textValue);
log.debug(" ---- dictModels: " + JSON.toJSONString(dictModels));
obj.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
}
}
}
}
private void addItems(Result<IPage<T>> result, List<JSONObject> items, List<Field> dictFieldList, Map<String, List<String>> dataListMap) {
for (Object obj : result.getResult().getRecords()) {
ObjectMapper mapper = new ObjectMapper();
String json="{}";
try {
//解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
json = mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
log.error("json解析失败"+e.getMessage(),e);
}
JSONObject item = JSON.parseObject(json,Feature.OrderedField);
//update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
// 遍历所有字段,把字典Code取出来,放到 map 里
putItem(dictFieldList, dataListMap, obj, item);
items.add(item);
}
}
private void putItem(List<Field> dictFieldList, Map<String, List<String>> dataListMap, Object obj, JSONObject item) {
for (Field field : oConvertUtils.getAllFields(obj)) {
String value = item.getString(field.getName());
if (oConvertUtils.isEmpty(value)) {
continue;
}
//update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
if (field.getAnnotation(Dict.class) != null) {
if (!dictFieldList.contains(field)) {
dictFieldList.add(field);
}
String code = field.getAnnotation(Dict.class).dicCode();
String text = field.getAnnotation(Dict.class).dicText();
String table = field.getAnnotation(Dict.class).dictTable();
List<String> dataList;
String dictCode = code;
if (!StringUtils.isEmpty(table)) {
dictCode = String.format("%s,%s,%s", table, text, code);
}
dataList = dataListMap.computeIfAbsent(dictCode, k -> new ArrayList<>());
this.listAddAllDeduplicate(dataList, Arrays.asList(value.split(",")));
}
//date类型默认转换string格式化日期
if (Date.class.isAssignableFrom(field.getType()) && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null){
SimpleDateFormat aDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
}
}
}
/**
* list 去重添加
*/
private void listAddAllDeduplicate(List<String> dataList, List<String> addList) {
// 筛选出dataList中没有的数据
List<String> filterList = addList.stream().filter(i -> !dataList.contains(i)).collect(Collectors.toList());
dataList.addAll(filterList);
}
/**
* 一次性把所有的字典都翻译了
* 1. 所有的普通数据字典的所有数据只执行一次SQL
* 2. 表字典相同的所有数据只执行一次SQL
* @param dataListMap
* @return
*/
private Map<String, List<DictModel>> translateAllDict(Map<String, List<String>> dataListMap) {
// 翻译后的字典文本,key=dictCode
Map<String, List<DictModel>> translText = new HashMap<>();
// 需要翻译的数据(有些可以从redis缓存中获取,就不走数据库查询)
List<String> needTranslData = new ArrayList<>();
//step.1 先通过redis中获取缓存字典数据
for (Map.Entry<String, List<String>> entry : dataListMap.entrySet()) {
String dictCode = entry.getKey();
List<String> dataList = entry.getValue();
if (dataList.isEmpty()) {
continue;
}
// 表字典需要翻译的数据
List<String> needTranslDataTable = new ArrayList<>();
addNeedTranslData(translText, needTranslData, dictCode, dataList, needTranslDataTable);
//step.2 调用数据库翻译表字典
if (!needTranslDataTable.isEmpty()) {
String[] arr = dictCode.split(",");
String table = arr[0];
String text = arr[1];
String code = arr[2];
String values = String.join(",", needTranslDataTable);
log.info("translateDictFromTableByKeys.dictCode:" + dictCode);
log.info("translateDictFromTableByKeys.values:" + values);
List<DictModel> texts;
if ("sys_user".equals(table)&&"realname".equals(text)&&"id".equals(code)){
texts = commonAPI.translateUserRealNameFromTableByKeys(values);
}else {
texts = commonAPI.translateDictFromTableByKeys(table, text, code, values);
}
log.info("translateDictFromTableByKeys.result:" + texts);
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
list.addAll(texts);
setRedis(dictCode, texts);
}
}
//step.3 调用数据库进行翻译普通字典
if (!needTranslData.isEmpty()) {
List<String> dictCodeList = Arrays.asList(dataListMap.keySet().toArray(new String[]{}));
// 将不包含逗号的字典code筛选出来,因为带逗号的是表字典,而不是普通的数据字典
List<String> filterDictCodes = dictCodeList.stream().filter(key -> !key.contains(",")).collect(Collectors.toList());
String dictCodes = String.join(",", filterDictCodes);
String values = String.join(",", needTranslData);
log.info("translateManyDict.dictCodes:" + dictCodes);
log.info("translateManyDict.values:" + values);
Map<String, List<DictModel>> manyDict = commonAPI.translateManyDict(dictCodes, values);
log.info("translateManyDict.result:" + manyDict);
for (Map.Entry<String, List<DictModel>> entry : manyDict.entrySet()) {
String dictCode = entry.getKey();
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
List<DictModel> newList = entry.getValue();
list.addAll(newList);
// 做 redis 缓存
for (DictModel dict : newList) {
String redisKey = String.format(SYS_CACHE_DICT_S_S, dictCode, dict.getValue());
try {
redisTemplate.opsForValue().set(redisKey, dict.getText());
} catch (Exception e) {
log.warn(e.getMessage(), e);
}
}
}
}
return translText;
}
private void setRedis(String dictCode, List<DictModel> texts) {
// 做 redis 缓存
for (DictModel dict : texts) {
String redisKey = String.format(CacheConstant.SYS_DICT_TABLE_CACHE_SIMPLE_KEY, dictCode, dict.getValue());
try {
// 保留10分钟
redisTemplate.opsForValue().set(redisKey, dict.getText(), 600, TimeUnit.SECONDS);
} catch (Exception e) {
log.warn(e.getMessage(), e);
}
}
}
private void addNeedTranslData(Map<String, List<DictModel>> translText, List<String> needTranslData, String dictCode, List<String> dataList, List<String> needTranslDataTable) {
for (String s : dataList) {
String data = s.trim();
if (data.length() == 0) {
continue; //跳过循环
}
if (dictCode.contains(",")) {
String keyString = String.format(CacheConstant.SYS_DICT_TABLE_CACHE_SIMPLE_KEY, dictCode, data);
if (Boolean.TRUE.equals(redisTemplate.hasKey(keyString))) {
addList(translText, dictCode, data, keyString);
} else if (!needTranslDataTable.contains(data)) {
// 去重添加
needTranslDataTable.add(data);
}
} else {
String keyString = String.format(SYS_CACHE_DICT_S_S, dictCode, data);
if (Boolean.TRUE.equals(redisTemplate.hasKey(keyString))) {
addList(translText, dictCode, data, keyString);
} else if (!needTranslData.contains(data)) {
// 去重添加
needTranslData.add(data);
}
}
}
}
private void addList(Map<String, List<DictModel>> translText, String dictCode, String data, String keyString) {
try {
String text = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
list.add(new DictModel(data, text));
} catch (Exception e) {
log.warn(e.getMessage());
}
}
/**
* 字典值替换文本
*
* @param dictModels
* @param values
* @return
*/
private String translDictText(List<DictModel> dictModels, String values) {
List<String> result = new ArrayList<>();
// 允许多个逗号分隔,允许传数组对象
String[] splitVal = values.split(",");
for (String val : splitVal) {
String dictText = "";
for (DictModel dict : dictModels) {
if (val.equals(dict.getValue())) {
dictText = dict.getText();
break;
}
}
result.add(dictText);
}
return String.join(",", result);
}
/**
* 翻译字典文本
* @param code
* @param text
* @param table
* @param key
* @deprecated 不推荐
* @return
*/
@Deprecated
private String translateDictValue(String code, String text, String table, String key) {
if(oConvertUtils.isEmpty(key)) {
return null;
}
StringBuilder textValue = new StringBuilder();
String[] keys = key.split(",");
for (String k : keys) {
String tmpValue = null;
log.debug(" 字典 key : "+ k);
if (k.trim().length() == 0) {
continue; //跳过循环
}
//update-begin--Author:scott -- Date:20210531 ----for !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
tmpValue = getTmpValue(code, text, table, k, tmpValue);
//update-end--Author:scott -- Date:20210531 ----for !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
if (tmpValue != null) {
if (!"".equals(textValue.toString())) {
textValue.append(",");
}
textValue.append(tmpValue);
}
}
return textValue.toString();
}
private String getTmpValue(String code, String text, String table, String k, String tmpValue) {
if (!StringUtils.isEmpty(table)){
log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim());
if (Boolean.TRUE.equals(redisTemplate.hasKey(keyString))){
try {
tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
} catch (Exception e) {
log.warn(e.getMessage());
}
}else {
//处理用户要翻译为姓名加工号
if ("sys_user".equals(table)&&"realname".equals(text)&&"id".equals(code)){
tmpValue= commonAPI.translateUserRealNameFromTable(k.trim());
}else {
tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim());
}
}
}else {
String keyString = String.format(SYS_CACHE_DICT_S_S,code,k.trim());
if (Boolean.TRUE.equals(redisTemplate.hasKey(keyString))){
try {
tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
} catch (Exception e) {
log.warn(e.getMessage());
}
}else {
tmpValue = commonAPI.translateDict(code, k.trim());
}
}
return tmpValue;
}
/**
* @param result
*/
private void parseMethodDictText(Object result) {
if (result instanceof Result) {
Object result1 = ((Result<Object>) result).getResult();
String jsonStr = JSONUtil.toJsonStr(result1);
if (JSONUtil.isTypeJSONObject(jsonStr)) {
JSONObject translate = translate(result1);
((Result<Object>) result).setResult(translate);
} else {
List<JSONObject> items = new ArrayList<>();
for (Object o : (List<Object>) result1) {
JSONObject translate = translate(o);
items.add(translate);
}
((Result<Object>) result).setResult(items);
}
}
}
/**
* @param record
* @return
*/
private JSONObject translate(Object record) {
ObjectMapper mapper = new ObjectMapper();
String json = "{}";
try {
//解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
json = mapper.writeValueAsString(record);
} catch (JsonProcessingException e) {
log.error("json解析失败" + e.getMessage(), e);
}
JSONObject item = JSONObject.parseObject(json, Feature.OrderedField);
//update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
//for (Field field : record.getClass().getDeclaredFields()) {
for (Field field : oConvertUtils.getAllFields(record)) {
//update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
if (field.getAnnotation(Dict.class) != null) {
String code = field.getAnnotation(Dict.class).dicCode();
String text = field.getAnnotation(Dict.class).dicText();
String table = field.getAnnotation(Dict.class).dictTable();
String key = String.valueOf(item.get(field.getName()));
//翻译字典值对应的txt
String textValue = translateDictValue(code, text, table, key);
log.debug(" 字典Val : " + textValue);
log.debug(" __翻译字典字段__ " + field.getName() + CommonConstant.DICT_TEXT_SUFFIX + " " + textValue);
item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
}
//date类型默认转换string格式化日期
if (field.getType().getName().equals("java.util.Date") && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null) {
SimpleDateFormat aDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
}
}
return item;
}
}
@@ -0,0 +1,57 @@
package com.jero.common.aspect;
import com.jero.common.aspect.annotation.RedisLock;
import com.jero.common.exception.JeroBootException;
import com.jero.common.util.RedisLockHelper;
import com.jero.common.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.UUID;
/**
* 分布式部署定时任务
* @Author lqt
*/
@Slf4j
@Aspect
@Component
public class LockMethodAspect {
@Resource
private RedisLockHelper redisLockHelper;
@Resource
private RedisUtil redisUtis;
@Around("@annotation(com.jero.common.aspect.annotation.RedisLock)")
public Object around(ProceedingJoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
RedisLock redisLock = method.getAnnotation(RedisLock.class);
String value = UUID.randomUUID().toString();
log.info("====value=====" + value + "===========");
String key = redisLock.key();
log.info("====key======" + key + "===========");
try {
final boolean islock = redisLockHelper.lock(redisUtis, key, value, redisLock.expire(), redisLock.timeUnit());
log.info("isLock : {}", islock);
if (!islock) {
log.error("获取锁失败");
throw new JeroBootException("获取锁失败");
}
try {
return joinPoint.proceed();
} catch (Throwable throwable) {
throw new JeroBootException("系统异常");
}
} finally {
log.info("释放锁");
redisLockHelper.unlock(redisUtis, key, value);
}
}
}
@@ -0,0 +1,122 @@
package com.jero.common.aspect;
import com.jero.common.api.CommonAPI;
import com.jero.common.aspect.annotation.PermissionData;
import com.jero.common.system.util.JeroDataAutorUtils;
import com.jero.common.system.util.JwtUtil;
import com.jero.common.system.vo.SysPermissionDataRuleModel;
import com.jero.common.system.vo.SysUserCacheInfo;
import com.jero.common.util.SpringContextUtils;
import com.jero.common.util.oConvertUtils;
import lombok.extern.slf4j.Slf4j;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;
/**
* 数据权限切面处理类
* 当被请求的方法有注解PermissionData时,会在往当前request中写入数据权限信息
* @Date 2019年4月10日
* @Version: 1.0
*/
@Aspect
@Component
@Slf4j
public class PermissionDataAspect {
@Autowired
private CommonAPI commonAPI;
@Pointcut("@annotation(com.jero.common.aspect.annotation.PermissionData)")
public void pointCut() {
// do other
}
@Around("pointCut()")
public Object arround(ProceedingJoinPoint point) throws Throwable{
HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
PermissionData pd = method.getAnnotation(PermissionData.class);
String component = pd.pageComponent();
String requestMethod = request.getMethod();
String requestPath = request.getRequestURI().substring(request.getContextPath().length());
requestPath = filterUrl(requestPath);
log.debug("拦截请求 >> "+requestPath+";请求类型 >> "+requestMethod);
String username = JwtUtil.getUserNameByToken(request);
//查询数据权限信息
// TODO 微服务情况下也得支持缓存机制
List<SysPermissionDataRuleModel> dataRules = commonAPI.queryPermissionDataRule(component, requestPath, username);
if(dataRules!=null && !dataRules.isEmpty()) {
//临时存储
JeroDataAutorUtils.installDataSearchConditon(request, dataRules);
// TODO 微服务情况下也得支持缓存机制
SysUserCacheInfo userinfo = commonAPI.getCacheUser(username);
JeroDataAutorUtils.installUserInfo(request, userinfo);
}
return point.proceed();
}
private String filterUrl(String requestPath){
String url = "";
if(oConvertUtils.isNotEmpty(requestPath)){
url = requestPath.replace("\\", "/");
url = url.replace("//", "/");
if(url.contains("//")){
url = filterUrl(url);
}
}
return url;
}
/**
* 获取请求地址
* @param request
* @return
* @deprecated 未调用
*/
@Deprecated
private String getJgAuthRequsetPath(HttpServletRequest request) {
String queryString = request.getQueryString();
String requestPath = request.getRequestURI();
if(oConvertUtils.isNotEmpty(queryString)){
requestPath += "?" + queryString;
}
if (requestPath.indexOf("&") > -1) {// 去掉其他参数(保留一个参数) 例如:loginController.do?login
requestPath = requestPath.substring(0, requestPath.indexOf("&"));
}
if(requestPath.indexOf("=")!=-1){
if(requestPath.indexOf(".do")!=-1){
requestPath = requestPath.substring(0,requestPath.indexOf(".do")+3);
}else{
requestPath = requestPath.substring(0,requestPath.indexOf("?"));
}
}
requestPath = requestPath.substring(request.getContextPath().length() + 1);// 去掉项目路径
return filterUrl(requestPath);
}
/**
*
* @deprecated 未调用
*/
@Deprecated
private boolean moHuContain(List<String> list,String key){
for(String str : list){
if(key.contains(str)){
return true;
}
}
return false;
}
}
@@ -0,0 +1,224 @@
package com.jero.common.aspect;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jero.common.api.CommonAPI;
import com.jero.common.api.vo.Result;
import com.jero.common.aspect.annotation.Dict;
import com.jero.common.constant.CommonConstant;
import com.jero.common.system.vo.SysDictItemCore;
import com.jero.common.util.oConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Description 对controller接口返回值翻译,不支持多层嵌套翻译
* @Author lqt
* @Date 2022/6/7 17:08
* @Version 1.0
*/
@Slf4j
@Aspect
@Component
@SuppressWarnings({"unused"})
public class TranslationAspect {
@Resource
private CommonAPI commonAPI;
@Pointcut("@annotation(com.jero.common.aspect.annotation.Translation)")
public void annotationPointcut() {
// do other
}
@Before("annotationPointcut()")
public void beforePointcut(JoinPoint joinPoint) {
// 此处进入到方法前 可以实现一些业务逻辑
}
@Around("annotationPointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
this.parseDictText(result);
return result;
}
/**
* 在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
*
* @param joinPoint
*/
@AfterReturning(returning = "rvt", pointcut = "annotationPointcut()")
public void doAfterReturning(JoinPoint joinPoint, Object rvt) {
}
private void parseDictText(Object result) {
List<SysDictItemCore> listDict = commonAPI.getDictItemAll();
if (CollectionUtils.isEmpty(listDict)) {
return;
}
if (result instanceof Result) {
if (((Result) result).getResult() instanceof IPage) {
List<Object> items = new ArrayList<>();
for (Object record : ((IPage) ((Result) result).getResult()).getRecords()) {
Object item = translateObject(record, listDict);
items.add(item);
}
((IPage) ((Result) result).getResult()).setRecords(items);
} else if (((Result) result).getResult() instanceof List) {
List<Object> items = new ArrayList<>();
for (Object record : ((List) ((Result) result).getResult())) {
Object item = translateObject(record, listDict);
items.add(item);
}
((Result) result).setResult(items);
} else {
Object record = (Object) ((Result) result).getResult();
Object item = translateObject(record, listDict);
((Result) result).setResult(item);
}
}
}
public String manualParseDictText(Object data, Object user) {
List<SysDictItemCore> listDict = commonAPI.getDictItemAll();
if (CollectionUtils.isEmpty(listDict)) {
return "";
}
JSONObject dataJsonObject = (JSONObject) translateObject(data, listDict);
dataJsonObject.put("personnelObj", user);
return dataJsonObject.toJSONString();
}
private Object translateObject(Object record, List<SysDictItemCore> listDict) {
ObjectMapper mapper = new ObjectMapper();
String json;
try {
json = mapper.writeValueAsString(record);
} catch (JsonProcessingException e) {
log.error("json解析失败" + e.getMessage(), e);
return record;
}
JSONObject item;
try {
item = JSONObject.parseObject(json);
} catch (Exception e) {
log.error("json解析失败" + e.getMessage(), e);
return record;
}
for (Field field : oConvertUtils.getAllFields(record)) {
field.setAccessible(true);
// 如果字段是复杂对象类型或者是List,进行递归翻译
if (isComplexObject(field.getType()) || List.class.isAssignableFrom(field.getType())) {
Object nestedRecord;
try {
nestedRecord = field.get(record);
} catch (IllegalAccessException e) {
continue;
}
if (nestedRecord != null) {
JsonProperty jsonProperty = field.getAnnotation(JsonProperty.class);
String jsonFieldName = (jsonProperty != null) ? jsonProperty.value() : field.getName();
if (List.class.isAssignableFrom(field.getType())) {
List<?> objList = (List<?>) nestedRecord;
List<Object> translatedList = new ArrayList<>();
for (Object obj : objList) {
translatedList.add(translateObject(obj, listDict));
}
item.put(jsonFieldName, translatedList);
} else {
Object translatedNestedRecord = translateObject(nestedRecord, listDict);
item.put(jsonFieldName, translatedNestedRecord);
}
}
}
if (field.getAnnotation(Dict.class) != null) {
String code = field.getAnnotation(Dict.class).dicCode();
String text = field.getAnnotation(Dict.class).dicText();
String table = field.getAnnotation(Dict.class).dictTable();
String key = String.valueOf(item.get(field.getName()));
String textValue = translateDictValue(code, text, table, key, listDict);
item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
}
if (Objects.equals(field.getType().getName(), "java.util.Date") && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null) {
SimpleDateFormat aDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
}
}
return item;
}
private boolean isComplexObject(Class<?> type) {
return !(
type.isPrimitive() ||
type.equals(String.class) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type)
);
}
/**
* 翻译字典文本
*
* @param code 编码
* @param text 值
* @param table 表名
* @param key 键
* @param listDict 字典集合
*/
private String translateDictValue(String code, String text, String table, String key, List<SysDictItemCore> listDict) {
if (oConvertUtils.isEmpty(key)) {
return null;
}
StringBuilder textValue = new StringBuilder();
String[] keys = key.split(",");
for (String k : keys) {
String tmpValue = null;
if (k.trim().length() == 0) {
continue; //跳过循环
}
if (!StringUtils.isEmpty(table)) {
tmpValue = commonAPI.queryTableDictTextByKey(table, text, code, k.trim());
} else {
List<SysDictItemCore> listNew = listDict.stream().filter(o -> Objects.equals(o.getDictCode(), code) && Objects.equals(o.getItemValue(), k.trim())).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(listNew)) {
tmpValue = listNew.get(0).getItemText();
}
}
if (tmpValue != null) {
if (!"".equals(textValue.toString())) {
textValue.append(",");
}
textValue.append(tmpValue);
}
}
return textValue.toString();
}
}
@@ -0,0 +1,57 @@
package com.jero.common.aspect;
/**
* @Author scott
* @Date 2020/1/14 13:36
* @Description: 请求URL与菜单路由URL转换规则(方便于采用菜单路由URL来配置数据权限规则)
*/
public enum UrlMatchEnum {
CGFORM_DATA("/online/cgform/api/getData/", UrlMatch.ONLINE_CGFORMLIST),
CGFORM_EXCEL_DATA("/online/cgform/api/exportXls/", UrlMatch.ONLINE_CGFORMLIST),
CGFORM_TREE_DATA("/online/cgform/api/getTreeData/", UrlMatch.ONLINE_CGFORMLIST),
CGREPORT_DATA("/online/cgreport/api/getColumnsAndData/", "/online/cgreport/"),
CGREPORT_EXCEL_DATA("/online/cgreport/api/exportXls/", "/online/cgreport/");
UrlMatchEnum(String url, String matchUrl) {
this.url = url;
this.matchUrl = matchUrl;
}
/**
* Request 请求 URL前缀
*/
private String url;
/**
* 菜单路由 URL前缀 (对应菜单路径)
*/
private String matchUrl;
/**
* 根据req url 获取到菜单配置路径(前端页面路由URL)
*
* @param url
* @return
*/
public static String getMatchResultByUrl(String url) {
//获取到枚举
UrlMatchEnum[] values = UrlMatchEnum.values();
//加强for循环进行遍历操作
for (UrlMatchEnum lr : values) {
//如果遍历获取的type和参数type一致
if (url.indexOf(lr.url) != -1) {
//返回type对象的desc
return url.replace(lr.url, lr.matchUrl);
}
}
return null;
}
public class UrlMatch{
private UrlMatch(){
}
public static final String ONLINE_CGFORMLIST = "/online/cgformList/";
}
}
@@ -0,0 +1,45 @@
package com.jero.common.aspect.annotation;
import com.jero.common.constant.CommonConstant;
import com.jero.common.constant.enums.ModuleType;
import java.lang.annotation.*;
/**
* 系统日志注解
*
* @Author scott
* @Date 2019年1月14日
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutoLog {
/**
* 日志内容
*
* @return
*/
String value() default "";
/**
* 日志类型
*
* @return 0:操作日志;1:登录日志;2:定时任务;
*/
int logType() default CommonConstant.LOG_TYPE_2;
/**
* 操作日志类型
*
* @return 1查询,2添加,3修改,4删除)
*/
int operateType() default 0;
/**
* 模块类型 默认为common
* @return
*/
ModuleType module() default ModuleType.COMMON;
}
@@ -0,0 +1,42 @@
package com.jero.common.aspect.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 类描述: 字典注解
* 作 者: dangzhenghui
* 日 期: 2019年03月17日-下午9:37:16
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dict {
/**
* 方法描述: 数据code
* 作 者: dangzhenghui
* 日 期: 2019年03月17日-下午9:37:16
*
* @return 返回类型: String
*/
String dicCode();
/**
* 方法描述: 数据Text
* 作 者: dangzhenghui
* 日 期: 2019年03月17日-下午9:37:16
*
* @return 返回类型: String
*/
String dicText() default "";
/**
* 方法描述: 数据字典表
* 作 者: dangzhenghui
* 日 期: 2019年03月17日-下午9:37:16
*
* @return 返回类型: String
*/
String dictTable() default "";
}
@@ -0,0 +1,17 @@
package com.jero.common.aspect.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 字典转换点注解
* 加到方法上,返回值会返回字典数据
* @author liJiaRao
* @date 2021-08-02 9:44
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DictPoint {
}
@@ -0,0 +1,18 @@
package com.jero.common.aspect.annotation;
import java.lang.annotation.*;
/**
* online请求拦截专用注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface OnlineAuth {
/**
* 请求关键字,在xxx/code之前的字符串
* @return
*/
String value();
}
@@ -0,0 +1,29 @@
package com.jero.common.aspect.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 数据权限注解
* @Author taoyan
* @Date 2019年4月11日
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface PermissionData {
/**
* 暂时没用
* @return
*/
String value() default "";
/**
* 配置菜单的组件路径,用于数据权限
*/
String pageComponent() default "";
}
@@ -0,0 +1,24 @@
package com.jero.common.aspect.annotation;
import java.lang.annotation.*;
import java.util.concurrent.TimeUnit;
/**
* @author LQT
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface RedisLock {
/*** 业务键** @return*/
String key();
/*** 锁的过期秒数,默认是5秒** @return*/
int expire() default 5;
/*** 尝试加锁,最多等待时间** @return*/
long waitTime() default Long.MIN_VALUE;
/*** 锁的超时时间单位** @return*/
TimeUnit timeUnit() default TimeUnit.SECONDS;
}
@@ -0,0 +1,14 @@
package com.jero.common.aspect.annotation;
import java.lang.annotation.*;
/**
* 只适用controller层,在controller上添加此注解,该注解对返回结果进行翻译,不支持多层嵌套
* @author LQT
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Translation {
}
@@ -0,0 +1,343 @@
package com.jero.common.constant;
public class CommonConstant {
private CommonConstant(){
}
/**
* 用户默认密码
*/
public static final String DEFAULT_PASSWORD = "srms1q2w3e";
/**
* 正常状态
*/
public static final Integer STATUS_NORMAL = 0;
/**
* 禁用状态
*/
public static final Integer STATUS_DISABLE = -1;
/**
* 删除标志
*/
public static final Integer DEL_FLAG_1 = 1;
/**
* 未删除
*/
public static final Integer DEL_FLAG_0 = 0;
/**
* 系统日志类型: 登录
*/
public static final int LOG_TYPE_1 = 1;
/**
* 系统日志类型: 操作
*/
public static final int LOG_TYPE_2 = 2;
/**
* 操作日志类型: 查询
*/
public static final int OPERATE_TYPE_1 = 1;
/**
* 操作日志类型: 添加
*/
public static final int OPERATE_TYPE_2 = 2;
/**
* 操作日志类型: 更新
*/
public static final int OPERATE_TYPE_3 = 3;
/**
* 操作日志类型: 删除
*/
public static final int OPERATE_TYPE_4 = 4;
/**
* 操作日志类型: 倒入
*/
public static final int OPERATE_TYPE_5 = 5;
/**
* 操作日志类型: 导出
*/
public static final int OPERATE_TYPE_6 = 6;
/** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */
public static final Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
/** {@code 200 OK} (HTTP/1.0 - RFC 1945) */
public static final Integer SC_OK_200 = 200;
/** {@code 600 OK} (自编,RSA过期) */
public static final Integer SC_RSA_TIMEOUT_600 = 600;
/**访问权限认证未通过 510*/
public static final Integer SC_JERO_NO_AUTHZ=510;
/** 登录用户Shiro权限缓存KEY前缀 */
public static final String PREFIX_USER_SHIRO_CACHE = "shiro:cache:com.jero.config.shiro.ShiroRealm.authorizationCache:";
/** 登录用户Token令牌缓存KEY前缀 */
public static final String PREFIX_USER_TOKEN = "prefix_user_token_";
/** Token缓存时间:3600秒即一小时 */
public static final int TOKEN_EXPIRE_TIME = 3600;
/**
* 0:一级菜单
*/
public static final Integer MENU_TYPE_0 = 0;
/**
* 1:子菜单
*/
public static final Integer MENU_TYPE_1 = 1;
/**
* 2:按钮权限
*/
public static final Integer MENU_TYPE_2 = 2;
/**通告对象类型(USER:指定用户,ALL:全体用户)*/
public static final String MSG_TYPE_UESR = "USER";
public static final String MSG_TYPE_ALL = "ALL";
/**发布状态(0未发布,1已发布,2已撤销)*/
public static final String NO_SEND = "0";
public static final String HAS_SEND = "1";
public static final String HAS_CANCLE = "2";
/**阅读状态(0未读,1已读)*/
public static final String HAS_READ_FLAG = "1";
public static final String NO_READ_FLAG = "0";
/**优先级(L低,M中,H高)*/
public static final String PRIORITY_L = "L";
public static final String PRIORITY_M = "M";
public static final String PRIORITY_H = "H";
/**
* 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板
*/
public static final String SMS_TPL_TYPE_0 = "0";
public static final String SMS_TPL_TYPE_1 = "1";
public static final String SMS_TPL_TYPE_2 = "2";
/**
* 状态(0无效1有效)
*/
public static final String STATUS_0 = "0";
public static final String STATUS_1 = "1";
/**
* 同步工作流引擎1同步0不同步
*/
public static final Integer ACT_SYNC_1 = 1;
public static final Integer ACT_SYNC_0 = 0;
/**
* 消息类型1:通知公告2:系统消息
*/
public static final String MSG_CATEGORY_1 = "1";
public static final String MSG_CATEGORY_2 = "2";
/**
* 是否配置菜单的数据权限 1是0否
*/
public static final Integer RULE_FLAG_0 = 0;
public static final Integer RULE_FLAG_1 = 1;
/**
* 是否用户已被冻结 1正常(解冻) 2冻结
*/
public static final Integer USER_UNFREEZE = 1;
public static final Integer USER_FREEZE = 2;
/**字典翻译文本后缀*/
public static final String DICT_TEXT_SUFFIX = "_dictText";
/**
* 表单设计器主表类型
*/
public static final Integer DESIGN_FORM_TYPE_MAIN = 1;
/**
* 表单设计器子表表类型
*/
public static final Integer DESIGN_FORM_TYPE_SUB = 2;
/**
* 表单设计器URL授权通过
*/
public static final Integer DESIGN_FORM_URL_STATUS_PASSED = 1;
/**
* 表单设计器URL授权未通过
*/
public static final Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2;
/**
* 表单设计器新增 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_ADD = "add";
/**
* 表单设计器修改 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_EDIT = "edit";
/**
* 表单设计器详情 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_DETAIL = "detail";
/**
* 表单设计器复用数据 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_REUSE = "reuse";
/**
* 表单设计器编辑 Flag (已弃用)
*/
public static final String DESIGN_FORM_URL_TYPE_VIEW = "view";
/**
* online参数值设置(是:Y, 否:N)
*/
public static final String ONLINE_PARAM_VAL_IS_TURE = "Y";
public static final String ONLINE_PARAM_VAL_IS_FALSE = "N";
/**
* 文件上传类型(本地:localMiniominio,阿里云:alioss
*/
public static final String UPLOAD_TYPE_LOCAL = "local";
public static final String UPLOAD_TYPE_MINIO = "minio";
public static final String UPLOAD_TYPE_OSS = "alioss";
/**
* 文档上传自定义桶名称
*/
public static final String UPLOAD_CUSTOM_BUCKET = "eoafile";
/**
* 文档上传自定义路径
*/
public static final String UPLOAD_CUSTOM_PATH = "eoafile";
/**
* 文件外链接有效天数
*/
public static final Integer UPLOAD_EFFECTIVE_DAYS = 1;
/**
* 员工身份 (1:普通员工 2:上级)
*/
public static final Integer USER_IDENTITY_1 = 1;
public static final Integer USER_IDENTITY_2 = 2;
/** sys_user 表 username 唯一键索引 */
public static final String SQL_INDEX_INDEX_USER_NAME = "index_user_name";
/** sys_user 表 username 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
/** sys_user 表 phone 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone";
/** sys_user 表 email 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
/** sys_quartz_job 表 job_class_name 唯一键索引 */
public static final String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name";
/** sys_position 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_CODE = "uniq_code";
/** sys_role 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code";
/** sys_depart 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code";
/**
* 在线聊天 是否为默认分组
*/
public static final String IM_DEFAULT_GROUP = "1";
/**
* 在线聊天 图片文件保存路径
*/
public static final String IM_UPLOAD_CUSTOM_PATH = "imfile";
/**
* 在线聊天 用户状态
*/
public static final String IM_STATUS_ONLINE = "online";
/**
* 在线聊天 SOCKET消息类型
*/
public static final String IM_SOCKET_TYPE = "chatMessage";
/**
* 在线聊天 是否开启默认添加好友 1是 0否
*/
public static final String IM_DEFAULT_ADD_FRIEND = "1";
/**
* 在线聊天 用户好友缓存前缀
*/
public static final String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_";
/**
* 考勤补卡业务状态 (1:同意 2:不同意)
*/
public static final String SIGN_PATCH_BIZ_STATUS_1 = "1";
public static final String SIGN_PATCH_BIZ_STATUS_2 = "2";
/**
* 公文文档上传自定义路径
*/
public static final String UPLOAD_CUSTOM_PATH_OFFICIAL = "officialdoc";
/**
* 公文文档下载自定义路径
*/
public static final String DOWNLOAD_CUSTOM_PATH_OFFICIAL = "officaldown";
/**
* WPS存储值类别(1 code文号 2 text(WPS模板还是公文发文模板))
*/
public static final String WPS_TYPE_1="1";
public static final String WPS_TYPE_2="2";
public static final String X_ACCESS_TOKEN = "X-Access-Token";
// common/view 预览接口用的token
public static final String AT = "at";
public static final String X_SIGN = "X-Sign";
public static final String X_TIMESTAMP = "X-TIMESTAMP";
/**
* 多租户 请求头
*/
public static final String TENANT_ID = "tenant-id";
/**
* 微服务读取配置文件属性 服务地址
*/
public static final String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr";
/**
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用
*/
public static final String THIRD_LOGIN_CODE = "third_login_code";
public static final String ANNOUNCEMENT_SEND_STATUS_0 = "0";
/** 系统通告消息状态:1=已发布 */
public static final String ANNOUNCEMENT_SEND_STATUS_1 = "1";
/** 系统通告消息状态:2=已撤销 */
public static final String ANNOUNCEMENT_SEND_STATUS_2 = "2";
/**
* 标准来源(1国内、2海外、3企业)
*/
public static final String STANDARD_SOURCE_1 = "1";
public static final String STANDARD_SOURCE_2 = "2";
public static final String STANDARD_SOURCE_3 = "3";
public static final String STANDARD_SOURCE_4 = "4";
/**
* 阅读状态(1未读、2已读)
*/
public static final String READING_STATUS_1 = "1";
public static final String READING_STATUS_2 = "2";
}
@@ -0,0 +1,28 @@
package com.jero.common.constant;
/**
* 系统通告 - 发布状态
* @Author LeeShaoQing
*
*/
public class CommonSendStatus {
private CommonSendStatus(){
}
public static final String UNPUBLISHED_STATUS_0 = "0"; //未发布
public static final String PUBLISHED_STATUS_1 = "1"; //已发布
public static final String REVOKE_STATUS_2 = "2"; //撤销
//app端推送会话标识后缀
public static final String APP_SESSION_SUFFIX = "_app"; //app端推送会话标识后缀
/**流程催办——系统通知消息模板*/
public static final String TZMB_BPM_CUIBAN = "bpm_cuiban";
/**标准模板—系统消息通知*/
public static final String TZMB_SYS_TS_NOTE = "sys_ts_note";
/**流程超时提醒——系统通知消息模板*/
public static final String TZMB_BPM_CHAOSHI_TIP = "bpm_chaoshi_tip";
}
@@ -0,0 +1,127 @@
package com.jero.common.constant;
/**
* 数据库上下文常量
*/
public class DataBaseConstant {
private DataBaseConstant(){
}
//*********数据库类型****************************************
public static final String DB_TYPE_MYSQL = "MYSQL";
public static final String DB_TYPE_ORACLE = "ORACLE";
public static final String DB_TYPE_DM = "DM";//达梦数据库
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
// 数据库类型,对应 database_type 字典
public static final String DB_TYPE_MYSQL_NUM = "1";
public static final String DB_TYPE_ORACLE_NUM = "2";
public static final String DB_TYPE_SQLSERVER_NUM = "3";
public static final String DB_TYPE_POSTGRESQL_NUM = "4";
//*********系统上下文变量****************************************
/**
* 数据-所属机构编码
*/
public static final String SYS_ORG_CODE = "sysOrgCode";
/**
* 数据-所属机构编码
*/
public static final String SYS_ORG_CODE_TABLE = "sys_org_code";
/**
* 数据-所属机构编码
*/
public static final String SYS_MULTI_ORG_CODE = "sysMultiOrgCode";
/**
* 数据-所属机构编码
*/
public static final String SYS_MULTI_ORG_CODE_TABLE = "sys_multi_org_code";
/**
* 数据-系统用户编码(对应登录用户账号)
*/
public static final String SYS_USER_CODE = "sysUserCode";
/**
* 数据-系统用户编码(对应登录用户账号)
*/
public static final String SYS_USER_CODE_TABLE = "sys_user_code";
/**
* 登录用户真实姓名
*/
public static final String SYS_USER_NAME = "sysUserName";
/**
* 登录用户真实姓名
*/
public static final String SYS_USER_NAME_TABLE = "sys_user_name";
/**
* 系统日期"yyyy-MM-dd"
*/
public static final String SYS_DATE = "sysDate";
/**
* 系统日期"yyyy-MM-dd"
*/
public static final String SYS_DATE_TABLE = "sys_date";
/**
* 系统时间"yyyy-MM-dd HH:mm"
*/
public static final String SYS_TIME = "sysTime";
/**
* 系统时间"yyyy-MM-dd HH:mm"
*/
public static final String SYS_TIME_TABLE = "sys_time";
//*********系统上下文变量****************************************
//*********系统建表标准字段****************************************
/**
* 创建者登录名称
*/
public static final String CREATE_BY_TABLE = "create_by";
/**
* 创建者登录名称
*/
public static final String CREATE_BY = "createBy";
/**
* 创建日期时间
*/
public static final String CREATE_TIME_TABLE = "create_time";
/**
* 创建日期时间
*/
public static final String CREATE_TIME = "createTime";
/**
* 更新用户登录名称
*/
public static final String UPDATE_BY_TABLE = "update_by";
/**
* 更新用户登录名称
*/
public static final String UPDATE_BY = "updateBy";
/**
* 更新日期时间
*/
public static final String UPDATE_TIME = "updateTime";
/**
* 更新日期时间
*/
public static final String UPDATE_TIME_TABLE = "update_time";
/**
* 业务流程状态
*/
public static final String BPM_STATUS = "bpmStatus";
/**
* 业务流程状态
*/
public static final String BPM_STATUS_TABLE = "bpm_status";
//*********系统建表标准字段****************************************
/**
* 租户ID 实体字段名
*/
public static final String TENANT_ID = "tenantId";
/**
* 租户ID 数据库字段名
*/
public static final String TENANT_ID_TABLE = "tenant_id";
}
@@ -0,0 +1,34 @@
package com.jero.common.constant;
/**
* 规则值生成 编码常量类
* @author: taoyan
* @date: 2020年04月02日
*/
public class FillRuleConstant {
private FillRuleConstant(){
}
/**
* 公文发文编码
*/
public static final String DOC_SEND = "doc_send_code";
/**
* 部门编码
*/
public static final String DEPART = "org_num_role";
/**
* 分类字典编码
*/
public static final String CATEGORY = "category_code_rule";
/**
* 体系字典编码
*/
public static final String SYSTEM = "system_tree_node";
}
@@ -0,0 +1,127 @@
package com.jero.common.constant;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jero.common.util.oConvertUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
@Component("pca")
public class ProvinceCityArea {
List<Area> areaList;
public String getText(String code){
this.initAreaList();
if(!CollectionUtils.isEmpty(this.areaList)){
List<String> ls = new ArrayList<>();
getAreaByCode(code,ls);
return String.join("/",ls);
}
return "";
}
public String getCode(String text){
this.initAreaList();
if(!CollectionUtils.isEmpty(areaList)){
for(int i=areaList.size()-1;i>=0;i--){
if(text.indexOf(areaList.get(i).getText())>=0){
return areaList.get(i).getId();
}
}
}
return null;
}
public void getAreaByCode(String code,List<String> ls){
for(Area area: areaList){
if(area.getId().equals(code)){
String pid = area.getPid();
ls.add(0,area.getText());
getAreaByCode(pid,ls);
}
}
}
private void initAreaList(){
if(CollectionUtils.isEmpty(this.areaList)){
this.areaList = new ArrayList<>();
try {
String jsonData = oConvertUtils.readStatic("classpath:static/pca.json");
JSONObject baseJson = JSON.parseObject(jsonData);
//第一层 省
JSONObject provinceJson = baseJson.getJSONObject("86");
for(String provinceKey: provinceJson.keySet()){
Area province = new Area(provinceKey,provinceJson.getString(provinceKey),"86");
this.areaList.add(province);
//第二层 市
JSONObject cityJson = baseJson.getJSONObject(provinceKey);
for(String cityKey:cityJson.keySet()){
Area city = new Area(cityKey,cityJson.getString(cityKey),provinceKey);
this.areaList.add(city);
//第三层 区
JSONObject areaJson = baseJson.getJSONObject(cityKey);
if(areaJson!=null){
addArea(cityKey, areaJson);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void addArea(String cityKey, JSONObject areaJson) {
for(String areaKey:areaJson.keySet()){
Area area = new Area(areaKey,areaJson.getString(areaKey),cityKey);
this.areaList.add(area);
}
}
/**
*
* @deprecated 未调用
*/
@Deprecated
private String jsonRead(File file){
StringBuilder buffer = new StringBuilder();
try(Scanner scanner = new Scanner(file, "utf-8");) {
while (scanner.hasNextLine()) {
buffer.append(scanner.nextLine());
}
} catch (Exception e) {
e.printStackTrace();
}
return buffer.toString();
}
class Area{
String id;
String text;
String pid;
public Area(String id,String text,String pid){
this.id = id;
this.text = text;
this.pid = pid;
}
public String getId() {
return id;
}
public String getText() {
return text;
}
public String getPid() {
return pid;
}
}
}
@@ -0,0 +1,42 @@
/*
*
* * Copyright (c) 2019-2020, 冷冷 (wangiegie@gmail.com).
* * <p>
* * Licensed under the GNU Lesser General Public License 3.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* * <p>
* * https://www.gnu.org/licenses/lgpl.html
* * <p>
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.jero.common.constant;
/**
* @author scott
* @date 2019年05月18日
* 服务名称
*/
public class ServiceNameConstants {
private ServiceNameConstants(){
}
/**
* 系统管理 admin
*/
public static final String SYSTEM_SERVICE = "jero-system";
/**
* gateway通过header传递根路径 basePath
*/
public static final String X_GATEWAY_BASE_PATH = "X_GATEWAY_BASE_PATH";
}
@@ -0,0 +1,34 @@
package com.jero.common.constant;
/**
* VXESocket 常量
*/
public class VXESocketConst {
private VXESocketConst(){
}
/**
* 消息类型
*/
public static final String TYPE = "type";
/**
* 消息数据
*/
public static final String DATA = "data";
/**
* 消息类型:心跳检测
*/
public static final String TYPE_HB = "heart_beat";
/**
* 消息类型:通用数据传递
*/
public static final String TYPE_CSD = "common_send_date";
/**
* 消息类型:更新vxe table数据
*/
public static final String TYPE_UVT = "update_vxe_table";
}
@@ -0,0 +1,64 @@
package com.jero.common.constant;
/**
* @Description: Websocket常量类
* @author: taoyan
* @date: 2020年03月23日
*/
public class WebsocketConst {
private WebsocketConst(){
}
/**
* 消息json key:cmd
*/
public static final String MSG_CMD = "cmd";
/**
* 消息json key:msgId
*/
public static final String MSG_ID = "msgId";
/**
* 消息json key:msgTxt
*/
public static final String MSG_TXT = "msgTxt";
/**
* 消息json key:userId
*/
public static final String MSG_USER_ID = "userId";
/**
* 消息类型 heartcheck
*/
public static final String CMD_CHECK = "heartcheck";
/**
* 消息类型 user 用户消息
*/
public static final String CMD_USER = "user";
/**
* 消息类型 topic 系统通知
*/
public static final String CMD_TOPIC = "topic";
/**
* 消息类型 email
*/
public static final String CMD_EMAIL = "email";
/**
* 消息类型 meetingsign 会议签到
*/
public static final String CMD_SIGN = "sign";
/**
* 消息类型 新闻发布/取消
*/
public static final String NEWS_PUBLISH = "publish";
}
@@ -0,0 +1,152 @@
package com.jero.common.constant.enums;
import java.util.*;
/**
* online表单枚举 代码生成器用到
*/
public enum CgformEnum {
/**
* 单表
*/
ONE(1, "one", Cgform.CODE_TEMPLATE_ONLINE, "default.one", "经典风格"),
/**
* 多表
*/
MANY(2, "many", Cgform.CODE_TEMPLATE_ONLINE, "default.onetomany", "经典风格"),
/**
* 多表
*/
ERP(2, "erp", Cgform.CODE_TEMPLATE_ONLINE, "erp.onetomany", "ERP风格"),
/**
* 多表(jvxe风格)
* */
JVXE_TABLE(2, "jvxe", Cgform.CODE_TEMPLATE_ONLINE, "jvxe.onetomany", "JVXE风格"),
/**
* 多表(内嵌子表风格)
*/
INNER_TABLE(2, "innerTable", Cgform.CODE_TEMPLATE_ONLINE, "inner-table.onetomany", "内嵌子表风格"),
/**
* 多表(tab风格)
* */
TAB(2, "tab", Cgform.CODE_TEMPLATE_ONLINE, "tab.onetomany", "Tab风格"),
/**
* 树形列表
*/
TREE(3, "tree", Cgform.CODE_TEMPLATE_ONLINE, "default.tree", "树形列表");
/**
* 类型 1/单表 2/一对多 3/树
*/
int type;
/**
* 编码标识
*/
String code;
/**
* 代码生成器模板路径
*/
String templatePath;
/**
* 代码生成器模板路径
*/
String stylePath;
/**
* 模板风格名称
*/
String note;
/**
* 构造器
*
* @param type 类型 1/单表 2/一对多 3/树
* @param code 模板编码
* @param templatePath 模板路径
* @param stylePath 模板子路径
* @param note
*/
CgformEnum(int type, String code, String templatePath, String stylePath, String note) {
this.type = type;
this.code = code;
this.templatePath = templatePath;
this.stylePath = stylePath;
this.note = note;
}
/**
* 根据code获取模板路径
*
* @param code
* @return
*/
public static String getTemplatePathByConfig(String code) {
return Objects.requireNonNull(getCgformEnumByConfig(code)).templatePath;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getTemplatePath() {
return templatePath;
}
public void setTemplatePath(String templatePath) {
this.templatePath = templatePath;
}
public String getStylePath() {
return stylePath;
}
public void setStylePath(String stylePath) {
this.stylePath = stylePath;
}
/**
* 根据code找枚举
*
* @param code
* @return
*/
public static CgformEnum getCgformEnumByConfig(String code) {
for (CgformEnum e : CgformEnum.values()) {
if (e.code.equals(code)) {
return e;
}
}
return null;
}
/**
* 根据类型找所有
*
* @param type
* @return
*/
public static List<Map<String, Object>> getJspModelList(int type) {
List<Map<String, Object>> ls = new ArrayList<>();
for (CgformEnum e : CgformEnum.values()) {
if (e.type == type) {
Map<String, Object> map = new HashMap<>();
map.put("code", e.code);
map.put("note", e.note);
ls.add(map);
}
}
return ls;
}
public class Cgform{
private Cgform(){
}
public static final String CODE_TEMPLATE_ONLINE = "/jero/code-template-online";
}
}
@@ -0,0 +1,37 @@
package com.jero.common.constant.enums;
/**
* 中英文切换标识
* @description
* @date 2022/1/21 15:22
* @auth zhn
*/
public enum IsMustEnum {
YES("","1"),
NO("","0");
String name;
String value;
private IsMustEnum(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@@ -0,0 +1,22 @@
package com.jero.common.constant.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 中英文切换标识
* @description
* @date 2022/1/21 15:22
* @auth zhn
*/
@Getter
@AllArgsConstructor
public enum LanguageEnum {
/**
* 中文,英文
*/
CN("cn"), EN("en");
String value;
}
@@ -0,0 +1,42 @@
package com.jero.common.constant.enums;
public enum MessageType2Enum {
SUBSCRIPTION_NOTIFICATION("Subscription Notification","订阅通知"),
SHARE_FORWARD("Share Forward","转发推送"),
REGULATION_EARLY_WARNING("Regulation Early Warning","法规预警"),
REGULATION_LIST_CONFIRMATION("Regulation List Confirmation","法规清单确认"),
REGULATION_TASK_CONFIRMATION("Regulation Task Confirmation","法规任务确认"),
DESIGN_COMPLIANCE_CONFIRMATION("Design Compliance Confirmation","设计符合性确认"),
PRE_HOMO_CONFIRMATION("Pre-Homo Confirmation","Pre-Homo确认"),
VALIDATION_COMPLIANCE_CONFIRMATION("Validation Compliance Confirmation","验证符合性确认"),
REGULATION_OPINION_COLLECTION("Regulation Opinion Collection","法规意见收集"),
REGULATION_TECHNICAL_ASSESSMENT("Regulation Technical Assessment","法规技术评估"),
HOMO_PARAMETER_COLLECTION("Homo Parameter Collection","认证参数收集"),
CERTIFICATION_LIST_CONFIRMATION("Certification List Confirmation","认证清单确认");
String en;
String cn;
MessageType2Enum(String en, String cn) {
this.en = en;
this.cn = cn;
}
public String getEn() {
return en;
}
public void setEn(String en) {
this.en = en;
}
public String getCn() {
return cn;
}
public void setCn(String cn) {
this.cn = cn;
}
}
@@ -0,0 +1,65 @@
package com.jero.common.constant.enums;
/**
* @description
* @date 2022/1/21 15:22
* @auth zhn
*/
public enum MessageTypeEnum {
READ("Subscription Notification","订阅通知","1"),
WARN("Regulation Early Warning","法规预警","2"),
PUSH("Share / Forward","转发推送","3"),
HOMO_TASK("Homo Parameter Task","","4"),
TASK("Regulation Compliance Task","", "5"),
//REGULATION_LIST_CONFIRMATION_TASK("Regulation List Confirmation Task", "6"), // 清单确认任务
//REGULATION_LIST_CONFIRMATION_NOTIFICATION("Regulation List Confirmation Notification", "7"), // 清单确认通知
//REGULATION_TASK_CONFIRMATION_TASK("Regulation Task Confirmation", "8"), // 任务确认任务
//REGULATION_TASK_CONFIRMATION_NOTIFICATION("Regulation Task Confirmation Notification", "15"), // 任务确认通知
//DESIGN_COMPLIANCE_TASK("Design Compliance Task", "9"), // 设计符合性任务
//PRE_HOMO_TASK("Pre-Homo Task", "10"), // Pre-Homo任务
//VALIDATION_TASK("Validation Compliance Task", "11"), // 验证符合性任务
//DESIGN_COMPLIANCE_NOTIFICATION("Design Compliance Notification", "12"), // 设计符合性通知
//PRE_HOMO_NOTIFICATION("Pre-Homo Notification", "13"), // Pre-Homo通知
//VALIDATION_COMPLIANCE_NOTIFICATION("Validation Compliance Notification", "14"), // 验证符合性通知
SYSTEMATIC_NOTIFICATION("Systematic Notification","系统通知", "15"), // 系统通知
LIST_CONFIRMATION("List Confirmation", "","17"), // 清单确认
TASK_CONFIRMATION("Task Confirmation", "","18"), // 任务确认
COMPLIANCE_CONFIRMATION("Compliance Confirmation","", "19"), // 符合性确认
COLLECTION_OF_LEGISLATIVE_COMMENTS("Collection of Legislative Comments","", "20"), // 法规意见收集
REGULATORY_AND_TECHNICAL_ASSESSMENT("Regulatory and technical assessment", "","21"), // 法规技术评估
;
String name;
String nameCn;
String value;
private MessageTypeEnum(String name,String nameCn, String value) {
this.name = name;
this.nameCn = nameCn;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getNameCn() {
return nameCn;
}
public void setNameCn(String nameCn) {
this.nameCn = nameCn;
}
}
@@ -0,0 +1,42 @@
package com.jero.common.constant.enums;
/**
* @description
* @date 2022/1/21 16:42
* @auth zhn
*/
public enum ModuleEnum {
DOCUMENT_LIBRARY("文档管理","1"),
OCR_RECORD("OCR识别转换记录表","2"),
FILE_SPLIT("文档拆分","3"),
FILE_SPLIT_ITEMS("文档拆分条款","4"),
ONL_CGFORM_COLLECTION("我的收藏","5"),
ONL_CGFORM_SUBSCRIBE("我的订阅","6"),
PARAMS_COLLECT_MANIFEST("参数收集清单","7"),
PARAMS_REPORT_DETAIL("上报库参数项","8");
String name;
String value;
private ModuleEnum(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@@ -0,0 +1,17 @@
package com.jero.common.constant.enums;
/**
* 日志按模块分类
*/
public enum ModuleType {
/**
* 普通
*/
COMMON,
/**
* online
*/
ONLINE;
}
@@ -0,0 +1,32 @@
package com.jero.common.constant.enums;
public enum MsgColorEnum {
GREEN("其他","green"),
RED("任务被拒绝","red"),
YELLOW("任务逾期","yellow");
String label;
String value;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
MsgColorEnum(String label, String value) {
this.label = label;
this.value = value;
}
}
@@ -0,0 +1,33 @@
package com.jero.common.constant.enums;
/**
* @description
* @date 2022/1/21 15:02
* @auth zhn
*/
public enum TableEnum {
BUSS_DOCUMENT_LIBRARY("buss_document_library"),
OCR_RECORD("ocr_record"),
FILE_SPLIT("sar_file_split_info"),
FILE_SPLIT_ITEMS("laws_document_split"),
TAG("onl_cgform_tag"),
TAG_AREA("onl_cgform_area"),
ONL_CGFORM_COLLECTION("onl_cgform_collection"),
ONL_CGFORM_SUBSCRIBE("onl_cgform_subscribe"),
PARAMS_COLLECT_MANIFEST("params_collect_manifest"),
PARAMS_REPORT_DETAIL("params_report_detail");
String table;
private TableEnum(String table) {
this.table = table;
}
public String getTable() {
return table;
}
public void setTable(String table) {
this.table = table;
}
}
@@ -0,0 +1,23 @@
package com.jero.common.constant.enums;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @description
* @date 2022/1/21 15:22
* @auth zhn
*/
@Getter
@AllArgsConstructor
public enum YesOrNoEnum {
NO("","0",0),
YES("","1",1);
String name;
String value;
Integer integer;
}
@@ -0,0 +1,589 @@
package com.jero.common.es;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.jero.common.util.RestUtil;
import com.jero.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.util.*;
/**
* 关于 ElasticSearch 的一些方法(创建索引、添加数据、查询等)
*
* @author sunjianlei
*/
@Slf4j
@Component
public class JeroElasticsearchTemplate {
/** es服务地址 */
private String baseUrl;
private static final String FORMAT_JSON = "format=json";
/** Elasticsearch 的版本号 */
private String version = null;
// ElasticSearch 最大可返回条目数
public static final int ES_MAX_SIZE = 10000;
@Value("${jero.elasticsearch.username}")
private String username;
@Value("${jero.elasticsearch.password}")
private String password;
public JeroElasticsearchTemplate(@Value("${jero.elasticsearch.cluster-nodes}") String baseUrl, @Value("${jero.elasticsearch.check-enabled}") boolean checkEnabled) {
log.debug("JeroElasticsearchTemplate BaseURL" + baseUrl);
if (StringUtils.isNotEmpty(baseUrl)) {
this.baseUrl = baseUrl;
// 验证配置的ES地址是否有效
if (checkEnabled) {
try {
this.getElasticsearchVersion();
String basicAuth = this.getBasicAuth();
HttpRequest.get(this.getBaseUrl().toString())
.header("Authorization", basicAuth)
.execute()
.body();
log.info("ElasticSearch 服务连接成功");
log.info("ElasticSearch version: " + this.version);
} catch (Exception e) {
this.version = "";
log.warn("ElasticSearch 服务连接失败,原因:配置未通过。可能是BaseURL未配置或配置有误,也可能是Elasticsearch服务未启动。接下来将会拒绝执行任何方法!");
}
}
}
}
/**
* 获取 Elasticsearch 的版本号信息,失败返回null
*/
private void getElasticsearchVersion() {
if (this.version == null) {
String basicAuth = this.getBasicAuth();
String response = HttpRequest.get(this.getBaseUrl().toString())
.header("Authorization", basicAuth)
.execute()
.body();
JSONObject result = JSONObject.parseObject(response);
if (result != null) {
JSONObject v = result.getJSONObject("version");
this.version = v.getString("number");
}
}
}
public String getBasicAuth(){
String authString = username + ":" + password;
String encode = Base64.getEncoder().encodeToString(authString.getBytes());
String authHeader = "Basic " + encode;
return authHeader;
}
public StringBuilder getBaseUrl(String indexName, String typeName) {
typeName = typeName.trim().toLowerCase();
return this.getBaseUrl(indexName).append("/").append(typeName);
}
public StringBuilder getBaseUrl(String indexName) {
indexName = indexName.trim().toLowerCase();
return this.getBaseUrl().append("/").append(indexName);
}
public StringBuilder getBaseUrl() {
return new StringBuilder("http://").append(this.baseUrl);
}
/**
* cat 查询ElasticSearch系统数据,返回json
*/
public JSONArray _cat(String urlAfter) {
String url = this.getBaseUrl().append("/_cat").append(urlAfter).append("?").append(FORMAT_JSON).toString();
String basicAuth = this.getBasicAuth();
String response = HttpRequest.get(url)
.header("Authorization", basicAuth)
.execute()
.body();
JSONArray jsonArray = JSONArray.parseArray(response);
return jsonArray;
}
public JSONObject put(String url){
String basicAuth = this.getBasicAuth();
String response = HttpRequest.put(url)
.header("Authorization", basicAuth)
.execute()
.body();
JSONObject jsonObject = JSONObject.parseObject(response);
return jsonObject;
}
public JSONObject put(String url, String params){
String basicAuth = this.getBasicAuth();
String response = HttpRequest.put(url)
.body(params)
.header("Authorization", basicAuth)
.execute()
.body();
JSONObject jsonObject = JSONObject.parseObject(response);
return jsonObject;
}
public JSONObject get(String url, JSONObject params){
String basicAuth = this.getBasicAuth();
String response = HttpRequest.get(url)
.body(params.toJSONString())
.header("Authorization", basicAuth)
.execute()
.body();
JSONObject jsonObject = JSONObject.parseObject(response);
return jsonObject;
}
public JSONObject post(String url, JSONObject params){
String basicAuth = this.getBasicAuth();
String response = HttpRequest.post(url)
.body(params.toJSONString())
.header("Authorization", basicAuth)
.execute()
.body();
JSONObject jsonObject = JSONObject.parseObject(response);
return jsonObject;
}
public JSONObject delete(String url){
String basicAuth = this.getBasicAuth();
String response = HttpRequest.delete(url)
.header("Authorization", basicAuth)
.execute()
.body();
JSONObject jsonObject = JSONObject.parseObject(response);
return jsonObject;
}
/**
* cat 查询ElasticSearch系统数据,返回json
*/
public <T> ResponseEntity<T> _cat(String urlAfter, Class<T> responseType) {
String url = this.getBaseUrl().append("/_cat").append(urlAfter).append("?").append(FORMAT_JSON).toString();
return RestUtil.request(url, HttpMethod.GET, null, null, null, responseType);
}
/**
* 查询所有索引
* <p>
* 查询地址:GET http://{baseUrl}/_cat/indices
*/
public JSONArray getIndices() {
return getIndices(null);
}
/**
* 查询单个索引
* <p>
* 查询地址:GET http://{baseUrl}/_cat/indices/{indexName}
*/
public JSONArray getIndices(String indexName) {
StringBuilder urlAfter = new StringBuilder("/indices");
if (!StringUtils.isEmpty(indexName)) {
urlAfter.append("/").append(indexName.trim().toLowerCase());
}
return _cat(urlAfter.toString());
}
/**
* 索引是否存在
*/
public boolean indexExists(String indexName) {
try {
JSONArray array = getIndices(indexName);
return array != null;
} catch (org.springframework.web.client.HttpClientErrorException ex) {
if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
return false;
} else {
throw ex;
}
}
}
/**
* 根据ID获取索引数据,未查询到返回null
* <p>
* 查询地址:GET http://{baseUrl}/{indexName}/{typeName}/{dataId}
*
* @param indexName 索引名称
* @param typeName type,一个任意字符串,用于分类
* @param dataId 数据id
* @return
*/
public JSONObject getDataById(String indexName, String typeName, String dataId) {
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString();
log.info("url:" + url);
String basicAuth = this.getBasicAuth();
String response = HttpRequest.get(this.getBaseUrl().toString())
.header("Authorization", basicAuth)
.execute()
.body();
JSONObject result = JSONObject.parseObject(response);
boolean found = result.getBoolean("found");
if (found) {
return result.getJSONObject("_source");
} else {
return new JSONObject();
}
}
/**
* 创建索引
* <p>
* 查询地址:PUT http://{baseUrl}/{indexName}
*/
public boolean createIndex(String indexName) {
String url = this.getBaseUrl(indexName).toString();
try {
return this.put(url).getBoolean("acknowledged");
} catch (org.springframework.web.client.HttpClientErrorException ex) {
if (HttpStatus.BAD_REQUEST == ex.getStatusCode()) {
log.warn("索引创建失败:" + indexName + " 已存在,无需再创建");
} else {
ex.printStackTrace();
}
}
return false;
}
/**
* 删除索引
* <p>
* 查询地址:DELETE http://{baseUrl}/{indexName}
*/
public boolean removeIndex(String indexName) {
String url = this.getBaseUrl(indexName).toString();
try {
return this.delete(url).getBoolean("acknowledged");
} catch (org.springframework.web.client.HttpClientErrorException ex) {
if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
log.warn("索引删除失败:" + indexName + " 不存在,无需删除");
} else {
ex.printStackTrace();
}
}
return false;
}
/**
* 获取索引字段映射(可获取字段类型)
* <p>
*
* @param indexName 索引名称
* @param typeName 分类名称
* @return
*/
public JSONObject getIndexMapping(String indexName, String typeName) {
String url = this.getBaseUrl(indexName, typeName).append("/_mapping?").append(FORMAT_JSON).toString();
// 针对 es 7.x 版本做兼容
this.getElasticsearchVersion();
if (oConvertUtils.isNotEmpty(this.version) && this.version.startsWith("7")) {
url += "&include_type_name=true";
}
log.info("getIndexMapping-url:" + url);
try {
String basicAuth = this.getBasicAuth();
String response = HttpRequest.get(this.getBaseUrl().toString())
.header("Authorization", basicAuth)
.execute()
.body();
JSONObject result = JSONObject.parseObject(response);
return result;
} catch (org.springframework.web.client.HttpClientErrorException e) {
String message = e.getMessage();
if (message != null && message.contains("404 Not Found")) {
return new JSONObject();
}
throw e;
}
}
/**
* 获取索引字段映射,返回Java实体类
*
* @param indexName
* @param typeName
* @return
*/
public <T> Map<String, T> getIndexMappingFormat(String indexName, String typeName, Class<T> clazz) {
JSONObject mapping = this.getIndexMapping(indexName, typeName);
Map<String, T> map = new HashMap<>();
if (mapping == null) {
return map;
}
// 获取字段属性
JSONObject properties = mapping.getJSONObject(indexName)
.getJSONObject("mappings")
.getJSONObject(typeName)
.getJSONObject("properties");
// 封装成 java类型
for (String key : properties.keySet()) {
T entity = properties.getJSONObject(key).toJavaObject(clazz);
map.put(key, entity);
}
return map;
}
/**
* 保存数据,详见:saveOrUpdate
*/
public boolean save(String indexName, String typeName, String dataId, JSONObject data) {
return this.saveOrUpdate(indexName, typeName, dataId, data);
}
/**
* 更新数据,详见:saveOrUpdate
*/
public boolean update(String indexName, String typeName, String dataId, JSONObject data) {
return this.saveOrUpdate(indexName, typeName, dataId, data);
}
/**
* 保存或修改索引数据
* <p>
* 查询地址:PUT http://{baseUrl}/{indexName}/{typeName}/{dataId}
*
* @param indexName 索引名称
* @param typeName type,一个任意字符串,用于分类
* @param dataId 数据id
* @param data 要存储的数据
* @return
*/
public boolean saveOrUpdate(String indexName, String typeName, String dataId, JSONObject data) {
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).append("?refresh=wait_for").toString();
try {
// 去掉 data 中为空的值
Set<String> keys = data.keySet();
List<String> emptyKeys = new ArrayList<>(keys.size());
for (String key : keys) {
String value = data.getString(key);
//1、剔除空值
if (oConvertUtils.isEmpty(value) || "[]".equals(value)) {
emptyKeys.add(key);
}
//2、剔除上传控件值(会导致ES同步失败,报异常failed to parse field [ge_pic] of type [text] )
if (oConvertUtils.isNotEmpty(value) && value.indexOf("[{")!=-1) {
emptyKeys.add(key);
log.info("-------剔除上传控件字段------------key: "+ key);
}
}
for (String key : emptyKeys) {
data.remove(key);
}
} catch (Exception e) {
e.printStackTrace();
}
try {
String result = this.put(url, data.toJSONString()).getString("result");
return "created".equals(result) || "updated".equals(result);
} catch (Exception e) {
log.error(e.getMessage() + "\n-- url: " + url + "\n-- data: " + data.toJSONString());
//TODO 打印接口返回异常json
return false;
}
}
/**
* 批量保存数据
*
* @param indexName 索引名称
* @param typeName type,一个任意字符串,用于分类
* @param dataList 要存储的数据数组,每行数据必须包含id
* @return
*/
public boolean saveBatch(String indexName, String typeName, JSONArray dataList) {
String url = this.getBaseUrl().append("/_bulk").append("?refresh=wait_for").toString();
StringBuilder bodySB = new StringBuilder();
for (int i = 0; i < dataList.size(); i++) {
JSONObject data = dataList.getJSONObject(i);
String id = data.getString("id");
// 该行的操作
JSONObject action = new JSONObject();
JSONObject actionInfo = new JSONObject();
actionInfo.put("_id", id);
actionInfo.put("_index", indexName);
actionInfo.put("_type", typeName);
action.put("create", actionInfo);
bodySB.append(action.toJSONString()).append("\n");
// 该行的数据
data.remove("id");
bodySB.append(data.toJSONString()).append("\n");
}
log.info("+-+-+-: bodySB.toString(): " + bodySB.toString());
this.put(url,bodySB.toString());
return true;
}
/**
* 删除索引数据
* <p>
* 请求地址:DELETE http://{baseUrl}/{indexName}/{typeName}/{dataId}
*/
public boolean delete(String indexName, String typeName, String dataId) {
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString();
try {
return "deleted".equals(this.delete(url).getString("result"));
} catch (org.springframework.web.client.HttpClientErrorException ex) {
if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
return false;
} else {
throw ex;
}
}
}
/* = = = 以下关于查询和查询条件的方法 = = =*/
/**
* 查询数据
* <p>
* 请求地址:POST http://{baseUrl}/{indexName}/{typeName}/_search
*/
public JSONObject search(String indexName, String typeName, JSONObject queryObject) {
String url = this.getBaseUrl(indexName, typeName).append("/_search").toString();
log.info("url:" + url + " ,search: " + queryObject.toJSONString());
JSONObject res = this.get(url, queryObject);
log.info("url:" + url + " ,return res: \n" + res.toJSONString());
return res;
}
/**
* @param _source (源滤波器)指定返回的字段,传null返回所有字段
* @param query
* @param from 从第几条数据开始
* @param size 返回条目数
* @return { "query": query }
*/
public JSONObject buildQuery(List<String> _source, JSONObject query, int from, int size) {
JSONObject json = new JSONObject();
if (_source != null) {
json.put("_source", _source);
}
json.put("query", query);
json.put("from", from);
json.put("size", size);
return json;
}
public JSONObject buildQuery(List<String> _source, JSONObject query,Map<String, Object> highlight,JSONArray sort, int from, int size) {
JSONObject json = new JSONObject();
if (_source != null) {
json.put("_source", _source);
}
json.put("highlight", highlight);
json.put("query", query);
json.put("sort", sort);
json.put("from", from * size);
json.put("size", size);
return json;
}
/**
* @return { "bool" : { "must": must, "must_not": mustNot, "should": should } }
*/
public JSONObject buildBoolQuery(JSONArray must, JSONArray mustNot, JSONArray should) {
JSONObject bool = new JSONObject();
if (must != null) {
bool.put("must", must);
}
if (mustNot != null) {
bool.put("must_not", mustNot);
}
if (should != null) {
bool.put("should", should);
}
JSONObject json = new JSONObject();
json.put("bool", bool);
return json;
}
/**
* @param field 要查询的字段
* @param args 查询参数,参考: *哈哈* OR *哒* NOT *呵* OR *啊*
* @return
*/
public JSONObject buildQueryString(String field, String... args) {
if (field == null) {
return new JSONObject();
}
StringBuilder sb = new StringBuilder(field).append(":(");
if (args != null) {
for (String arg : args) {
sb.append(arg).append(" ");
}
}
sb.append(")");
return this.buildQueryString(sb.toString());
}
/**
* @return { "query_string": { "query": query } }
*/
public JSONObject buildQueryString(String query) {
JSONObject queryString = new JSONObject();
queryString.put("query", query);
JSONObject json = new JSONObject();
json.put("query_string", queryString);
return json;
}
/**
* @param field 查询字段
* @param min 最小值
* @param max 最大值
* @param containMin 范围内是否包含最小值
* @param containMax 范围内是否包含最大值
* @return { "range" : { field : { 『 "gt『e』?containMin" : min 』?min!=null , 『 "lt『e』?containMax" : max 』}} }
*/
public JSONObject buildRangeQuery(String field, Object min, Object max, boolean containMin, boolean containMax) {
JSONObject inner = new JSONObject();
if (min != null) {
if (containMin) {
inner.put("gte", min);
} else {
inner.put("gt", min);
}
}
if (max != null) {
if (containMax) {
inner.put("lte", max);
} else {
inner.put("lt", max);
}
}
JSONObject range = new JSONObject();
range.put(field, inner);
JSONObject json = new JSONObject();
json.put("range", range);
return json;
}
/**
* 按条件删除数据
* <p>
* 请求地址:POST http://{baseUrl}/{indexName}/{typeName}/_delete_by_query
*/
public JSONObject delete(String indexName, String typeName, JSONObject queryObject) {
String url = this.getBaseUrl(indexName, typeName).append("/_delete_by_query").toString();
log.info("url:" + url + " ,delete: " + queryObject.toJSONString());
JSONObject res = this.post(url, queryObject);
log.info("url:" + url + " ,return res: \n" + res.toJSONString());
return res;
}
}
@@ -0,0 +1,98 @@
package com.jero.common.es;
/**
* 用于创建 ElasticSearch 的 queryString
*
* @author sunjianlei
*/
public class QueryStringBuilder {
StringBuilder builder;
public QueryStringBuilder(String field, String str, boolean not, boolean addQuot) {
builder = this.createBuilder(field, str, not, addQuot);
}
public QueryStringBuilder(String field, String str, boolean not) {
builder = this.createBuilder(field, str, not, true);
}
/**
* 创建 StringBuilder
*
* @param field
* @param str
* @param not 是否是不匹配
* @param addQuot 是否添加双引号
* @return
*/
public StringBuilder createBuilder(String field, String str, boolean not, boolean addQuot) {
StringBuilder sb = new StringBuilder(field).append(":(");
if (not) {
sb.append(" NOT ");
}
this.addQuotEffect(sb, str, addQuot);
return sb;
}
public QueryStringBuilder and(String str) {
return this.and(str, true);
}
public QueryStringBuilder and(String str, boolean addQuot) {
builder.append(" AND ");
this.addQuot(str, addQuot);
return this;
}
public QueryStringBuilder or(String str) {
return this.or(str, true);
}
public QueryStringBuilder or(String str, boolean addQuot) {
builder.append(" OR ");
this.addQuot(str, addQuot);
return this;
}
public QueryStringBuilder not(String str) {
return this.not(str, true);
}
public QueryStringBuilder not(String str, boolean addQuot) {
builder.append(" NOT ");
this.addQuot(str, addQuot);
return this;
}
/**
* 添加双引号(模糊查询,不能加双引号)
*/
private QueryStringBuilder addQuot(String str, boolean addQuot) {
return this.addQuotEffect(this.builder, str, addQuot);
}
/**
* 是否在两边加上双引号
* @param builder
* @param str
* @param addQuot
* @return
*/
private QueryStringBuilder addQuotEffect(StringBuilder builder, String str, boolean addQuot) {
if (addQuot) {
builder.append('"');
}
builder.append(str);
if (addQuot) {
builder.append('"');
}
return this;
}
@Override
public String toString() {
return builder.append(")").toString();
}
}
@@ -0,0 +1,24 @@
package com.jero.common.exception;
import com.jero.common.util.MessageUtils;
public class JeroBootException extends RuntimeException {
private static final long serialVersionUID = 1L;
public JeroBootException(String message){
super(MessageUtils.getMessage(message));
}
public JeroBootException(String message, Object... args) {
super(MessageUtils.getMessage(message,args));
}
public JeroBootException(Throwable cause)
{
super(cause);
}
public JeroBootException(String message,Throwable cause)
{
super(message,cause);
}
}
@@ -0,0 +1,104 @@
package com.jero.common.exception;
import com.jero.common.api.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.connection.PoolException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.NoHandlerFoundException;
/**
* 异常处理器
*
* @Author scott
* @Date 2019
*/
@RestControllerAdvice
@Slf4j
public class JeroBootExceptionHandler {
/**
* 处理自定义异常
*/
@ExceptionHandler(JeroBootException.class)
public Result<T> handleJeroBootException(JeroBootException e){
log.error(e.getMessage(), e);
return Result.error(e.getMessage());
}
@ExceptionHandler(NoHandlerFoundException.class)
public Result<T> handlerNoFoundException(Exception e) {
log.error(e.getMessage(), e);
return Result.error(404, "路径不存在,请检查路径是否正确");
}
@ExceptionHandler(DuplicateKeyException.class)
public Result<T> handleDuplicateKeyException(DuplicateKeyException e){
log.error(e.getMessage(), e);
return Result.error("数据库中已存在该记录");
}
@ExceptionHandler({UnauthorizedException.class, AuthorizationException.class})
public Result<Object> handleAuthorizationException(AuthorizationException e){
log.error(e.getMessage(), e);
return Result.noauth("没有权限,请联系管理员授权");
}
@ExceptionHandler(Exception.class)
public Result<T> handleException(Exception e){
log.error(e.getMessage(), e);
return Result.error("操作失败,"+e.getMessage());
}
/**
* @Author 政辉
* @param e
* @return
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Result<T> httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e){
StringBuilder sb = new StringBuilder();
sb.append("不支持");
sb.append(e.getMethod());
sb.append("请求方法,");
sb.append("支持以下");
String [] methods = e.getSupportedMethods();
if(methods!=null){
for(String str:methods){
sb.append(str);
sb.append("");
}
}
log.error(sb.toString(), e);
return Result.error(405,sb.toString());
}
/**
* spring默认上传大小100MB 超出大小捕获异常MaxUploadSizeExceededException
*/
@ExceptionHandler(MaxUploadSizeExceededException.class)
public Result<T> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
log.error(e.getMessage(), e);
return Result.error("文件大小超出10MB限制, 请压缩或降低文件质量! ");
}
@ExceptionHandler(DataIntegrityViolationException.class)
public Result<T> handleDataIntegrityViolationException(DataIntegrityViolationException e) {
log.error(e.getMessage(), e);
return Result.error("字段太长,超出数据库字段的长度");
}
@ExceptionHandler(PoolException.class)
public Result<T> handlePoolException(PoolException e) {
log.error(e.getMessage(), e);
return Result.error("Redis 连接异常!");
}
}
@@ -0,0 +1,21 @@
package com.jero.common.handler;
import com.alibaba.fastjson.JSONObject;
/**
* 填值规则接口
*
* @author Yan_东
* 如需使用填值规则功能,规则实现类必须实现此接口
*/
public interface IFillRuleHandler {
/**
* @param params 页面配置固定参数
* @param formData 动态表单参数
* @return
*/
public Object execute(JSONObject params, JSONObject formData);
}
@@ -0,0 +1,221 @@
package com.jero.common.system.base.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 com.baomidou.mybatisplus.extension.service.IService;
import com.jero.common.api.vo.Result;
import com.jero.common.system.query.QueryGenerator;
import com.jero.common.system.vo.LoginUser;
import com.jero.common.util.oConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
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.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: Controller基类
* @Author: dangzhenghui@163.com
* @Date: 2019-4-21 8:13
* @Version: 1.0
*/
@Slf4j
public class JeroController<T, S extends IService<T>> {
public static final String CLASS = "entity";
public static final String PARAMS = "params";
public static final String FILE_NAME = "fileName";
@Autowired
S service;
@Value("${jero.path.upload}")
private String upLoadPath;
/**
* 导出excel
*
* @param request
*/
protected ModelAndView exportXls(HttpServletRequest request, T object, Class<T> clazz, String title) {
// Step.1 组装查询条件
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
// Step.2 获取导出数据
List<T> pageList = service.list(queryWrapper);
List<T> exportList = null;
// 过滤选中数据
String selections = request.getParameter("selections");
if (oConvertUtils.isNotEmpty(selections)) {
List<String> selectionList = Arrays.asList(selections.split(","));
exportList = pageList.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
} else {
exportList = pageList;
}
// Step.3 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
mv.addObject(FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
mv.addObject(CLASS, clazz);
//update-begin--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置--------------------
ExportParams exportParams=new ExportParams(title, "导出人:" + sysUser.getRealname(), title);
exportParams.setImageBasePath(upLoadPath);
//update-end--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置----------------------
mv.addObject(PARAMS,exportParams);
mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
return mv;
}
/**
* 导出excel
*
* @param
*/
protected ModelAndView exportListXls(List<?> object, Class<?> clazz, String title) {
// Step.3 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
//此处设置的filename无效 ,前端会重更新设置一下
mv.addObject(NormalExcelConstants.FILE_NAME, title);
mv.addObject(NormalExcelConstants.CLASS, clazz);
ExportParams exportParams=new ExportParams(title, title);
// 导出xlsx
exportParams.setType(ExcelType.XSSF);
exportParams.setImageBasePath(upLoadPath);
mv.addObject(NormalExcelConstants.PARAMS,exportParams);
mv.addObject(NormalExcelConstants.DATA_LIST, object);
return mv;
}
/**
* 根据每页sheet数量导出多sheet
*
* @param request
* @param object 实体类
* @param clazz 实体类class
* @param title 标题
* @param exportFields 导出字段自定义
* @param pageNum 每个sheet的数据条数
* @param request
*/
protected ModelAndView exportXlsSheet(HttpServletRequest request, T object, Class<T> clazz, String title,String exportFields,Integer pageNum) {
// Step.1 组装查询条件
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
// Step.2 计算分页sheet数据
double total = service.count();
int count = (int)Math.ceil(total/pageNum);
// Step.3 多sheet处理
List<Map<String, Object>> listMap = new ArrayList<>();
for (int i = 1; i <=count ; i++) {
Page<T> page = new Page<>(i, pageNum);
IPage<T> pageList = service.page(page, queryWrapper);
List<T> records = pageList.getRecords();
List<T> exportList = null;
// 过滤选中数据
String selections = request.getParameter("selections");
if (oConvertUtils.isNotEmpty(selections)) {
List<String> selectionList = Arrays.asList(selections.split(","));
exportList = records.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
} else {
exportList = records;
}
Map<String, Object> map = new HashMap<>();
ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title+i,upLoadPath);
exportParams.setType(ExcelType.XSSF);
//map.put("title",exportParams);//表格Title
map.put(PARAMS,exportParams);//表格Title
map.put(CLASS,clazz);//表格对应实体
map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
listMap.add(map);
}
// Step.4 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
mv.addObject(FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
mv.addObject(NormalExcelConstants.MAP_LIST, listMap);
return mv;
}
/**
* 根据权限导出excel,传入导出字段参数
*
* @param request
*/
protected ModelAndView exportXls(HttpServletRequest request, T object, Class<T> clazz, String title,String exportFields) {
ModelAndView mv = this.exportXls(request,object,clazz,title);
mv.addObject(NormalExcelConstants.EXPORT_FIELDS,exportFields);
return mv;
}
/**
* 获取对象ID
*
* @return
*/
private String getId(T item) {
try {
return PropertyUtils.getProperty(item, "id").toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 通过excel导入数据
*
* @param request
* @return
*/
protected Result<T> importExcel(HttpServletRequest request, HttpServletResponse response, Class<T> clazz) {
if(Objects.isNull(response)){
log.info("打印未使用参数");
}
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<T> list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params);
//update-begin-author:taoyan date:20190528 for:批量插入数据
long start = System.currentTimeMillis();
service.saveBatch(list);
//400条 saveBatch消耗时间1592毫秒 循环插入消耗时间1947毫秒
//1200条 saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
//update-end-author:taoyan date:20190528 for:批量插入数据
return Result.OK("文件导入成功!数据行数:" + list.size());
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error("文件导入失败:" + e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return Result.error("文件导入失败!");
}
}
@@ -0,0 +1,52 @@
package com.jero.common.system.base.entity;
import java.io.Serializable;
import org.jeecgframework.poi.excel.annotation.Excel;
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 io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @Description: Entity基类
* @Author: dangzhenghui@163.com
* @Date: 2019-4-28
* @Version: 1.1
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class JeroEntity implements Serializable {
private static final long serialVersionUID = 1L;
/** ID */
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "ID")
private java.lang.String id;
/** 创建人 */
@ApiModelProperty(value = "创建人")
@Excel(name = "创建人", width = 15)
private java.lang.String createBy;
/** 创建时间 */
@ApiModelProperty(value = "创建时间")
@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 createTime;
/** 更新人 */
@ApiModelProperty(value = "更新人")
@Excel(name = "更新人", width = 15)
private java.lang.String updateBy;
/** 更新时间 */
@ApiModelProperty(value = "更新时间")
@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 updateTime;
}
@@ -0,0 +1,12 @@
package com.jero.common.system.base.service;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: Service基类
* @Author: dangzhenghui@163.com
* @Date: 2019-4-21 8:13
* @Version: 1.0
*/
public interface JeroService<T> extends IService<T> {
}
@@ -0,0 +1,19 @@
package com.jero.common.system.base.service.impl;
import com.jero.common.system.base.entity.JeroEntity;
import com.jero.common.system.base.service.JeroService;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
/**
* @Description: ServiceImpl基类
* @Author: dangzhenghui@163.com
* @Date: 2019-4-21 8:13
* @Version: 1.0
*/
@Slf4j
public class JeroServiceImpl<M extends BaseMapper<T>, T extends JeroEntity> extends ServiceImpl<M, T> implements JeroService<T> {
}
@@ -0,0 +1,43 @@
package com.jero.common.system.query;
import com.jero.common.util.oConvertUtils;
/**
* 查询链接规则
*
* @Author Sunjianlei
*/
public enum MatchTypeEnum {
AND("AND"),
OR("OR");
private String value;
MatchTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static MatchTypeEnum getByValue(Object value) {
if (oConvertUtils.isEmpty(value)) {
return null;
}
return getByValue(value.toString());
}
public static MatchTypeEnum getByValue(String value) {
if (oConvertUtils.isEmpty(value)) {
return null;
}
for (MatchTypeEnum val : values()) {
if (val.getValue().equalsIgnoreCase(value)) {
return val;
}
}
return null;
}
}
@@ -0,0 +1,69 @@
package com.jero.common.system.query;
import java.io.Serializable;
public class QueryCondition implements Serializable {
private static final long serialVersionUID = 4740166316629191651L;
private String field;
/** 组件的类型(例如:input、select、radio */
private String type;
/**
* 对应的数据库字段的类型
* 支持:int、bigDecimal、short、long、float、double、boolean
*/
private String dbType;
private String rule;
private String val;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public String getRule() {
return rule;
}
public void setRule(String rule) {
this.rule = rule;
}
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
@Override
public String toString(){
StringBuilder sb =new StringBuilder();
if(field == null || "".equals(field)){
return "";
}
sb.append(this.field).append(" ").append(this.rule).append(" ").append(this.type).append(" ").append(this.dbType).append(" ").append(this.val);
return sb.toString();
}
}
@@ -0,0 +1,73 @@
package com.jero.common.system.query;
import com.jero.common.util.oConvertUtils;
/**
* Query 规则 常量
* @Author Scott
* @Date 2019年02月14日
*/
public enum QueryRuleEnum {
GT(">","gt","大于"),
GE(">=","ge","大于等于"),
LT("<","lt","小于"),
LE("<=","le","小于等于"),
EQ("=","eq","等于"),
NE("!=","ne","不等于"),
IN("IN","in","包含"),
LIKE("LIKE","like","全模糊"),
LEFT_LIKE("LEFT_LIKE","left_like","左模糊"),
RIGHT_LIKE("RIGHT_LIKE","right_like","右模糊"),
EQ_WITH_ADD("EQWITHADD","eq_with_add","带加号等于"),
LIKE_WITH_AND("LIKEWITHAND","like_with_and","多词模糊匹配————暂时未用上"),
SQL_RULES("USE_SQL_RULES","ext","自定义SQL片段");
private String value;
private String condition;
private String msg;
QueryRuleEnum(String value, String condition, String msg){
this.value = value;
this.condition = condition;
this.msg = msg;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public static QueryRuleEnum getByValue(String value){
if(oConvertUtils.isEmpty(value)) {
return null;
}
for(QueryRuleEnum val :values()){
if (val.getValue().equals(value) || val.getCondition().equals(value)){
return val;
}
}
return null;
}
}
@@ -0,0 +1,108 @@
package com.jero.common.system.util;
import com.jero.common.system.vo.SysPermissionDataRuleModel;
import com.jero.common.system.vo.SysUserCacheInfo;
import com.jero.common.util.SpringContextUtils;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: JeroDataAutorUtils
* @Description: 数据权限查询规则容器工具类
* @Author: 张代浩
* @Date: 2012-12-15 下午11:27:39
*
*/
public class JeroDataAutorUtils {
private JeroDataAutorUtils(){
}
public static final String MENU_DATA_AUTHOR_RULES = "MENU_DATA_AUTHOR_RULES";
public static final String MENU_DATA_AUTHOR_RULE_SQL = "MENU_DATA_AUTHOR_RULE_SQL";
public static final String SYS_USER_INFO = "SYS_USER_INFO";
/**
* 往链接请求里面,传入数据查询条件
*
* @param request
* @param dataRules
*/
public static synchronized void installDataSearchConditon(HttpServletRequest request, List<SysPermissionDataRuleModel> dataRules) {
@SuppressWarnings("unchecked")
List<SysPermissionDataRuleModel> list = loadDataSearchConditon();// 1.先从request获取MENU_DATA_AUTHOR_RULES,如果存则获取到LIST
if (list==null) {
// 2.如果不存在,则new一个list
list = new ArrayList<>();
}
for (SysPermissionDataRuleModel tsDataRule : dataRules) {
list.add(tsDataRule);
}
request.setAttribute(MENU_DATA_AUTHOR_RULES, list); // 3.往list里面增量存指
}
/**
* 获取请求对应的数据权限规则
*
* @return
*/
@SuppressWarnings("unchecked")
public static synchronized List<SysPermissionDataRuleModel> loadDataSearchConditon() {
return (List<SysPermissionDataRuleModel>) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULES);
}
/**
* 获取请求对应的数据权限SQL
*
* @return
*/
public static synchronized String loadDataSearchConditonSQLString() {
return (String) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULE_SQL);
}
/**
* 往链接请求里面,传入数据查询条件
*
* @param request
* @param sql
*/
public static synchronized void installDataSearchConditon(HttpServletRequest request, String sql) {
String ruleSql = loadDataSearchConditonSQLString();
if (!StringUtils.hasText(ruleSql)) {
request.setAttribute(MENU_DATA_AUTHOR_RULE_SQL,sql);
}
}
/**
* 将用户信息存到request
* @param request
* @param userinfo
*/
public static synchronized void installUserInfo(HttpServletRequest request, SysUserCacheInfo userinfo) {
request.setAttribute(SYS_USER_INFO, userinfo);
}
/**
* 将用户信息存到request
* @param userinfo
*/
public static synchronized void installUserInfo(SysUserCacheInfo userinfo) {
SpringContextUtils.getHttpServletRequest().setAttribute(SYS_USER_INFO, userinfo);
}
/**
* 从request获取用户信息
* @return
*/
public static synchronized SysUserCacheInfo loadUserInfo() {
return (SysUserCacheInfo) SpringContextUtils.getHttpServletRequest().getAttribute(SYS_USER_INFO);
}
}
@@ -0,0 +1,257 @@
package com.jero.common.system.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.common.base.Joiner;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.jero.common.constant.CommonConstant;
import org.apache.shiro.SecurityUtils;
import com.jero.common.constant.DataBaseConstant;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.vo.LoginUser;
import com.jero.common.system.vo.SysUserCacheInfo;
import com.jero.common.util.DateUtils;
import com.jero.common.util.SpringContextUtils;
import com.jero.common.util.oConvertUtils;
/**
* @Author Scott
* @Date 2018-07-12 14:23
* @Desc JWT工具类
**/
public class JwtUtil {
private JwtUtil(){
}
// Token过期时间30分钟(用户登录过期时间也是30分钟,以token在reids缓存时间为准)
//public static final long EXPIRE_TIME = 180 * 60 * 1000L;
public static final long EXPIRE_TIME = 24 * 60 * 60 * 1000L; // 设置成1天(开发用)
private static final String USERNAME_FIELD = "username";
/**
* 校验token是否正确
*
* @param token 密钥
* @param secret 用户的密码
* @return 是否正确
*/
public static boolean verify(String token, String username, String secret) {
try {
// 根据密码生成JWT效验器
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm).withClaim(USERNAME_FIELD, username).build();
// 效验TOKEN
verifier.verify(token);
return true;
} catch (Exception exception) {
return false;
}
}
/**
* 获得token中的信息无需secret解密也能获得
*
* @return token中包含的用户名
*/
public static String getUsername(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim(USERNAME_FIELD).asString();
} catch (JWTDecodeException e) {
return null;
}
}
/**
* 生成签名,5min后过期
*
* @param username 用户名
* @param secret 用户的密码
* @return 加密的token
*/
public static String sign(String username, String secret) {
// 24小时后过期
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret);
// 附带username信息
return JWT.create().withClaim(USERNAME_FIELD, username).withExpiresAt(date).sign(algorithm);
}
/**
* 根据request中的token获取用户账号
*
* @param request
* @return
* @throws JeroBootException
*/
public static String getUserNameByToken(HttpServletRequest request) throws JeroBootException {
String accessToken = request.getHeader("X-Access-Token");
String username = getUsername(accessToken);
if (oConvertUtils.isEmpty(username)) {
throw new JeroBootException("未获取到用户");
}
return username;
}
/**
* 从session中获取变量
* @param key
* @return
*/
public static String getSessionData(String key) {
//${myVar}%
//得到${} 后面的值
String moshi = "";
if(key.indexOf("}")!=-1){
moshi = key.substring(key.indexOf("}")+1);
}
String returnValue = null;
if (key.contains("#{")) {
key = key.substring(2,key.indexOf("}"));
}
if (oConvertUtils.isNotEmpty(key)) {
HttpSession session = SpringContextUtils.getHttpServletRequest().getSession();
returnValue = (String) session.getAttribute(key);
}
//结果加上${} 后面的值
if(returnValue!=null){returnValue = returnValue + moshi;}
return returnValue;
}
/**
* 从当前用户中获取变量
* @param key
* @param user
* @return
*/
// TODO 急待改造 sckjkdsjsfjdk
public static String getUserSystemData(String key,SysUserCacheInfo user) {
if(user==null) {
user = JeroDataAutorUtils.loadUserInfo();
}
//#{sys_user_code}%
// 获取登录用户信息
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String moshi = "";
if(key.contains("}")){
moshi = key.substring(key.indexOf("}")+1);
}
String returnValue = null;
//针对特殊标示处理#{sysOrgCode},判断替换
if (key.contains("#{")) {
key = key.substring(2,key.indexOf("}"));
}
returnValue = setReturnValue(key, user, sysUser, returnValue);
//update-end-author:taoyan date:20210330 for:多租户ID作为系统变量
if(returnValue!=null){returnValue = returnValue + moshi;}
return returnValue;
}
private static String setReturnValue(String key, SysUserCacheInfo user, LoginUser sysUser, String returnValue) {
//替换为系统登录用户帐号
if (isaBoolean(key, DataBaseConstant.SYS_USER_CODE, DataBaseConstant.SYS_USER_CODE_TABLE)) {
returnValue = setReturnValueUsername(user, sysUser);
}
//替换为系统登录用户真实名字
else if (isaBoolean(key, DataBaseConstant.SYS_USER_NAME, DataBaseConstant.SYS_USER_NAME_TABLE)) {
returnValue = setReturnValueRealName(user, sysUser);
}
//替换为系统用户登录所使用的机构编码
else if (isaBoolean(key, DataBaseConstant.SYS_ORG_CODE, DataBaseConstant.SYS_ORG_CODE_TABLE)) {
returnValue = setReturnValueOrgCode(user, sysUser);
}
//替换为系统用户所拥有的所有机构编码
else if (isaBoolean(key, DataBaseConstant.SYS_MULTI_ORG_CODE, DataBaseConstant.SYS_MULTI_ORG_CODE_TABLE)) {
returnValue = setReturnValueOrgCodeNew(user, sysUser);
}
//替换为当前系统时间(年月日)
else if (isaBoolean(key, DataBaseConstant.SYS_DATE, DataBaseConstant.SYS_DATE_TABLE)) {
returnValue = DateUtils.formatDate();
}
//替换为当前系统时间(年月日时分秒)
else if (isaBoolean(key, DataBaseConstant.SYS_TIME, DataBaseConstant.SYS_TIME_TABLE)) {
returnValue = DateUtils.now();
}
//流程状态默认值(默认未发起)
else if (isaBoolean(key, DataBaseConstant.BPM_STATUS, DataBaseConstant.BPM_STATUS_TABLE)) {
returnValue = "1";
}
//update-begin-author:taoyan date:20210330 for:多租户ID作为系统变量
else if (isaBoolean(key, DataBaseConstant.TENANT_ID, DataBaseConstant.TENANT_ID_TABLE)){
returnValue = sysUser.getRelTenantIds();
returnValue = setReturnValueTenantId(returnValue);
}
return returnValue;
}
private static boolean isaBoolean(String key, String sysUserCode, String sysUserCodeTable) {
return key.equals(sysUserCode) || key.equalsIgnoreCase(sysUserCodeTable);
}
private static String setReturnValueTenantId(String returnValue) {
if(oConvertUtils.isEmpty(returnValue) || returnValue.contains(",")){
returnValue = SpringContextUtils.getHttpServletRequest().getHeader(CommonConstant.TENANT_ID);
}
return returnValue;
}
private static String setReturnValueOrgCodeNew(SysUserCacheInfo user, LoginUser sysUser) {
String returnValue;
if(user==null){
// TODO 暂时使用用户登录部门,存在逻辑缺陷,不是用户所拥有的部门
returnValue = sysUser.getOrgCode();
}else{
if(user.isOneDepart()) {
returnValue = user.getSysMultiOrgCode().get(0);
}else {
returnValue = Joiner.on(",").join(user.getSysMultiOrgCode());
}
}
return returnValue;
}
private static String setReturnValueOrgCode(SysUserCacheInfo user, LoginUser sysUser) {
String returnValue;
if(user==null) {
returnValue = sysUser.getOrgCode();
}else {
returnValue = user.getSysOrgCode();
}
return returnValue;
}
private static String setReturnValueRealName(SysUserCacheInfo user, LoginUser sysUser) {
String returnValue;
if(user==null) {
returnValue = sysUser.getRealname();
}else {
returnValue = user.getSysUserName();
}
return returnValue;
}
private static String setReturnValueUsername(SysUserCacheInfo user, LoginUser sysUser) {
String returnValue;
if(user==null) {
returnValue = sysUser.getUsername();
}else {
returnValue = user.getSysUserCode();
}
return returnValue;
}
}
@@ -0,0 +1,36 @@
package com.jero.common.system.vo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ComboModel implements Serializable {
private String id;
private String title;
/**文档管理 表单table默认选中*/
private boolean checked;
/**文档管理 表单table 用户账号*/
private String username;
/**文档管理 表单table 用户邮箱*/
private String email;
/**文档管理 表单table 角色编码*/
private String roleCode;
public ComboModel(){
}
public ComboModel(String id,String title,boolean checked,String username){
this.id = id;
this.title = title;
this.checked = checked;
this.username = username;
}
}
@@ -0,0 +1,43 @@
package com.jero.common.system.vo;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
public class DictModel implements Serializable{
private static final long serialVersionUID = 1L;
public DictModel() {
}
public DictModel(String value, String text) {
this.value = value;
this.text = text;
}
/**
* 字典value
*/
private String value;
/**
* 字典文本
*/
private String text;
/**
* 特殊用途: JgEditableTable
* @return
*/
public String getTitle() {
return this.text;
}
}
@@ -0,0 +1,18 @@
package com.jero.common.system.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 查询多个字典时用到
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class DictModelMany extends DictModel {
/**
* 字典code,根据多个字段code查询时才用到,用于区分不同的字典选项
*/
private String dictCode;
}
@@ -0,0 +1,34 @@
package com.jero.common.system.vo;
import lombok.Data;
/**
* 字典查询参数实体
*/
@Data
public class DictQuery {
/**
* 表名
*/
private String table;
/**
* 存储列
*/
private String code;
/**
* 显示列
*/
private String text;
/**
* 关键字查询
*/
private String keyword;
/**
* 存储列的值 用于回显查询
*/
private String codeValue;
}
@@ -0,0 +1,48 @@
package com.jero.common.system.vo;
import lombok.Data;
import org.springframework.beans.BeanUtils;
@Data
public class DynamicDataSourceModel {
public DynamicDataSourceModel() {
}
public DynamicDataSourceModel(Object dbSource) {
if (dbSource != null) {
BeanUtils.copyProperties(dbSource, this);
}
}
/**
* id
*/
private java.lang.String id;
/**
* 数据源编码
*/
private java.lang.String code;
/**
* 数据库类型
*/
private java.lang.String dbType;
/**
* 驱动类
*/
private java.lang.String dbDriver;
/**
* 数据源地址
*/
private java.lang.String dbUrl;
/**
* 用户名
*/
private java.lang.String dbUsername;
/**
* 密码
*/
private java.lang.String dbPassword;
}
@@ -0,0 +1,125 @@
package com.jero.common.system.vo;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 在线用户信息
* </p>
*
* @Author scott
* @since 2018-12-20
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class LoginUser {
/**
* 登录人id
*/
private String id;
/**
* 登录人账号
*/
private String username;
/**
* 登录人名字
*/
private String realname;
/**
* 登录人密码
*/
private String password;
/**
* 当前登录部门code
*/
private String orgCode;
/**
* 头像
*/
private String avatar;
/**
* 生日
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
/**
* 性别(1:男 2:女)
*/
private Integer sex;
/**
* 电子邮件
*/
private String email;
/**
* 电话
*/
private String phone;
/**
* 状态(1:正常 2:冻结
*/
private Integer status;
private Integer delFlag;
/**
* 同步工作流引擎1同步0不同步
*/
private Integer activitiSync;
/**
* 创建时间
*/
private Date createTime;
/**
* 身份(1 普通员工 2 上级)
*/
private Integer userIdentity;
/**
* 管理部门ids
*/
private String departIds;
/**
* 职务,关联职务表
*/
private String post;
/**
* 座机号
*/
private String telephone;
/**多租户id配置,编辑用户的时候设置*/
private String relTenantIds;
/**设备id uniapp推送用*/
private String clientId;
private String roleIds;
public String calcNameWorkNo(){
return this.realname + "(" + this.username + ")";
}
}
@@ -0,0 +1,50 @@
package com.jero.common.system.vo;
/**
* @Author qinfeng
* @Date 2020/2/19 12:01
* @Description:
* @Version 1.0
*/
public class SysCategoryModel {
/**主键*/
private java.lang.String id;
/**父级节点*/
private java.lang.String pid;
/**类型名称*/
private java.lang.String name;
/**类型编码*/
private java.lang.String code;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
@@ -0,0 +1,147 @@
package com.jero.common.system.vo;
/**
* lvdandan 部门机构model
*/
public class SysDepartModel {
/**ID*/
private String id;
/**父机构ID*/
private String parentId;
/**机构/部门名称*/
private String departName;
/**英文名*/
private String departNameEn;
/**缩写*/
private String departNameAbbr;
/**排序*/
private Integer departOrder;
/**描述*/
private String description;
/**机构类别 1组织机构,2岗位*/
private String orgCategory;
/**机构类型*/
private String orgType;
/**机构编码*/
private String orgCode;
/**手机号*/
private String mobile;
/**传真*/
private String fax;
/**地址*/
private String address;
/**备注*/
private String memo;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getDepartName() {
return departName;
}
public void setDepartName(String departName) {
this.departName = departName;
}
public String getDepartNameEn() {
return departNameEn;
}
public void setDepartNameEn(String departNameEn) {
this.departNameEn = departNameEn;
}
public String getDepartNameAbbr() {
return departNameAbbr;
}
public void setDepartNameAbbr(String departNameAbbr) {
this.departNameAbbr = departNameAbbr;
}
public Integer getDepartOrder() {
return departOrder;
}
public void setDepartOrder(Integer departOrder) {
this.departOrder = departOrder;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getOrgCategory() {
return orgCategory;
}
public void setOrgCategory(String orgCategory) {
this.orgCategory = orgCategory;
}
public String getOrgType() {
return orgType;
}
public void setOrgType(String orgType) {
this.orgType = orgType;
}
public String getOrgCode() {
return orgCode;
}
public void setOrgCode(String orgCode) {
this.orgCode = orgCode;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getFax() {
return fax;
}
public void setFax(String fax) {
this.fax = fax;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
}
@@ -0,0 +1,388 @@
package com.jero.common.system.vo;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* <p>
* 部门表 存储树结构数据的实体类
* <p>
*
* @Author Steve
* @Since 2019-01-22
*/
public class SysDepartTreeModel implements Serializable{
private static final long serialVersionUID = 1L;
/** 对应SysDepart中的id字段,前端数据树中的key*/
private String key;
/** 对应SysDepart中的id字段,前端数据树中的value*/
private String value;
/** 对应depart_name字段,前端数据树中的title*/
private String title;
private boolean isLeaf;
// 以下所有字段均与SysDepart相同
private String id;
private String parentId;
private String departName;
private String departNameEn;
private String departNameAbbr;
private Integer departOrder;
private String description;
private String orgCategory;
private String orgType;
private String orgCode;
private String mobile;
private String fax;
private String address;
private String memo;
private String status;
private String delFlag;
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
private String company;
private String headOfDepartment;
private String leadersInCharge;
private String deputyLeader;
private List<SysDepartTreeModel> children = new ArrayList<>();
public boolean getIsLeaf() {
return isLeaf;
}
public void setIsLeaf(boolean isleaf) {
this.isLeaf = isleaf;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<SysDepartTreeModel> getChildren() {
return children;
}
public void setChildren(List<SysDepartTreeModel> children) {
if (children==null){
this.isLeaf=true;
}
this.children = children;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getDepartName() {
return departName;
}
public void setDepartName(String departName) {
this.departName = departName;
}
public String getOrgCategory() {
return orgCategory;
}
public void setOrgCategory(String orgCategory) {
this.orgCategory = orgCategory;
}
public String getOrgType() {
return orgType;
}
public void setOrgType(String orgType) {
this.orgType = orgType;
}
public String getOrgCode() {
return orgCode;
}
public void setOrgCode(String orgCode) {
this.orgCode = orgCode;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getFax() {
return fax;
}
public void setFax(String fax) {
this.fax = fax;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
public String getDepartNameEn() {
return departNameEn;
}
public void setDepartNameEn(String departNameEn) {
this.departNameEn = departNameEn;
}
public String getDepartNameAbbr() {
return departNameAbbr;
}
public void setDepartNameAbbr(String departNameAbbr) {
this.departNameAbbr = departNameAbbr;
}
public Integer getDepartOrder() {
return departOrder;
}
public void setDepartOrder(Integer departOrder) {
this.departOrder = departOrder;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getHeadOfDepartment() {
return headOfDepartment;
}
public void setHeadOfDepartment(String headOfDepartment) {
this.headOfDepartment = headOfDepartment;
}
public String getLeadersInCharge() {
return leadersInCharge;
}
public void setLeadersInCharge(String leadersInCharge) {
this.leadersInCharge = leadersInCharge;
}
public String getDeputyLeader() {
return deputyLeader;
}
public void setDeputyLeader(String deputyLeader) {
this.deputyLeader = deputyLeader;
}
public SysDepartTreeModel() {
// do other
}
/**
* 重写equals方法
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SysDepartTreeModel model = (SysDepartTreeModel) o;
return Objects.equals(id, model.id) &&
Objects.equals(parentId, model.parentId) &&
Objects.equals(departName, model.departName) &&
Objects.equals(departNameEn, model.departNameEn) &&
Objects.equals(departNameAbbr, model.departNameAbbr) &&
Objects.equals(departOrder, model.departOrder) &&
Objects.equals(description, model.description) &&
Objects.equals(orgCategory, model.orgCategory) &&
Objects.equals(orgType, model.orgType) &&
Objects.equals(orgCode, model.orgCode) &&
Objects.equals(mobile, model.mobile) &&
Objects.equals(fax, model.fax) &&
Objects.equals(address, model.address) &&
Objects.equals(memo, model.memo) &&
Objects.equals(status, model.status) &&
Objects.equals(delFlag, model.delFlag) &&
Objects.equals(createBy, model.createBy) &&
Objects.equals(createTime, model.createTime) &&
Objects.equals(updateBy, model.updateBy) &&
Objects.equals(updateTime, model.updateTime) &&
Objects.equals(company, model.company)&&
Objects.equals(headOfDepartment, model.headOfDepartment)&&
Objects.equals(leadersInCharge, model.leadersInCharge)&&
Objects.equals(deputyLeader, model.deputyLeader)&&
Objects.equals(children, model.children);
}
/**
* 重写hashCode方法
*/
@Override
public int hashCode() {
return Objects.hash(id, parentId, departName, departNameEn, departNameAbbr,
departOrder, description, orgCategory, orgType, orgCode, mobile, fax, address,
memo, status, delFlag, createBy, createTime, updateBy, updateTime,
headOfDepartment, leadersInCharge, deputyLeader, children);
}
}
@@ -0,0 +1,80 @@
package com.jero.common.system.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.jero.common.aspect.annotation.Dict;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class SysDictItemCore implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.ASSIGN_ID)
private String id;
/**
* 字典id
*/
private String dictId;
/**
* 字典编码
*/
@TableField(exist = false)
private String dictCode;
/**
* 字典项文本
*/
@Excel(name = "字典项文本", width = 20)
private String itemText;
/**
* 字典项值
*/
@Excel(name = "字典项值", width = 30)
private String itemValue;
/**
* 描述
*/
@Excel(name = "描述", width = 40)
private String description;
/**
* 排序
*/
@Excel(name = "排序", width = 15,type=4)
private Integer sortOrder;
/**
* 状态(1启用 0不启用)
*/
@Dict(dicCode = "dict_item_status")
private Integer status;
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
}
@@ -0,0 +1,144 @@
package com.jero.common.system.vo;
import java.util.Date;
/**
* <p>
* 菜单权限规则表
* </p>
*
* @Author huangzhilin
* @since 2019-03-29
*/
public class SysPermissionDataRuleModel {
/**
* id
*/
private String id;
/**
* 对应的菜单id
*/
private String permissionId;
/**
* 规则名称
*/
private String ruleName;
/**
* 字段
*/
private String ruleColumn;
/**
* 条件
*/
private String ruleConditions;
/**
* 规则值
*/
private String ruleValue;
/**
* 创建时间
*/
private Date createTime;
/**
* 创建人
*/
private String createBy;
/**
* 修改时间
*/
private Date updateTime;
/**
* 修改人
*/
private String updateBy;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPermissionId() {
return permissionId;
}
public void setPermissionId(String permissionId) {
this.permissionId = permissionId;
}
public String getRuleName() {
return ruleName;
}
public void setRuleName(String ruleName) {
this.ruleName = ruleName;
}
public String getRuleColumn() {
return ruleColumn;
}
public void setRuleColumn(String ruleColumn) {
this.ruleColumn = ruleColumn;
}
public String getRuleConditions() {
return ruleConditions;
}
public void setRuleConditions(String ruleConditions) {
this.ruleConditions = ruleConditions;
}
public String getRuleValue() {
return ruleValue;
}
public void setRuleValue(String ruleValue) {
this.ruleValue = ruleValue;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
}
@@ -0,0 +1,67 @@
package com.jero.common.system.vo;
import java.util.List;
import com.jero.common.util.DateUtils;
public class SysUserCacheInfo {
private String sysUserCode;
private String sysUserName;
private String sysOrgCode;
private List<String> sysMultiOrgCode;
private boolean oneDepart;
public boolean isOneDepart() {
return oneDepart;
}
public void setOneDepart(boolean oneDepart) {
this.oneDepart = oneDepart;
}
public String getSysDate() {
return DateUtils.formatDate();
}
public String getSysTime() {
return DateUtils.now();
}
public String getSysUserCode() {
return sysUserCode;
}
public void setSysUserCode(String sysUserCode) {
this.sysUserCode = sysUserCode;
}
public String getSysUserName() {
return sysUserName;
}
public void setSysUserName(String sysUserName) {
this.sysUserName = sysUserName;
}
public String getSysOrgCode() {
return sysOrgCode;
}
public void setSysOrgCode(String sysOrgCode) {
this.sysOrgCode = sysOrgCode;
}
public List<String> getSysMultiOrgCode() {
return sysMultiOrgCode;
}
public void setSysMultiOrgCode(List<String> sysMultiOrgCode) {
this.sysMultiOrgCode = sysMultiOrgCode;
}
}
@@ -0,0 +1,33 @@
package com.jero.common.util;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.stream.Collectors;
public class BeanCopyUtils {
private BeanCopyUtils() {
}
/** 1、单个对象*/
public static <V> V copyBean(Object source, Class<V> clazz) {
/** 创建目标对象 实现属性拷贝*/
V result = null;
try {
result = clazz.newInstance();
/** 拷贝*/
BeanUtils.copyProperties(source, result);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/** 2、集合*/
public static <O, V> List<V> copyBeanList(List<O> list, Class<V> clazz) {
/** 创建目标对象 实现属性拷贝*/
return list.stream()
.map(o -> copyBean(o, clazz))
.collect(Collectors.toList());
}
}
@@ -0,0 +1,10 @@
package com.jero.common.util;
/**
*
* @Author 张代浩
*
*/
public enum BrowserType {
IE11,IE10,IE9,IE8,IE7,IE6,FIREFOX,SAFARI,CHROME,OPERA,CAMINO,GECKO
}
@@ -0,0 +1,213 @@
package com.jero.common.util;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
/**
*
* @Author 张代浩
*
*/
public class BrowserUtils {
private BrowserUtils(){
}
private static final String USER_AGENT = "USER-AGENT";
private static final String RV_11 = "rv:11.0";
// 判断是否是IE
public static boolean isIE(HttpServletRequest request) {
return (request.getHeader(USER_AGENT).toLowerCase().indexOf("msie") > -1 || request
.getHeader(USER_AGENT).toLowerCase().contains(RV_11));
}
/**
* 获取IE版本
*
* @param request
* @return
*/
public static Double getIEversion(HttpServletRequest request) {
Double version = 0.0;
if (getBrowserType(request, IE11)) {
version = 11.0;
} else if (getBrowserType(request, IE10)) {
version = 10.0;
} else if (getBrowserType(request, IE9)) {
version = 9.0;
} else if (getBrowserType(request, IE8)) {
version = 8.0;
} else if (getBrowserType(request, IE7)) {
version = 7.0;
} else if (getBrowserType(request, IE6)) {
version = 6.0;
}
return version;
}
/**
* 获取浏览器类型
*
* @param request
* @return
*/
public static BrowserType getBrowserType(HttpServletRequest request) {
BrowserType browserType = null;
if (getBrowserType(request, IE11)) {
browserType = BrowserType.IE11;
}
if (getBrowserType(request, IE10)) {
browserType = BrowserType.IE10;
}
if (getBrowserType(request, IE9)) {
browserType = BrowserType.IE9;
}
if (getBrowserType(request, IE8)) {
browserType = BrowserType.IE8;
}
if (getBrowserType(request, IE7)) {
browserType = BrowserType.IE7;
}
if (getBrowserType(request, IE6)) {
browserType = BrowserType.IE6;
}
if (getBrowserType(request, FIREFOX)) {
browserType = BrowserType.FIREFOX;
}
if (getBrowserType(request, SAFARI)) {
browserType = BrowserType.SAFARI;
}
if (getBrowserType(request, CHROME)) {
browserType = BrowserType.CHROME;
}
if (getBrowserType(request, OPERA)) {
browserType = BrowserType.OPERA;
}
if (getBrowserType(request, "Camino")) {
browserType = BrowserType.CAMINO;
}
return browserType;
}
private static boolean getBrowserType(HttpServletRequest request,
String brosertype) {
return request.getHeader(USER_AGENT).toLowerCase()
.indexOf(brosertype) > -1;
}
private static final String IE11 = RV_11;
private static final String IE10 = "MSIE 10.0";
private static final String IE9 = "MSIE 9.0";
private static final String IE8 = "MSIE 8.0";
private static final String IE7 = "MSIE 7.0";
private static final String IE6 = "MSIE 6.0";
private static final String MAXTHON = "Maxthon";
private static final String QQ = "QQBrowser";
private static final String GREEN = "GreenBrowser";
private static final String SE360 = "360SE";
private static final String FIREFOX = "Firefox";
private static final String OPERA = "Opera";
private static final String CHROME = "Chrome";
private static final String SAFARI = "Safari";
private static final String OTHER = "其它";
public static String checkBrowse(HttpServletRequest request) {
String userAgent = request.getHeader(USER_AGENT);
if (regex(OPERA, userAgent)) {
return OPERA;
}
if (regex(CHROME, userAgent)) {
return CHROME;
}
if (regex(FIREFOX, userAgent)) {
return FIREFOX;
}
if (regex(SAFARI, userAgent)) {
return SAFARI;
}
if (regex(SE360, userAgent)) {
return SE360;
}
if (regex(GREEN, userAgent)) {
return GREEN;
}
if (regex(QQ, userAgent)) {
return QQ;
}
if (regex(MAXTHON, userAgent)) {
return MAXTHON;
}
if (regex(IE11, userAgent)) {
return IE11;
}
if (regex(IE10, userAgent)) {
return IE10;
}
if (regex(IE9, userAgent)) {
return IE9;
}
if (regex(IE8, userAgent)) {
return IE8;
}
if (regex(IE7, userAgent)) {
return IE7;
}
if (regex(IE6, userAgent)) {
return IE6;
}
return OTHER;
}
public static boolean regex(String regex, String str) {
Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
Matcher m = p.matcher(str);
return m.find();
}
private static Map<String, String> langMap = new HashMap<>();
private static final String ZH = "zh";
private static final String ZH_CN = "zh-cn";
private static final String EN = "en";
private static final String EN_US = "en";
static
{
langMap.put(ZH, ZH_CN);
langMap.put(EN, EN_US);
}
public static String getBrowserLanguage(HttpServletRequest request) {
String browserLang = request.getLocale().getLanguage();
String browserLangCode = langMap.get(browserLang);
if(browserLangCode == null)
{
browserLangCode = EN_US;
}
return browserLangCode;
}
/** 判断请求是否来自电脑端 */
public static boolean isDesktop(HttpServletRequest request) {
return !isMobile(request);
}
/** 判断请求是否来自移动端 */
public static boolean isMobile(HttpServletRequest request) {
String ua = request.getHeader(USER_AGENT).toLowerCase();
Pattern pattern = Pattern.compile("(phone|pad|pod|iphone|ipod|ios|ipad|android|mobile|blackberry|iemobile|mqqbrowser|juc|fennec|wosbrowser|browserng|webos|symbian|windows phone)");
return pattern.matcher(ua).find();
}
}
@@ -0,0 +1,272 @@
package com.jero.common.util;
import java.io.*;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.sql.DataSource;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.jero.common.constant.CommonConstant;
import com.jero.common.constant.DataBaseConstant;
import com.jero.common.exception.JeroBootException;
import com.jero.common.util.filter.FileTypeFilter;
import com.jero.common.util.oss.OssBootUtil;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class CommonUtils {
private CommonUtils(){
}
//中文正则
private static Pattern ZHONGWEN_PATTERN = Pattern.compile("[\u4e00-\u9fa5]");
public static String uploadOnlineImage(byte[] data,String basePath,String bizPath,String uploadType){
String dbPath = null;
String fileName = "image" + Math.round(Math.random() * 100000000000L);
fileName += "." + PoiPublicUtil.getFileExtendName(data);
try {
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
File file = new File(basePath + File.separator + bizPath + File.separator );
if (!file.exists()) {
file.mkdirs();// 创建文件根目录
}
String savePath = file.getPath() + File.separator + fileName;
File savefile = new File(savePath);
FileCopyUtils.copy(data, savefile);
dbPath = bizPath + File.separator + fileName;
}else {
InputStream in = new ByteArrayInputStream(data);
String relativePath = bizPath+ File.separator +fileName;
if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
dbPath = MinioUtil.upload(in,relativePath);
}else if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
dbPath = OssBootUtil.upload(in,relativePath);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return dbPath;
}
/**
* 判断文件名是否带盘符,重新处理
* @param fileName
* @return
*/
public static String getFileName(String fileName){
//判断是否带有盘符信息
// Check for Unix-style path
int unixSep = fileName.lastIndexOf('/');
// Check for Windows-style path
int winSep = fileName.lastIndexOf('\\');
// Cut off at latest possible point
int pos = (winSep > unixSep ? winSep : unixSep);
if (pos != -1) {
// Any sort of path separator found...
fileName = fileName.substring(pos + 1);
}
//替换上传文件名字的特殊字符
fileName = fileName.replace("=","").replace(",","").replace("&","")
.replace("#", "").replace("", "").replace("", "");
//替换上传文件名字中的空格
fileName=fileName.replaceAll("\\s","");
return fileName;
}
// java 判断字符串里是否包含中文字符
public static boolean ifContainChinese(String str) {
if(str.getBytes().length == str.length()){
return false;
}else{
Matcher m = ZHONGWEN_PATTERN.matcher(str);
return m.find();
}
}
/**
* 统一全局上传
* @Return: java.lang.String
*/
public static String upload(MultipartFile file, String bizPath, String uploadType) {
String url = "";
if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
url = MinioUtil.upload(file,bizPath);
}else{
url = OssBootUtil.upload(file,bizPath);
}
return url;
}
/**
* 统一全局上传 带桶
* @Return: java.lang.String
*/
public static String upload(MultipartFile file, String bizPath, String uploadType, String customBucket) {
String url = "";
if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
url = MinioUtil.upload(file,bizPath,customBucket);
}else{
url = OssBootUtil.upload(file,bizPath,customBucket);
}
return url;
}
/**
* 本地文件上传
* @param mf 文件
* @param bizPath 自定义路径
* @return
*/
public static String uploadLocal(MultipartFile mf,String bizPath, String uploadpath){
try {
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
FileTypeFilter.fileTypeFilter(mf);
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
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(".")!=-1){
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
}else{
fileName = orgName+ "_" + System.currentTimeMillis();
}
String savePath = file.getPath() + File.separator + fileName;
File savefile = new File(savePath);
FileCopyUtils.copy(mf.getBytes(), savefile);
String dbpath = null;
if(oConvertUtils.isNotEmpty(bizPath)){
dbpath = bizPath + File.separator + fileName;
}else{
dbpath = fileName;
}
if (dbpath.contains("\\")) {
dbpath = dbpath.replace("\\", "/");
}
return dbpath;
} catch (IOException e) {
log.error(e.getMessage(), e);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return "";
}
/** 当前系统数据库类型 */
private static String DB_TYPE = "";
private static DbType dbTypeEnum = null;
/**
* 全局获取平台数据库类型(作废了)
* @deprecated 不推荐
* @return
*/
@Deprecated
public static String getDatabaseType() {
if(oConvertUtils.isNotEmpty(DB_TYPE)){
return DB_TYPE;
}
DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
try {
return getDatabaseTypeByDataSource(dataSource);
} catch (SQLException e) {
log.warn(e.getMessage(), e);
return "";
}
}
/**
* 全局获取平台数据库类型(对应mybaisPlus枚举)
* @return
*/
public static DbType getDatabaseTypeEnum() {
if (oConvertUtils.isNotEmpty(dbTypeEnum)) {
return dbTypeEnum;
}
DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
try (Connection connection = dataSource.getConnection();) {
dbTypeEnum = JdbcUtils.getDbType(connection.getMetaData().getURL());
return dbTypeEnum;
} catch (SQLException e) {
log.warn(e.getMessage(), e);
return null;
}
}
/**
* 获取数据库类型
* @param dataSource
* @return
* @throws SQLException
*/
private static String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException{
if("".equals(DB_TYPE)) {
Connection connection = dataSource.getConnection();
try {
DatabaseMetaData md = connection.getMetaData();
String dbType = md.getDatabaseProductName().toLowerCase();
if(dbType.indexOf("mysql")>=0) {
DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL;
}else if(dbType.indexOf("oracle")>=0 ||dbType.indexOf("dm")>=0) {
DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE;
}else if(dbType.indexOf("sqlserver")>=0||dbType.indexOf("sql server")>=0) {
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
}else if(dbType.indexOf("postgresql")>=0) {
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
}else {
throw new JeroBootException("数据库类型:["+dbType+"]不识别!");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}finally {
connection.close();
}
}
return DB_TYPE;
}
/**
* 黑名单限制文件
* @date 2021/4/14 6:18
* @param fileName 文件名
* @return boolean true:处于黑名单 false:不处于黑名单
*/
public static boolean limitFileSuffix(String fileName,String[] fileSuffixLimits){
final List<String> fileNameList = Arrays.asList(fileSuffixLimits);
boolean isExists = fileNameList.stream().anyMatch(name -> fileName.substring(0,fileName.lastIndexOf('.')).contains(name)||fileName.substring(fileName.lastIndexOf('.')).contains(name));
return isExists;
}
/**
* RSA 使用私钥解密
* @date 2021/4/15 16:11
* @param str 待解密的字符串
* @param RSAPrivateKey 私钥
* @return String 解密后的字符串
*/
public static String decryptBtRsaPriKey(String str,String RSAPrivateKey){
RSA rsa = new RSA(RSAPrivateKey, null);
byte[] decrypt = rsa.decrypt(str, KeyType.PrivateKey);
return new String(decrypt);
}
}
@@ -0,0 +1,737 @@
package com.jero.common.util;
import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
/**
* 类描述:时间操作定义类
*
* @Author: 张代浩
* @Date:2012-12-8 12:15:03
* @Version 1.0
*/
public class DateUtils extends PropertyEditorSupport {
public static ThreadLocal<SimpleDateFormat> date_sdf = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
public static ThreadLocal<SimpleDateFormat> yyyyMMdd = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd"));
public static ThreadLocal<SimpleDateFormat> date_sdf_wz = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy年MM月dd日"));
public static ThreadLocal<SimpleDateFormat> time_sdf = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm"));
public static ThreadLocal<SimpleDateFormat> yyyymmddhhmmss = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmss"));
public static ThreadLocal<SimpleDateFormat> short_time_sdf = ThreadLocal.withInitial(() -> new SimpleDateFormat("HH:mm"));
public static ThreadLocal<SimpleDateFormat> datetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// 以毫秒表示的时间
private static final long DAY_IN_MILLIS = 24 * 3600 * 1000L;
private static final long HOUR_IN_MILLIS = 3600 * 1000L;
private static final long MINUTE_IN_MILLIS = 60 * 1000L;
private static final long SECOND_IN_MILLIS = 1000L;
// 指定模式的时间格式
private static SimpleDateFormat getSDFormat(String pattern) {
return new SimpleDateFormat(pattern);
}
/**
* 当前日历,这里用中国时间表示
*
* @return 以当地时区表示的系统当前日历
*/
public static Calendar getCalendar() {
return Calendar.getInstance();
}
/**
* 指定毫秒数表示的日历
*
* @param millis 毫秒数
* @return 指定毫秒数表示的日历
*/
public static Calendar getCalendar(long millis) {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(millis));
return cal;
}
// ////////////////////////////////////////////////////////////////////////////
// getDate
// 各种方式获取的Date
// ////////////////////////////////////////////////////////////////////////////
/**
* 当前日期
*
* @return 系统当前时间
*/
public static Date getDate() {
return new Date();
}
/**
* 指定毫秒数表示的日期
*
* @param millis 毫秒数
* @return 指定毫秒数表示的日期
*/
public static Date getDate(long millis) {
return new Date(millis);
}
/**
* 时间戳转换为字符串
*
* @return
*/
public static String timestamptoStr() {
return date2Str(date_sdf.get());
}
/**
* 字符串转换时间戳
*
* @param str
* @return
*/
public static Timestamp str2Timestamp(String str) {
Date date = str2Date(str, date_sdf.get());
if(Objects.isNull(date)){
return null;
}
return new Timestamp(date.getTime());
}
/**
* 字符串转换成日期
*
* @param str
* @param sdf
* @return
*/
public static Date str2Date(String str, SimpleDateFormat sdf) {
if (null == str || "".equals(str)) {
return null;
}
Date date = null;
try {
date = sdf.parse(str);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
/**
* 日期转换为字符串
*
* @param dateSdf 日期格式
* @return 字符串
*/
public static String date2Str(SimpleDateFormat dateSdf) {
Date date = getDate();
return dateSdf.format(date);
}
/**
* 格式化时间
*
* @param date
* @param format
* @return
*/
public static String dateformat(String date, String format) {
SimpleDateFormat sformat = new SimpleDateFormat(format);
Date dateNew = null;
try {
dateNew = sformat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return sformat.format(dateNew);
}
/**
* 日期转换为字符串
*
* @param date 日期
* @param dateSdf 日期格式
* @return 字符串
*/
public static String date2Str(Date date, SimpleDateFormat dateSdf) {
if (null == date) {
return null;
}
return dateSdf.format(date);
}
/**
* 日期转换为字符串
*
* @param format 日期格式
* @return 字符串
*/
public static String getDate(String format) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
/**
* 指定毫秒数的时间戳
*
* @param millis 毫秒数
* @return 指定毫秒数的时间戳
*/
public static Timestamp getTimestamp(long millis) {
return new Timestamp(millis);
}
/**
* 以字符形式表示的时间戳
*
* @param time 毫秒数
* @return 以字符形式表示的时间戳
*/
public static Timestamp getTimestamp(String time) {
return new Timestamp(Long.parseLong(time));
}
/**
* 系统当前的时间戳
*
* @return 系统当前的时间戳
*/
public static Timestamp getTimestamp() {
return new Timestamp(System.currentTimeMillis());
}
/**
* 当前时间,格式 yyyy-MM-dd HH:mm:ss
*
* @return 当前时间的标准形式字符串
*/
public static String now() {
return datetimeFormat.get().format(getCalendar().getTime());
}
/**
* 指定日期的时间戳
*
* @param date 指定日期
* @return 指定日期的时间戳
*/
public static Timestamp getTimestamp(Date date) {
return new Timestamp(date.getTime());
}
/**
* 指定日历的时间戳
*
* @param cal 指定日历
* @return 指定日历的时间戳
*/
public static Timestamp getCalendarTimestamp(Calendar cal) {
return new Timestamp(cal.getTime().getTime());
}
public static Timestamp geTimestamps() {
Date dt = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String nowTime = df.format(dt);
return java.sql.Timestamp.valueOf(nowTime);
}
// ////////////////////////////////////////////////////////////////////////////
// getMillis
// 各种方式获取的Millis
// ////////////////////////////////////////////////////////////////////////////
/**
* 系统时间的毫秒数
*
* @return 系统时间的毫秒数
*/
public static long getMillis() {
return System.currentTimeMillis();
}
/**
* 指定日历的毫秒数
*
* @param cal 指定日历
* @return 指定日历的毫秒数
*/
public static long getMillis(Calendar cal) {
return cal.getTime().getTime();
}
/**
* 指定日期的毫秒数
*
* @param date 指定日期
* @return 指定日期的毫秒数
*/
public static long getMillis(Date date) {
return date.getTime();
}
/**
* 指定时间戳的毫秒数
*
* @param ts 指定时间戳
* @return 指定时间戳的毫秒数
*/
public static long getMillis(Timestamp ts) {
return ts.getTime();
}
// ////////////////////////////////////////////////////////////////////////////
// formatDate
// 将日期按照一定的格式转化为字符串
// ////////////////////////////////////////////////////////////////////////////
/**
* 默认方式表示的系统当前日期,具体格式:年-月-日
*
* @return 默认日期按“年-月-日“格式显示
*/
public static String formatDate() {
return date_sdf.get().format(getCalendar().getTime());
}
/**
* 默认方式表示的系统当前日期,具体格式:yyyy-MM-dd HH:mm:ss
*
* @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示
*/
public static String formatDateTime() {
return datetimeFormat.get().format(getCalendar().getTime());
}
/**
* 获取时间字符串
*/
public static String getDataString(SimpleDateFormat formatstr) {
return formatstr.format(getCalendar().getTime());
}
/**
* 指定日期的默认显示,具体格式:年-月-日
*
* @param cal 指定的日期
* @return 指定日期按“年-月-日“格式显示
*/
public static String formatDate(Calendar cal) {
return date_sdf.get().format(cal.getTime());
}
/**
* 指定日期的默认显示,具体格式:年-月-日
*
* @param date 指定的日期
* @return 指定日期按“年-月-日“格式显示
*/
public static String formatDate(Date date) {
return date_sdf.get().format(date);
}
/**
* 指定毫秒数表示日期的默认显示,具体格式:年-月-日
*
* @param millis 指定的毫秒数
* @return 指定毫秒数表示日期按“年-月-日“格式显示
*/
public static String formatDate(long millis) {
return date_sdf.get().format(new Date(millis));
}
/**
* 默认日期按指定格式显示
*
* @param pattern 指定的格式
* @return 默认日期按指定格式显示
*/
public static String formatDate(String pattern) {
return getSDFormat(pattern).format(getCalendar().getTime());
}
/**
* 指定日期按指定格式显示
*
* @param cal 指定的日期
* @param pattern 指定的格式
* @return 指定日期按指定格式显示
*/
public static String formatDate(Calendar cal, String pattern) {
return getSDFormat(pattern).format(cal.getTime());
}
/**
* 指定日期按指定格式显示
*
* @param date 指定的日期
* @param pattern 指定的格式
* @return 指定日期按指定格式显示
*/
public static String formatDate(Date date, String pattern) {
return getSDFormat(pattern).format(date);
}
// ////////////////////////////////////////////////////////////////////////////
// formatTime
// 将日期按照一定的格式转化为字符串
// ////////////////////////////////////////////////////////////////////////////
/**
* 默认方式表示的系统当前日期,具体格式:年-月-日 时:分
*
* @return 默认日期按“年-月-日 时:分“格式显示
*/
public static String formatTime() {
return time_sdf.get().format(getCalendar().getTime());
}
/**
* 指定毫秒数表示日期的默认显示,具体格式:年-月-日 时:分
*
* @param millis 指定的毫秒数
* @return 指定毫秒数表示日期按“年-月-日 时:分“格式显示
*/
public static String formatTime(long millis) {
return time_sdf.get().format(new Date(millis));
}
/**
* 指定日期的默认显示,具体格式:年-月-日 时:分
*
* @param cal 指定的日期
* @return 指定日期按“年-月-日 时:分“格式显示
*/
public static String formatTime(Calendar cal) {
return time_sdf.get().format(cal.getTime());
}
/**
* 指定日期的默认显示,具体格式:年-月-日 时:分
*
* @param date 指定的日期
* @return 指定日期按“年-月-日 时:分“格式显示
*/
public static String formatTime(Date date) {
return time_sdf.get().format(date);
}
// ////////////////////////////////////////////////////////////////////////////
// formatShortTime
// 将日期按照一定的格式转化为字符串
// ////////////////////////////////////////////////////////////////////////////
/**
* 默认方式表示的系统当前日期,具体格式:时:分
*
* @return 默认日期按“时:分“格式显示
*/
public static String formatShortTime() {
return short_time_sdf.get().format(getCalendar().getTime());
}
/**
* 指定毫秒数表示日期的默认显示,具体格式:时:分
*
* @param millis 指定的毫秒数
* @return 指定毫秒数表示日期按“时:分“格式显示
*/
public static String formatShortTime(long millis) {
return short_time_sdf.get().format(new Date(millis));
}
/**
* 指定日期的默认显示,具体格式:时:分
*
* @param cal 指定的日期
* @return 指定日期按“时:分“格式显示
*/
public static String formatShortTime(Calendar cal) {
return short_time_sdf.get().format(cal.getTime());
}
/**
* 指定日期的默认显示,具体格式:时:分
*
* @param date 指定的日期
* @return 指定日期按“时:分“格式显示
*/
public static String formatShortTime(Date date) {
return short_time_sdf.get().format(date);
}
// ////////////////////////////////////////////////////////////////////////////
// parseDate
// parseCalendar
// parseTimestamp
// 将字符串按照一定的格式转化为日期或时间
// ////////////////////////////////////////////////////////////////////////////
/**
* 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
*
* @param src 将要转换的原始字符窜
* @param pattern 转换的匹配格式
* @return 如果转换成功则返回转换后的日期
* @throws ParseException
*/
public static Date parseDate(String src, String pattern) throws ParseException {
return getSDFormat(pattern).parse(src);
}
/**
* 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
*
* @param src 将要转换的原始字符窜
* @param pattern 转换的匹配格式
* @return 如果转换成功则返回转换后的日期
* @throws ParseException
*/
public static Calendar parseCalendar(String src, String pattern) throws ParseException {
Date date = parseDate(src, pattern);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal;
}
public static String formatAddDate(String src, String pattern, int amount) throws ParseException {
Calendar cal;
cal = parseCalendar(src, pattern);
cal.add(Calendar.DATE, amount);
return formatDate(cal);
}
/**
* 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
*
* @param src 将要转换的原始字符窜
* @param pattern 转换的匹配格式
* @return 如果转换成功则返回转换后的时间戳
* @throws ParseException
*/
public static Timestamp parseTimestamp(String src, String pattern) throws ParseException {
Date date = parseDate(src, pattern);
return new Timestamp(date.getTime());
}
// ////////////////////////////////////////////////////////////////////////////
// dateDiff
// 计算两个日期之间的差值
// ////////////////////////////////////////////////////////////////////////////
/**
* 计算两个时间之间的差值,根据标志的不同而不同
*
* @param flag 计算标志,表示按照年/月/日/时/分/秒等计算
* @param calSrc 减数
* @param calDes 被减数
* @return 两个日期之间的差值
*/
public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) {
long millisDiff = getMillis(calSrc) - getMillis(calDes);
if (flag == 'y') {
return (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR));
}
if (flag == 'd') {
return (int) (millisDiff / DAY_IN_MILLIS);
}
if (flag == 'h') {
return (int) (millisDiff / HOUR_IN_MILLIS);
}
if (flag == 'm') {
return (int) (millisDiff / MINUTE_IN_MILLIS);
}
if (flag == 's') {
return (int) (millisDiff / SECOND_IN_MILLIS);
}
return 0;
}
public static Long getCurrentTimestamp() {
return Long.valueOf(DateUtils.yyyymmddhhmmss.get().format(new Date()));
}
/**
* 日期数据转换字符串
* @param dateList
* @return
*/
public static String formatDateList(List<Date> dateList) {
StringBuilder strSb = new StringBuilder();
if(CollectionUtils.isNotEmpty(dateList)){
dateList = dateList.stream().distinct().sorted().collect(Collectors.toList());
for (Date date : dateList) {
strSb.append(date_sdf.get().format(date)).append(",");
}
}
String result = "";
if(!StringUtils.isEmpty(strSb.toString())){
result = strSb.substring(0,strSb.length()-1);
}
return result;
}
/**
* String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd
* HH:mm:ss“ * @param text String类型的时间值
*/
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (org.springframework.util.StringUtils.hasText(text)) {
try {
if (text.indexOf(":") == -1 && text.length() == 10) {
setValue(DateUtils.date_sdf.get().parse(text));
} else if (text.indexOf(":") > -1 && text.length() == 19) {
setValue(DateUtils.datetimeFormat.get().parse(text));
} else {
throw new IllegalArgumentException("Could not parse date, date format is error ");
}
} catch (ParseException ex) {
IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage());
iae.initCause(ex);
throw iae;
}
} else {
setValue(null);
}
}
public static int getYear() {
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(getDate());
return calendar.get(Calendar.YEAR);
}
/**
* LocalDate转Date
* @param localDate
* @return Date
*/
public static Date localDate2Date(LocalDate localDate) {
if (null == localDate) {
return null;
}
ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
return Date.from(zonedDateTime.toInstant());
}
/**
* Date转LocalDate
* @param date
*/
public static LocalDate date2LocalDate(Date date) {
if(null == date) {
return null;
}
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
/**
* LocalDateTime转Date
* @param localDateTime
* @return Date
*/
public static Date localDateTime2Date(LocalDateTime localDateTime){
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
Instant instant = zonedDateTime.toInstant();
return Date.from(instant);
}
/**
* Date转LocalDateTime
* @param date
* @return LocalDateTime
*/
public static LocalDateTime date2LocalDateTime(Date date){
Instant instant = date.toInstant();
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zonedDateTime = instant.atZone(zoneId);
return zonedDateTime.toLocalDateTime();
}
/***
* @Description: 判断多个日期是否都符合日期格式 yyyy/m/d、yyyy-MM-dd、yyyy年MM月dd日
* @Author: yangxuenan
* @Date: 2020/12/31 11:31
* @Param: [str]
* @Return: boolean
*/
public static boolean isValidDate(String str){
if(StringUtils.isNotBlank(str)){
String dateRegex = "^\\d{4}年\\d{1,2}月\\d{1,2}日";
str = str.replace("",",");
String[] strArr = str.split(",");
for (String dateStr : strArr) {
if(dateStr.matches(dateRegex)){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
try {
simpleDateFormat.setLenient(false);
simpleDateFormat.parse(dateStr);
} catch (Exception e){
return false;
}
} else {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String replace = dateStr.replace("/", "-");
try {
simpleDateFormat.setLenient(false);
simpleDateFormat.parse(replace);
} catch (Exception e){
return false;
}
}
}
}
return true;
}
//yyyy年MM月dd日,yyyy/MM/dd 转 yyyy-MM-dd
public static String coverDate(String str) throws ParseException {
List<String> newStrList = new ArrayList<>();
String dateRegex = "^\\d{4}年\\d{1,2}月\\d{1,2}日";
str = str.replace("",",");
String[] strArr = str.split(",");
for (String dateStr : strArr) {
String newStr = null;
if (dateStr.matches(dateRegex)) {
Date date = new SimpleDateFormat("yyyy年MM月dd日").parse(dateStr);
newStr = new SimpleDateFormat("yyyy-MM-dd").format(date);
} else if (dateStr.contains("/")) {
Date date = new SimpleDateFormat("yyyy/MM/dd").parse(dateStr);
newStr = new SimpleDateFormat("yyyy-MM-dd").format(date);
} else if (dateStr.contains("-")){
newStr = dateStr;
}
newStrList.add(newStr);
}
newStrList.sort((t1, t2) -> t1.compareTo(t2)); // 日期增序
return StringUtils.join(newStrList, ",");
}
}
@@ -0,0 +1,70 @@
package com.jero.common.util;
import org.apache.commons.lang3.StringUtils;
public enum DySmsEnum {
LOGIN_TEMPLATE_CODE("SMS_175435174","JERO","code"),
FORGET_PASSWORD_TEMPLATE_CODE("SMS_175435174","JERO","code"),
REGISTER_TEMPLATE_CODE("SMS_175430166","JERO","code"),
/**会议通知*/
MEET_NOTICE_TEMPLATE_CODE("SMS_201480469","H5活动之家","username,title,minute,time"),
/**我的计划通知*/
PLAN_NOTICE_TEMPLATE_CODE("SMS_201470515","H5活动之家","username,title,time");
/**
* 短信模板编码
*/
private String templateCode;
/**
* 签名
*/
private String signName;
/**
* 短信模板必需的数据名称,多个key以逗号分隔,此处配置作为校验
*/
private String keys;
private DySmsEnum(String templateCode,String signName,String keys) {
this.templateCode = templateCode;
this.signName = signName;
this.keys = keys;
}
public String getTemplateCode() {
return templateCode;
}
public void setTemplateCode(String templateCode) {
this.templateCode = templateCode;
}
public String getSignName() {
return signName;
}
public void setSignName(String signName) {
this.signName = signName;
}
public String getKeys() {
return keys;
}
public void setKeys(String keys) {
this.keys = keys;
}
public static DySmsEnum toEnum(String templateCode) {
if(StringUtils.isEmpty(templateCode)){
return null;
}
for(DySmsEnum item : DySmsEnum.values()) {
if(item.getTemplateCode().equals(templateCode)) {
return item;
}
}
return null;
}
}
@@ -0,0 +1,115 @@
package com.jero.common.util;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.jero.common.exception.JeroBootException;
import com.jero.config.StaticConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created on 17/6/7.
* 短信API产品的DEMO程序,工程中包含了一个SmsDemo类,直接通过
* 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可)
* 工程依赖了2个jar包(存放在工程的libs目录下)
* 1:aliyun-java-sdk-core.jar
* 2:aliyun-java-sdk-dysmsapi.jar
*
* 备注:Demo工程编码采用UTF-8
* 国际短信发送请勿参照此DEMO
*/
public class DySmsHelper {
private DySmsHelper(){
}
private static final Logger logger=LoggerFactory.getLogger(DySmsHelper.class);
//产品名称:云通信短信API产品,开发者无需替换
static final String PRODUCT = "Dysmsapi";
//产品域名,开发者无需替换
static final String DOMAIN = "dysmsapi.aliyuncs.com";
// 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
static String accessKeyId;
static String accessKeySecret;
public static void setAccessKeyId(String accessKeyId) {
DySmsHelper.accessKeyId = accessKeyId;
}
public static void setAccessKeySecret(String accessKeySecret) {
DySmsHelper.accessKeySecret = accessKeySecret;
}
public static String getAccessKeyId() {
return accessKeyId;
}
public static String getAccessKeySecret() {
return accessKeySecret;
}
public static boolean sendSms(String phone,JSONObject templateParamJson,DySmsEnum dySmsEnum) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//update-begin-authortaoyan date:20200811 for:配置类数据获取
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
setAccessKeyId(staticConfig.getAccessKeyId());
setAccessKeySecret(staticConfig.getAccessKeySecret());
//update-end-authortaoyan date:20200811 for:配置类数据获取
String hangzhou = "cn-hangzhou";
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile(hangzhou, accessKeyId, accessKeySecret);
DefaultProfile.addEndpoint(hangzhou, hangzhou, PRODUCT, DOMAIN);
IAcsClient acsClient = new DefaultAcsClient(profile);
//验证json参数
validateParam(templateParamJson,dySmsEnum);
//组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest();
//必填:待发送手机号
request.setPhoneNumbers(phone);
//必填:短信签名-可在短信控制台中找到
request.setSignName(dySmsEnum.getSignName());
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode(dySmsEnum.getTemplateCode());
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
request.setTemplateParam(templateParamJson.toJSONString());
boolean result = false;
//hint 此处可能会抛出异常,注意catch
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
logger.info("短信接口返回的数据----------------");
String str = "{Code:" + sendSmsResponse.getCode()+",Message:" + sendSmsResponse.getMessage()+",RequestId:"+ sendSmsResponse.getRequestId()+",BizId:"+sendSmsResponse.getBizId()+"}";
logger.info(str);
if ("OK".equals(sendSmsResponse.getCode())) {
result = true;
}
return result;
}
private static void validateParam(JSONObject templateParamJson,DySmsEnum dySmsEnum) {
String keys = dySmsEnum.getKeys();
String [] keyArr = keys.split(",");
for(String item :keyArr) {
if(!templateParamJson.containsKey(item)) {
throw new JeroBootException("模板缺少参数:"+item);
}
}
}
}
@@ -0,0 +1,53 @@
/**
* @Author: Greyfus
* @Create: 2022-06-26 19:24
* @Version:
* @Description:
*/
package com.jero.common.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
public class FileUtils {
private FileUtils() {
throw new IllegalStateException("FileUtils class");
}
private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
/**
* 删除指定文件夹下文件
*
* @param filePath
*/
public static void deleteFolders(String filePath) {
Path path = Paths.get(filePath);
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {
Files.delete(file);
LOGGER.info("删除文件: {}", file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir,
IOException exc) throws IOException {
Files.delete(dir);
LOGGER.info("文件夹被删除: {}", dir);
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,101 @@
package com.jero.common.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.handler.IFillRuleHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
/**
* 规则值自动生成工具类
*
* @author qinfeng
* @举例: 自动生成订单号;自动生成当前日期
*/
@Slf4j
public class FillRuleUtil {
private FillRuleUtil(){
}
/**
* @param ruleCode ruleCode
* @return
*/
@SuppressWarnings("unchecked")
public static Object executeRule(String ruleCode, JSONObject formData) {
if (!StringUtils.isEmpty(ruleCode)) {
try {
// 获取 Service
ServiceImpl<BaseMapper<T>,T> impl = (ServiceImpl) SpringContextUtils.getBean("sysFillRuleServiceImpl");
// 根据 ruleCode 查询出实体
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("rule_code", ruleCode);
JSONObject entity = JSON.parseObject(JSON.toJSONString(impl.getOne(queryWrapper)));
if (entity == null) {
log.warn("填值规则:" + ruleCode + " 不存在");
return null;
}
// 获取必要的参数
String ruleClass = entity.getString("ruleClass");
JSONObject params = entity.getJSONObject("ruleParams");
if (params == null) {
params = new JSONObject();
}
if (formData == null) {
formData = new JSONObject();
}
// 通过反射执行配置的类里的方法
IFillRuleHandler ruleHandler = (IFillRuleHandler) Class.forName(ruleClass).newInstance();
return ruleHandler.execute(params, formData);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* @param ruleCode ruleCode
* @return
*/
@SuppressWarnings("unchecked")
public static Object executeRuleByParam(String ruleCode, JSONObject formData, String moduleCode) {
if (!StringUtils.isEmpty(ruleCode)) {
try {
// 获取 Service
ServiceImpl<BaseMapper<T>,T> impl = (ServiceImpl) SpringContextUtils.getBean("sysFillRuleServiceImpl");
// 根据 ruleCode 查询出实体
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("rule_code", ruleCode);
JSONObject entity = JSON.parseObject(JSON.toJSONString(impl.getOne(queryWrapper)));
if (entity == null) {
log.warn("填值规则:" + ruleCode + " 不存在");
return null;
}
// 获取必要的参数
String ruleClass = entity.getString("ruleClass");
JSONObject params = entity.getJSONObject("ruleParams");
if (params == null) {
params = new JSONObject();
}
if (formData == null) {
formData = new JSONObject();
}
params.put("moduleCode", moduleCode);
// 通过反射执行配置的类里的方法
IFillRuleHandler ruleHandler = (IFillRuleHandler) Class.forName(ruleClass).newInstance();
return ruleHandler.execute(params, formData);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
@@ -0,0 +1,33 @@
package com.jero.common.util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.util.HtmlUtils;
/**
* HTML 工具类
*/
public class HTMLUtils {
private HTMLUtils(){
}
/**
* 获取HTML内的文本,不包含标签
*
* @param html HTML 代码
*/
public static String getInnerText(String html) {
if (StringUtils.isNotBlank(html)) {
//去掉 html 的标签
String content = html.replaceAll("</?[^>]+>", "");
// 将多个空格合并成一个空格
content = content.replaceAll("(&nbsp;)+", "&nbsp;");
// 反向转义字符
content = HtmlUtils.htmlUnescape(content);
return content.trim();
}
return "";
}
}
@@ -0,0 +1,61 @@
package com.jero.common.util;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* IP地址
*
* @Author scott
* @email test@163.com
* @Date 2019年01月14日
*/
public class IPUtils {
private IPUtils(){
}
private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
/**
* 获取IP地址
*
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = null;
try {
String unknown = "unknown";
ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} catch (Exception e) {
logger.error("IPUtils ERROR ", e);
}
//使用代理,则获取第一个IP地址
if(!StringUtils.isEmpty(ip) && ip.length() > 15 && ip.contains(",")) {
ip = ip.substring(0, ip.indexOf(","));
}
return ip;
}
}
@@ -0,0 +1,182 @@
package com.jero.common.util;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jero.common.api.vo.Result;
import com.jero.common.constant.CommonConstant;
import com.jero.common.exception.JeroBootException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* 导出返回信息
*/
@Slf4j
public class ImportExcelUtil {
private ImportExcelUtil(){
}
public static Result<JSONObject> imporReturnRes(int errorLines, int successLines, List<String> errorMessage){
if (errorLines == 0) {
return Result.OK("" + successLines + "行数据全部导入成功!");
} else {
JSONObject result = new JSONObject(5);
int totalCount = successLines + errorLines;
result.put("totalCount", totalCount);
result.put("errorCount", errorLines);
result.put("successCount", successLines);
result.put("msg", "总上传行数:" + totalCount + ",已导入行数:" + successLines + ",错误行数:" + errorLines);
String fileUrl = PmsUtil.saveErrorTxtByList(errorMessage, "userImportExcelErrorLog");
int lastIndex = fileUrl.lastIndexOf(File.separator);
String fileName = fileUrl.substring(lastIndex + 1);
result.put("fileUrl", "/sys/common/static/" + fileUrl);
result.put("fileName", fileName);
Result<JSONObject> res = Result.OK(result);
res.setCode(201);
res.setMessage("文件导入成功,但有错误。");
return res;
}
}
public static List<String> importDateSave(List<Object> list, Class<?> serviceClass,List<String> errorMessage,String errorFlag) {
IService<Object> bean =(IService) SpringContextUtils.getBean(serviceClass);
for (int i = 0; i < list.size(); i++) {
try {
boolean save = bean.save(list.get(i));
if(!save){
throw new JeroBootException(errorFlag);
}
} catch (Exception e) {
String message = e.getMessage().toLowerCase();
int lineNumber = i + 1;
// 通过索引名判断出错信息
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) {
errorMessage.add("" + lineNumber + " 行:角色编码已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME)) {
errorMessage.add("" + lineNumber + " 行:任务类名已经存在,忽略导入。");
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CODE)) {
errorMessage.add("" + lineNumber + " 行:职务编码已经存在,忽略导入。");
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE)) {
errorMessage.add("" + lineNumber + " 行:部门编码已经存在,忽略导入。");
}else {
errorMessage.add("" + lineNumber + " 行:未知错误,忽略导入");
log.error(e.getMessage(), e);
}
}
}
return errorMessage;
}
public static List<String> importDateSaveOne(Object obj, Class<?> serviceClass, List<String> errorMessage, int i, String errorFlag) {
IService<Object> bean = (IService) SpringContextUtils.getBean(serviceClass);
try {
boolean save = bean.save(obj);
if(!save){
throw new JeroBootException(errorFlag);
}
} catch (Exception e) {
String message = e.getMessage().toLowerCase();
int lineNumber = i + 1;
// 通过索引名判断出错信息
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) {
errorMessage.add("" + lineNumber + " 行:角色编码已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME)) {
errorMessage.add("" + lineNumber + " 行:任务类名已经存在,忽略导入。");
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CODE)) {
errorMessage.add("" + lineNumber + " 行:职务编码已经存在,忽略导入。");
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE)) {
errorMessage.add("" + lineNumber + " 行:部门编码已经存在,忽略导入。");
}else {
errorMessage.add("" + lineNumber + " 行:未知错误,忽略导入");
log.error(e.getMessage(), e);
}
}
return errorMessage;
}
/**
* 检查模板标题行模型是否匹配 不检查顺序(需要检查顺序的可自己优化)
*
* @param file 上传的excel 文件 对象
* @param pojoClass 导入模型
* @param titleRow 标题行下标
* @param redundantNum 冗余数 默认为0
* @return
*/
public static Boolean checkTemplateTitle(MultipartFile file, Class<?> pojoClass, Integer titleRow, int redundantNum) {
//excel中标题行的所有标题
List<String> excelList = new ArrayList<>();
//注解中所有标题
List<String> list = new ArrayList<>();
Field[] fields = pojoClass.getDeclaredFields();
for (Field field : fields) {
Annotation excelAnn = field.getAnnotation(Excel.class);
if (null != excelAnn) {
Excel ec = (Excel) excelAnn;
String name = ec.name();
if (StringUtils.isNotBlank(name)) {
list.add(name);
}
}
}
if (CollectionUtils.isEmpty(list)) {
return true;
}
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
if (!(inputStream.markSupported())) {
inputStream = new PushbackInputStream(inputStream, 8);
}
Workbook book = WorkbookFactory.create(inputStream);
Sheet sheet = book.getSheetAt(0);
Row row = sheet.getRow(titleRow);
for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) {
String value = row.getCell(i).getStringCellValue();
if (StringUtils.isNotBlank(value)) {
excelList.add(value);
}
}
book.close();
} catch (Exception e) {
throw new JeroBootException("excel表头错误");
}
if (CollectionUtils.isEmpty(excelList)) {
return false;
}
boolean flag = true;
flag = excelContainsList(redundantNum, excelList, list, flag);
return flag;
}
private static boolean excelContainsList(int redundantNum, List<String> excelList, List<String> list,boolean flag) {
if(excelList.size() != list.size()){
flag = false;
}
int i = 0;
for (String name : list) {
if (!excelList.contains(name)) {
i++;
}
}
if (i > redundantNum) {
flag = false;
}
return flag;
}
}
@@ -0,0 +1,50 @@
package com.jero.common.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Author: liyawei
* @Description:
* @Date: Created in 13:38 2022/2/24
*/
public class LineHumpUtil {
private static Pattern linePattern = Pattern.compile("_(\\w)");
/** 下划线转驼峰 */
public static String lineToHump(String str) {
str = str.toLowerCase();
Matcher matcher = linePattern.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
}
matcher.appendTail(sb);
return sb.toString();
}
/** 驼峰转下划线(简单写法,效率低于{@link #humpToLine2(String)}) */
public static String humpToLine(String str) {
return str.replaceAll("[A-Z]", "_$0").toLowerCase();
}
private static Pattern humpPattern = Pattern.compile("[A-Z]");
/** 驼峰转下划线,效率比上面高 */
public static String humpToLine2(String str) {
Matcher matcher = humpPattern.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
}
matcher.appendTail(sb);
return sb.toString();
}
public static void main(String[] args) {
String lineToHump = lineToHump("f_parent_no_leader");
System.out.println(lineToHump);// fParentNoLeader
System.out.println(humpToLine(lineToHump));// f_parent_no_leader
System.out.println(humpToLine2(lineToHump));// f_parent_no_leader
}
}
@@ -0,0 +1,48 @@
package com.jero.common.util;
import java.security.MessageDigest;
public class MD5Util {
private MD5Util(){
}
public static String byteArrayToHexString(byte[] b) {
StringBuilder resultSb = new StringBuilder();
for (int i = 0; i < b.length; i++){
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n += 256;
}
int d1 = n / 16;
int d2 = n % 16;
return HEX_DIGITS[d1] + HEX_DIGITS[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = origin;
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname)) {
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
} else {
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
}
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}
private static final String[] HEX_DIGITS = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
@@ -0,0 +1,35 @@
package com.jero.common.util;
import cn.hutool.extra.spring.SpringUtil;
import com.jero.common.constant.enums.LanguageEnum;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
/**
* @author liJiaRao
* @date 2023-08-17 14:07
*/
public class MessageUtils {
/**
* 根据消息键和参数 获取消息 委托给spring messageSource
* @param code 消息键
* @param args 参数
* @return 获取国际化翻译值
*/
public static String getMessage(String code, Object... args) {
MessageSource messageSource = SpringUtil.getBean(MessageSource.class);
String message;
try {
message = messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
}catch (Exception e){
message = code;
}
return message;
}
public static LanguageEnum getLanguage() {
String language = LocaleContextHolder.getLocale().getLanguage();
return LanguageEnum.EN.getValue().equals(language) ? LanguageEnum.EN : LanguageEnum.CN;
}
}
@@ -0,0 +1,343 @@
package com.jero.common.util;
import com.jero.common.util.filter.FileTypeFilter;
import com.jero.common.util.filter.StrAttackFilter;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* minio文件上传工具类
*/
@Slf4j
public class MinioUtil {
private MinioUtil(){
}
private static String minioUrl;
private static String minioName;
private static String minioPass;
private static String bucketName;
public static void setMinioUrl(String minioUrl) {
MinioUtil.minioUrl = minioUrl;
}
public static void setMinioName(String minioName) {
MinioUtil.minioName = minioName;
}
public static void setMinioPass(String minioPass) {
MinioUtil.minioPass = minioPass;
}
public static void setBucketName(String bucketName) {
MinioUtil.bucketName = bucketName;
}
public static String getMinioUrl() {
return minioUrl;
}
public static String getBucketName() {
return bucketName;
}
private static MinioClient minioClient = null;
/**
* 上传文件
* @param file
* @return
*/
public static String upload(MultipartFile file, String bizPath, String customBucket) {
String fileUrl = "";
//update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
bizPath=StrAttackFilter.filter(bizPath);
//update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
String newBucket = bucketName;
if(oConvertUtils.isNotEmpty(customBucket)){
newBucket = customBucket;
}
try {
initMinio(minioUrl, minioName,minioPass);
// 检查存储桶是否已经存在
if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(newBucket).build())) {
log.info("Bucket already exists.");
} else {
// 创建一个名为ota的存储桶
minioClient.makeBucket(MakeBucketArgs.builder().bucket(newBucket).build());
log.info("create a new bucket.");
}
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
FileTypeFilter.fileTypeFilter(file);
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
InputStream stream = file.getInputStream();
// 获取文件名
String orgName = file.getOriginalFilename();
if("".equals(orgName)){
orgName=file.getName();
}
orgName = CommonUtils.getFileName(orgName);
String objectName = bizPath+"/"
+(!orgName.contains(".")
?orgName + "_" + System.currentTimeMillis()
:orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."))
);
// 使用putObject上传一个本地文件到存储桶中。
if(objectName.startsWith("/")){
objectName = objectName.substring(1);
}
PutObjectArgs objectArgs = PutObjectArgs.builder().object(objectName)
.bucket(newBucket)
.contentType("application/octet-stream")
.stream(stream,stream.available(),-1).build();
minioClient.putObject(objectArgs);
stream.close();
fileUrl = objectName;
}catch (Exception e){
log.error(e.getMessage(), e);
}
return fileUrl;
}
/**
* 文件上传
* @param file
* @param bizPath
* @return
*/
public static String upload(MultipartFile file, String bizPath) {
return upload(file,bizPath,null);
}
/**
* 判断文件是否存在
* @param objectName 文件名
* @return
*/
public static boolean doesObjectExist(String objectName) {
boolean exist = true;
try {
initMinio(minioUrl, minioName,minioPass);
minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
} catch (Exception e) {
exist = false;
}
return exist;
}
/**
* 获取文件流
* @param bucketName
* @param objectName
* @return
*/
public static InputStream getMinioFile(String bucketName, String objectName){
InputStream inputStream = null;
try {
initMinio(minioUrl, minioName, minioPass);
GetObjectArgs objectArgs = GetObjectArgs.builder().object(objectName)
.bucket(bucketName).build();
inputStream = minioClient.getObject(objectArgs);
} catch (Exception e) {
log.info("文件获取失败" + e.getMessage());
}
return inputStream;
}
/**
* 获取文件流
* @param objectName
* @return
*/
public static InputStream download(String objectName){
InputStream inputStream = null;
try {
initMinio(minioUrl, minioName, minioPass);
GetObjectArgs objectArgs = GetObjectArgs.builder().object(objectName)
.bucket(bucketName).build();
inputStream = minioClient.getObject(objectArgs);
} catch (Exception e) {
log.info("文件获取失败" + e.getMessage());
}
return inputStream;
}
/**
* 删除文件
* @param objectName
* @throws Exception
*/
public static void removeObject(String objectName) {
try {
initMinio(minioUrl, minioName,minioPass);
RemoveObjectArgs objectArgs = RemoveObjectArgs.builder().object(objectName)
.bucket(bucketName).build();
minioClient.removeObject(objectArgs);
}catch (Exception e){
log.info("文件删除失败" + e.getMessage());
}
}
/**
* 删除文件
* @param objectName
* @throws Exception
*/
public static void delete(String objectName) {
try {
initMinio(minioUrl, minioName,minioPass);
RemoveObjectArgs objectArgs = RemoveObjectArgs.builder().object(objectName)
.bucket(bucketName).build();
minioClient.removeObject(objectArgs);
}catch (Exception e){
log.info("文件删除失败" + e.getMessage());
}
}
/**
* 获取文件外链
* @param bucketName
* @param objectName
* @param expires
* @return
*/
public static String getObjectURL(String bucketName, String objectName, Integer expires) {
initMinio(minioUrl, minioName,minioPass);
try{
GetPresignedObjectUrlArgs objectArgs = GetPresignedObjectUrlArgs.builder().object(objectName)
.bucket(bucketName)
.expiry(expires).build();
String url = minioClient.getPresignedObjectUrl(objectArgs);
return URLDecoder.decode(url,"UTF-8");
}catch (Exception e){
log.info("文件路径获取失败" + e.getMessage());
}
return null;
}
/**
* 初始化客户端
* @param minioUrl
* @param minioName
* @param minioPass
* @return
*/
private static MinioClient initMinio(String minioUrl, String minioName,String minioPass) {
if (minioClient == null) {
try {
minioClient = MinioClient.builder()
.endpoint(minioUrl)
.credentials(minioName, minioPass)
.build();
} catch (Exception e) {
e.printStackTrace();
}
}
return minioClient;
}
/**
* 上传文件到minio
* @param stream
* @param relativePath
* @return
*/
public static String upload(InputStream stream,String relativePath) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
initMinio(minioUrl, minioName,minioPass);
if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
log.info("Bucket already exists.");
} else {
// 创建一个名为ota的存储桶
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
log.info("create a new bucket.");
}
PutObjectArgs objectArgs = PutObjectArgs.builder().object(relativePath)
.bucket(bucketName)
.contentType("application/octet-stream")
.stream(stream,stream.available(),-1).build();
minioClient.putObject(objectArgs);
stream.close();
return minioUrl+bucketName+"/"+relativePath;
}
/**
* cos 上传
* 相同key 文件会覆盖
* @param bytev
* @param key
*/
public static void uploadByte(byte[] bytev, String key){
initMinio(minioUrl, minioName,minioPass);
try {
// 生成预签名上传 URL
Map<String, String> reqParams = new HashMap<String, String>();
reqParams.put("response-content-type", "application/json");
String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.PUT)
.bucket(bucketName)
.object(key)
.expiry(1, TimeUnit.DAYS)
.extraQueryParams(reqParams)
.build());
log.info("生成预签名上传URL:" + url);
int responseCode = upLoadFileByte(url.toString(), bytev);
if (responseCode == 200) {
log.info("上传成功!");
} else {
log.info("上传失败!");
}
} catch (ErrorResponseException | InsufficientDataException | InternalException | ServerException | XmlParserException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
private static int upLoadFileByte(String singnedurl,byte[] bytev){
InputStream inputStream= null;
DataOutputStream out = null;
int responseCode = 0;
try {
URL url= null;
url = new URL(singnedurl);
inputStream= new ByteArrayInputStream(bytev);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
out = new DataOutputStream(connection.getOutputStream());
// 写入要上传的数据
IOUtils.copy(inputStream, out);
responseCode = connection.getResponseCode();
log.info("Service returned response code " + responseCode);
} catch (IOException e) {
log.error(e.getMessage(), e);
} finally {
try {
inputStream.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
try {
out.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return responseCode;
}
}
}
@@ -0,0 +1,96 @@
package com.jero.common.util;
import com.jero.common.exception.JeroBootException;
import org.apache.poi.ss.formula.functions.T;
import java.io.File;
/**
* @Author 张代浩
*/
public class MyClassLoader extends ClassLoader {
public static Class<?> getClassByScn(String className) {
Class<?> myclass;
try {
myclass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new JeroBootException(className+" not found!");
}
return myclass;
}
// 获得类的全名,包括包名
public static String getPackPath(Object object) {
// 检查用户传入的参数是否为空
if (object == null) {
throw new java.lang.IllegalArgumentException("参数不能为空!");
}
// 获得类的全名,包括包名
return object.getClass().getName();
}
public static String getAppPath(Class<T> cls) {
// 检查用户传入的参数是否为空
if (cls == null) {
throw new java.lang.IllegalArgumentException("参数不能为空!");
}
ClassLoader loader = cls.getClassLoader();
// 获得类的全名,包括包名
String clsName = cls.getName() + ".class";
// 获得传入参数所在的包
Package pack = cls.getPackage();
StringBuilder path = new StringBuilder();
// 如果不是匿名包,将包名转化为路径
if (pack != null) {
String packName = pack.getName();
// 此处简单判定是否是Java基础类库,防止用户传入JDK内置的类库
if (packName.startsWith("java.") || packName.startsWith("javax.")) {
throw new java.lang.IllegalArgumentException("不要传送系统类!");
}
// 在类的名称中,去掉包名的部分,获得类的文件名
clsName = clsName.substring(packName.length() + 1);
// 判定包名是否是简单包名,如果是,则直接将包名转换为路径,
if (!packName.contains(".")) {
path = new StringBuilder(packName + File.separator);
} else {// 否则按照包名的组成部分,将包名转换为路径
int start = 0;
int end = packName.indexOf(".");
while (end != -1) {
path.append(packName.substring(start, end)).append(File.separator);
start = end + 1;
end = packName.indexOf(".", start);
}
path.append(packName.substring(start)).append(File.separator);
}
}
// 调用ClassLoader的getResource方法,传入包含路径信息的类文件名
java.net.URL url = loader.getResource(path + clsName);
// 从URL对象中获取路径信息
String realPath = url.getPath();
// 去掉路径信息中的协议名"file:"
int pos = realPath.indexOf("file:");
if (pos > -1) {
realPath = realPath.substring(pos + 5);
}
// 去掉路径信息最后包含类文件信息的部分,得到类所在的路径
pos = realPath.indexOf(path + clsName);
realPath = realPath.substring(0, pos - 1);
// 如果类文件被打包到JAR等文件中时,去掉对应的JAR等打包文件名
if (realPath.endsWith("!")) {
realPath = realPath.substring(0, realPath.lastIndexOf("/"));
}
/*------------------------------------------------------------
ClassLoader的getResource方法使用了utf-8对路径信息进行了编码,当路径
中存在中文和空格时,他会对这些字符进行转换,这样,得到的往往不是我们想要
的真实路径,在此,调用了URLDecoder的decode方法进行解码,以便得到原始的
中文及空格路径
-------------------------------------------------------------*/
try {
realPath = java.net.URLDecoder.decode(realPath, "utf-8");
} catch (Exception e) {
throw new JeroBootException(e);
}
return realPath;
}// getAppPath定义结束
}
@@ -0,0 +1,236 @@
package com.jero.common.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.SecureRandom;
@Component
public class PasswordUtil {
private PasswordUtil(){
}
/**
* JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES
* PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1
* */
/**
* 定义使用的算法为:PBEWITHMD5andDES算法
*/
//加密算法
public static String ALGORITHM;
@Value("${jero.password.pbe.algorithm}")
private String algorithmStr;
@PostConstruct
public void setAlgorithm(){
synchronized (PasswordUtil.class){
if(ALGORITHM == null){
ALGORITHM = this.algorithmStr;
}
}
}
public static String SALT;
//密钥
@Value("${jero.password.pbe.salt}")
private String saltStr;
@PostConstruct
public void setSalt(){
synchronized (PasswordUtil.class){
if(SALT == null){
SALT = this.saltStr;
}
}
}
/**
* 定义迭代次数为1000次
*/
private static final int ITERATIONCOUNT = 1000;
/**
* 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节
*
* @return byte[] 盐值
* */
public static byte[] getSalt() {
// 实例化安全随机数
SecureRandom random = new SecureRandom();
// 产出盐
return random.generateSeed(8);
}
public static byte[] getStaticSalt() {
// 产出盐
return SALT.getBytes();
}
/**
* 根据PBE密码生成一把密钥
*
* @param password
* 生成密钥时所使用的密码
* @return Key PBE算法密钥
* */
private static Key getPBEKey(String password) {
// 实例化使用的算法
SecretKeyFactory keyFactory;
SecretKey secretKey = null;
try {
keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
// 设置PBE密钥参数
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
// 生成密钥
secretKey = keyFactory.generateSecret(keySpec);
} catch (Exception e) {
// Auto-generated catch block
e.printStackTrace();
}
return secretKey;
}
/**
* 加密明文字符串
*
* @param plaintext
* 待加密的明文字符串
* @param password
* 生成密钥时所使用的密码
* @param salt
* 盐值
* @return 加密后的密文字符串
* @throws Exception
*/
public static String encrypt(String plaintext, String password, String salt) {
Key key = getPBEKey(password);
byte[] encipheredData = null;
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
//update-begin-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
encipheredData = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
//update-end-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
} catch (Exception e) {
e.printStackTrace();
}
return bytesToHexString(encipheredData);
}
/**
* 自定义加密明文字符串
*
* @param plaintext
* 待加密的明文字符串
* @return 加密后的密文字符串
* @throws Exception
*/
public static String encrypt(String plaintext) {
return encrypt(plaintext, ALGORITHM, SALT);
}
/**
* 解密密文字符串
*
* @param ciphertext
* 待解密的密文字符串
* @param password
* 生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
* @param salt
* 盐值(如需解密,该参数需要与加密时使用的一致)
* @return 解密后的明文字符串
* @throws Exception
*/
public static String decrypt(String ciphertext, String password, String salt) {
Key key = getPBEKey(password);
byte[] passDec = null;
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
passDec = cipher.doFinal(hexStringToBytes(ciphertext));
}catch (Exception e) {
// handle exception
}
return new String(passDec);
}
/**
* 自定义加密明文字符串
*
* @param ciphertext
* 待解密的密文字符串
* @return 解密后的明文字符串
* @throws Exception
*/
public static String decrypt(String ciphertext) {
return decrypt(ciphertext, ALGORITHM, SALT);
}
/**
* 将字节数组转换为十六进制字符串
*
* @param src
* 字节数组
* @return
*/
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* 将十六进制字符串转换为字节数组
*
* @param hexString
* 十六进制字符串
* @return
*/
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || "".equals(hexString)) {
return new byte[0];
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]) & 0xff);
}
return d;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
}
@@ -0,0 +1,86 @@
package com.jero.common.util;
import java.util.Collection;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
/**
* 使用Spring自身提供的地址匹配工具匹配URL
*/
@Slf4j
public class PathMatcherUtil {
public static void main(String[] args) {
String url = "/sys/dict/loadDictOrderByValue/tree,s2,2";
String p = "/sys/dict/loadDictOrderByValue/*";
log.info("" + PathMatcherUtil.match(p,url));
}
/**
* 实际验证路径匹配权限
*
* @param matchPath 权限url
* @param path 访问路径
* @return 是否拥有权限
*/
public static boolean match(String matchPath, String path) {
SpringAntMatcher springAntMatcher = new SpringAntMatcher(matchPath, true);
return springAntMatcher.matches(path);
}
/**
* 实际验证路径匹配权限
*
* @param list 权限url
* @param path 访问路径
* @return 是否拥有权限
*/
public static boolean matches(Collection<String> list, String path) {
for (String s : list) {
SpringAntMatcher springAntMatcher = new SpringAntMatcher(s, true);
if (springAntMatcher.matches(path)) {
return true;
}
}
return false;
}
/**
* 地址表达式匹配工具
*/
private static class SpringAntMatcher implements Matcher {
private final AntPathMatcher antMatcher;
private final String pattern;
private SpringAntMatcher(String pattern, boolean caseSensitive) {
this.pattern = pattern;
this.antMatcher = createMatcher(caseSensitive);
}
@Override
public boolean matches(String path) {
return this.antMatcher.match(this.pattern, path);
}
@Override
public Map<String, String> extractUriTemplateVariables(String path) {
return this.antMatcher.extractUriTemplateVariables(this.pattern, path);
}
private static AntPathMatcher createMatcher(boolean caseSensitive) {
AntPathMatcher matcher = new AntPathMatcher();
matcher.setTrimTokens(false);
matcher.setCaseSensitive(caseSensitive);
return matcher;
}
}
private interface Matcher {
boolean matches(String var1);
Map<String, String> extractUriTemplateVariables(String var1);
}
}
@@ -0,0 +1,62 @@
package com.jero.common.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.Date;
import java.util.List;
@Slf4j
@Component
public class PmsUtil {
private static String uploadPath;
@Value("${jero.path.upload}")
public void setUploadPath(String uploadPath) {
synchronized (PmsUtil.class){
if(PmsUtil.uploadPath == null){
PmsUtil.uploadPath = uploadPath;
}
}
}
public static String saveErrorTxtByList(List<String> msg, String name) {
Date d = new Date();
String saveDir = "logs" + File.separator + DateUtils.yyyyMMdd.get().format(d) + File.separator;
String saveFullDir = uploadPath + File.separator + saveDir;
File saveFile = new File(saveFullDir);
if (!saveFile.exists()) {
saveFile.mkdirs();
}
name += DateUtils.yyyymmddhhmmss.get().format(d) + Math.round(Math.random() * 10000);
String saveFilePath = saveFullDir + name + ".txt";
//封装目的地
try (BufferedWriter bw = new BufferedWriter(new FileWriter(saveFilePath))) {
//遍历集合
for (String s : msg) {
//写数据
if (s.contains("_")) {
String[] arr = s.split("_");
bw.write("" + arr[0] + "行:" + arr[1]);
} else {
bw.write(s);
}
bw.write("\r\n");
}
//释放资源
bw.flush();
} catch (Exception e) {
log.info("excel导入生成错误日志文件异常:" + e.getMessage());
}
return saveDir + name + ".txt";
}
}
@@ -0,0 +1,57 @@
package com.jero.common.util;
import java.awt.*;
import java.util.Random;
/**
* @Author: liyawei
* @Description:
* @Date: Created in 0:09 2022/3/8
*/
public class RandomUtils extends org.apache.commons.lang3.RandomUtils {
private static final char[] codeSeq = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9'};
private static final char[] numberArray = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
private static Random random = new Random();
public RandomUtils() {
}
public static final String randomString(int length) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < length; ++i) {
sb.append(String.valueOf(codeSeq[random.nextInt(codeSeq.length)]));
}
return sb.toString();
}
public static final String randomNumberString(int length) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < length; ++i) {
sb.append(String.valueOf(numberArray[random.nextInt(numberArray.length)]));
}
return sb.toString();
}
public static Color randomColor(int fc, int bc) {
int f = fc;
int b = bc;
Random random = new Random();
if (fc > 255) {
f = 255;
}
if (bc > 255) {
b = 255;
}
return new Color(f + random.nextInt(b - f), f + random.nextInt(b - f), f + random.nextInt(b - f));
}
public static int nextInt(int bound) {
return random.nextInt(bound);
}
}
@@ -0,0 +1,116 @@
package com.jero.common.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class RedisLockHelper {
private long sleepTime = 100;
/**
* 直接使用setnx + expire方式获取分布式锁
* 非原子性
*
* @param key
* @param value
* @param timeout
* @return
*/
public boolean lockSetNx(RedisUtil redisTemplate, String key, String value, int timeout) {
if ( redisTemplate.setnx(key, value)) {
return redisTemplate.expire(key, timeout);
} else {
return false;
}
}
/**
* 使用Lua脚本,脚本中使用setnex+expire命令进行加锁操作
*
* @param redisTemplate
* @param key
* @param uniqueId
* @param seconds
* @return
*/
public boolean lockWithLua(RedisUtil redisTemplate, String key, String uniqueId, int seconds) {
if(!Objects.isNull(seconds)){
log.info("未使用参数:" + seconds);
}
String luaScript = "if redis.call('setnx',KEYS[1],ARGV[1]) == 1 then" +
"redis.call('expire',KEYS[1],ARGV[2]) return 1 else return 0 end";
Object result = redisTemplate.eval(RedisScript.of(luaScript), Collections.singletonList(key), uniqueId);
//判断是否成功
return result.equals(1L);
}
/**
* 在Redis的2.6.12及以后中,使用 set key value [NX] [EX] 命令
*
* @param key
* @param value
* @param timeout
* @return
*/
public boolean lock(RedisUtil redisTemplate, String key, String value, int timeout, TimeUnit timeUnit) {
long seconds = timeUnit.toSeconds(timeout);
return redisTemplate.setnx(key, value, seconds);
}
/**
* 自定义获取锁的超时时间
*
* @param redisTemplate
* @param key
* @param value
* @param timeout
* @param waitTime
* @param timeUnit
* @return
* @throws InterruptedException
*/
public boolean lockWithWaitTime(RedisUtil redisTemplate, String key, String value, int timeout, long waitTime, TimeUnit timeUnit) throws InterruptedException {
long seconds = timeUnit.toSeconds(timeout);
while (waitTime >= 0) {
if (redisTemplate.setnx(key, value, seconds)) {
return true;
}
waitTime -= sleepTime;
Thread.sleep(sleepTime);
}
return false;
}
/**
* 错误的解锁方法—直接删除key
*
* @param key
*/
public void unlockWithDel(RedisUtil redisTemplate, String key) {
redisTemplate.del(key);
}
/**
* 使用Lua脚本进行解锁操纵,解锁的时候验证value值
*
* @param redisTemplate
* @param key
* @param value
* @return
*/
public boolean unlock(RedisUtil redisTemplate, String key, String value) {
String luaScript = "if redis.call('get',KEYS[1]) == ARGV[1] then " +
"return redis.call('del',KEYS[1]) else return 0 end";
DefaultRedisScript<Long> redisScript =new DefaultRedisScript<> ();
redisScript.setScriptText(luaScript);
// 这个值类型要跟lua返回值类型一致才行,否则就会报 java.lang.IllegalStateException
redisScript.setResultType(Long.class);
return redisTemplate.eval(redisScript, Collections.singletonList(key), value);
}
}
@@ -0,0 +1,250 @@
package com.jero.common.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
/**
* @author 张代浩
* @desc 通过反射来动态调用get 和 set 方法
*/
@Slf4j
public class ReflectHelper {
private Class<?> cls;
/**
* 传过来的对象
*/
private Object obj;
/**
* 存放get方法
*/
private HashMap<String, Method> getMethods = null;
/**
* 存放set方法
*/
private HashMap<String, Method> setMethods = null;
/**
* 定义构造方法 -- 一般来说是个pojo
*
* @param o 目标对象
*/
public ReflectHelper(Object o) {
obj = o;
initMethods();
}
/**
* @desc 初始化
*/
public void initMethods() {
getMethods = new HashMap<>();
setMethods = new HashMap<>();
cls = obj.getClass();
Method[] methods = cls.getMethods();
// 定义正则表达式,从方法中过滤出getter / setter 函数.
String gs = "get(\\w+)";
Pattern getM = Pattern.compile(gs);
String ss = "set(\\w+)";
Pattern setM = Pattern.compile(ss);
// 把方法中的"set" 或者 "get" 去掉
String rapl = "$1";
String param;
for (int i = 0; i < methods.length; ++i) {
Method m = methods[i];
String methodName = m.getName();
if (Pattern.matches(gs, methodName)) {
param = getM.matcher(methodName).replaceAll(rapl).toLowerCase();
getMethods.put(param, m);
} else if (Pattern.matches(ss, methodName)) {
param = setM.matcher(methodName).replaceAll(rapl).toLowerCase();
setMethods.put(param, m);
}
}
}
/**
* @desc 调用set方法
*/
public boolean setMethodValue(String property, Object object) {
Method m = setMethods.get(property.toLowerCase());
if (m != null) {
try {
// 调用目标类的setter函数
m.invoke(obj, object);
return true;
} catch (Exception ex) {
log.info("invoke getter on " + property + " error: " + ex.toString());
return false;
}
}
return false;
}
/**
* @desc 调用set方法
*/
public Object getMethodValue(String property) {
Object value = null;
Method m = getMethods.get(property.toLowerCase());
if (m != null) {
try {
/*
* 调用obj类的setter函数
*/
value = m.invoke(obj);
} catch (Exception ex) {
log.info("invoke getter on " + property + " error: " + ex.toString());
}
}
return value;
}
/**
* 把map中的内容全部注入到obj中
*
* @param data
* @return
*/
public Object setAll(Map<String, Object> data) {
if (data == null || data.keySet().isEmpty()) {
return null;
}
for (Entry<String, Object> entry : data.entrySet()) {
this.setMethodValue(entry.getKey(), entry.getValue());
}
return obj;
}
/**
* 把map中的内容全部注入到obj中
*
* @param o
* @param data
* @return
*/
public static Object setAll(Object o, Map<String, Object> data) {
ReflectHelper reflectHelper = new ReflectHelper(o);
reflectHelper.setAll(data);
return o;
}
/**
* 把map中的内容全部注入到新实例中
*
* @param clazz
* @param data
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T setAll(Class<T> clazz, Map<String, Object> data) {
T o = null;
try {
o = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
o = null;
return o;
}
return (T) setAll(o, data);
}
/**
* 根据传入的class将mapList转换为实体类list
*
* @param mapist
* @param clazz
* @return
*/
public static <T> List<T> transList2Entrys(List<Map<String, Object>> mapist, Class<T> clazz) {
List<T> list = new ArrayList<>();
if (mapist != null && !mapist.isEmpty()) {
for (Map<String, Object> data : mapist) {
list.add(ReflectHelper.setAll(clazz, data));
}
}
return list;
}
/**
* 根据属性名获取属性值
*/
public static Object getFieldValueByName(String fieldName, Object o) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = o.getClass().getMethod(getter);
return method.invoke(o);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取属性值
*/
public static Object getFieldVal(String fieldName, Object o) {
try {
// 暴力反射获取属性
Field field = o.getClass().getDeclaredField(fieldName);
// 设置反射时取消Java的访问检查,暴力访问
ReflectionUtils.makeAccessible(field);
return field.get(o);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取属性名数组
*/
public static String[] getFiledName(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
String[] fieldNames = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
fieldNames[i] = fields[i].getName();
}
return fieldNames;
}
/**
* 获取属性类型(type),属性名(name),属性值(value)的map组成的list
*/
public static List<Map<String, Object>> getFiledsInfo(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
List<Map<String, Object>> list = new ArrayList<>();
Map<String, Object> infoMap;
for (int i = 0; i < fields.length; i++) {
infoMap = new HashMap<>();
infoMap.put("type", fields[i].getType().toString());
infoMap.put("name", fields[i].getName());
infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
list.add(infoMap);
}
return list;
}
/**
* 获取对象的所有属性值,返回一个对象数组
*/
public static Object[] getFiledValues(Object o) {
String[] fieldNames = getFiledName(o);
Object[] value = new Object[fieldNames.length];
for (int i = 0; i < fieldNames.length; i++) {
value[i] = getFieldValueByName(fieldNames[i], o);
}
return value;
}
}
@@ -0,0 +1,129 @@
package com.jero.common.util;
import com.alibaba.fastjson.JSONObject;
import com.jero.common.api.vo.Result;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import java.util.Objects;
/**
* 通过 RESTful 风格的接口操纵 desform 里的数据
*
* @author sunjianlei
*/
public class RestDesformUtil {
private RestDesformUtil(){
}
private static String domain = null;
private static String path = null;
static {
domain = SpringContextUtils.getDomain();
path = oConvertUtils.getString(SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path"));
}
/**
* 查询数据
*
* @param desformCode
* @param dataId
* @param token
* @return
*/
public static Result<T> queryOne(String desformCode, String dataId, String token) {
String url = getBaseUrl(desformCode, dataId).toString();
HttpHeaders headers = getHeaders(token);
ResponseEntity<JSONObject> result = RestUtil.request(url, HttpMethod.GET, headers, null, null, JSONObject.class);
return packageReturn(result);
}
/**
* 新增数据
*
* @param desformCode
* @param formData
* @param token
* @return
*/
public static Result<T> addOne(String desformCode, JSONObject formData, String token) {
return addOrEditOne(desformCode, formData, token, HttpMethod.POST);
}
/**
* 修改数据
*
* @param desformCode
* @param formData
* @param token
* @return
*/
public static Result<T> editOne(String desformCode, JSONObject formData, String token) {
return addOrEditOne(desformCode, formData, token, HttpMethod.PUT);
}
private static Result<T> addOrEditOne(String desformCode, JSONObject formData, String token, HttpMethod method) {
String url = getBaseUrl(desformCode).toString();
HttpHeaders headers = getHeaders(token);
ResponseEntity<JSONObject> result = RestUtil.request(url, method, headers, null, formData, JSONObject.class);
return packageReturn(result);
}
/**
* 删除数据
*
* @param desformCode
* @param dataId
* @param token
* @return
*/
public static Result<T> removeOne(String desformCode, String dataId, String token) {
String url = getBaseUrl(desformCode, dataId).toString();
HttpHeaders headers = getHeaders(token);
ResponseEntity<JSONObject> result = RestUtil.request(url, HttpMethod.DELETE, headers, null, null, JSONObject.class);
return packageReturn(result);
}
private static Result<T> packageReturn(ResponseEntity<JSONObject> result) {
JSONObject json = result.getBody();
if (!Objects.isNull(json)) {
return json.toJavaObject(Result.class);
}
return Result.error("操作失败");
}
private static StringBuilder getBaseUrl() {
StringBuilder builder = new StringBuilder(domain).append(path);
builder.append("/desform/api");
return builder;
}
private static StringBuilder getBaseUrl(String desformCode, String dataId) {
StringBuilder builder = getBaseUrl();
builder.append("/").append(desformCode);
if (dataId != null) {
builder.append("/").append(dataId);
}
return builder;
}
private static StringBuilder getBaseUrl(String desformCode) {
return getBaseUrl(desformCode, null);
}
private static HttpHeaders getHeaders(String token) {
HttpHeaders headers = new HttpHeaders();
String mediaType = MediaType.APPLICATION_JSON_UTF8_VALUE;
headers.setContentType(MediaType.parseMediaType(mediaType));
headers.set("Accept", mediaType);
headers.set("X-Access-Token", token);
return headers;
}
}

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