fix(*) 首次提交Common项目
This commit is contained in:
170
Common/pom.xml
Normal file
170
Common/pom.xml
Normal file
@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>cn.crtech.cloud.common</groupId>
|
||||
<artifactId>Common</artifactId>
|
||||
<version>1.0.1</version>
|
||||
|
||||
<!-- 父工程 -->
|
||||
<parent>
|
||||
<groupId>cn.crtech.cloud.dependencies</groupId>
|
||||
<artifactId>Dependencies</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<!-- 依赖的版本锁定 -->
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
|
||||
<fastjson.version>1.2.83</fastjson.version>
|
||||
<thumbnailator.version>0.4.9</thumbnailator.version>
|
||||
<druid.version>1.2.8</druid.version>
|
||||
<mysql.version>8.0.27</mysql.version>
|
||||
<jackson.databind.version>2.8.8</jackson.databind.version>
|
||||
<jackson.mapper.asl.version>1.9.13</jackson.mapper.asl.version>
|
||||
<wildfly.version>1.5.2.Final</wildfly.version>
|
||||
<aliyun.sdk.version>4.0.3</aliyun.sdk.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-context</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- tk-mybatis -->
|
||||
<dependency>
|
||||
<groupId>tk.mybatis</groupId>
|
||||
<artifactId>mapper-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- page-helper -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- hutool -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>io.lettuce</groupId>
|
||||
<artifactId>lettuce-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- druid-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- thumbnailator -->
|
||||
<dependency>
|
||||
<groupId>net.coobird</groupId>
|
||||
<artifactId>thumbnailator</artifactId>
|
||||
<version>${thumbnailator.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mysql -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--JsonFormat-->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.databind.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
<version>${jackson.mapper.asl.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- wildfly -->
|
||||
<dependency>
|
||||
<groupId>org.wildfly.common</groupId>
|
||||
<artifactId>wildfly-common</artifactId>
|
||||
<version>${wildfly.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里云短信 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-core</artifactId>
|
||||
<version>${aliyun.sdk.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,11 @@
|
||||
package cn.crtech.cloud.common.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented // 文档
|
||||
@Retention(RetentionPolicy.RUNTIME) // 在运行时可以获取
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE }) // 作用到字段上
|
||||
public @interface DataExportAnnotation {
|
||||
//导出字段名称
|
||||
String value() default "";
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package cn.crtech.cloud.common.api;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* 阿里云模板配置
|
||||
*/
|
||||
public enum ALiYunSMSEnum {
|
||||
SMS_133972087("SECTION_CHECK_IN_CODE");
|
||||
|
||||
private String typeCode;
|
||||
|
||||
public String getTypeCode() {
|
||||
return typeCode;
|
||||
}
|
||||
|
||||
public void setTypeCode(String typeCode) {
|
||||
this.typeCode = typeCode;
|
||||
}
|
||||
|
||||
ALiYunSMSEnum(String typeCode) {
|
||||
this.typeCode = typeCode;
|
||||
}
|
||||
|
||||
public static ALiYunSMSEnum getEnumValue(String typeCode) {
|
||||
if (!StringUtils.isEmpty(typeCode)) {
|
||||
for (ALiYunSMSEnum sendCodeEnum : ALiYunSMSEnum.values()) {
|
||||
if (sendCodeEnum.getTypeCode().equals(typeCode)) {
|
||||
return sendCodeEnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
package cn.crtech.cloud.common.api;
|
||||
|
||||
/**
|
||||
* 通用返回对象
|
||||
*/
|
||||
public class CommonResult<T> {
|
||||
private long code;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
protected CommonResult() {
|
||||
}
|
||||
|
||||
protected CommonResult(long code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功返回结果
|
||||
*
|
||||
* @param data 获取的数据
|
||||
*/
|
||||
public static <T> CommonResult<T> success(T data) {
|
||||
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功返回结果
|
||||
*
|
||||
* @param data 获取的数据
|
||||
* @param message 提示信息
|
||||
*/
|
||||
public static <T> CommonResult<T> success(T data, String message) {
|
||||
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败返回结果
|
||||
* @param errorCode 错误码
|
||||
*/
|
||||
public static <T> CommonResult<T> failed(IErrorCode errorCode) {
|
||||
return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败返回结果
|
||||
* @param errorCode 错误码
|
||||
* @param message 错误信息
|
||||
*/
|
||||
public static <T> CommonResult<T> failed(IErrorCode errorCode, String message) {
|
||||
return new CommonResult<T>(errorCode.getCode(), message, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败返回结果
|
||||
* @param message 提示信息
|
||||
*/
|
||||
public static <T> CommonResult<T> failed(String message) {
|
||||
return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败返回结果
|
||||
*/
|
||||
public static <T> CommonResult<T> failed() {
|
||||
return failed(ResultCode.FAILED);
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数验证失败返回结果
|
||||
*/
|
||||
public static <T> CommonResult<T> validateFailed() {
|
||||
return failed(ResultCode.VALIDATE_FAILED);
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数验证失败返回结果
|
||||
* @param message 提示信息
|
||||
*/
|
||||
public static <T> CommonResult<T> validateFailed(String message) {
|
||||
return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 未登录返回结果
|
||||
*/
|
||||
public static <T> CommonResult<T> unauthorized(T data) {
|
||||
return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 未授权返回结果
|
||||
*/
|
||||
public static <T> CommonResult<T> forbidden(T data) {
|
||||
return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
|
||||
}
|
||||
|
||||
public long getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(long code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package cn.crtech.cloud.common.api;
|
||||
|
||||
/**
|
||||
* 封装API的错误码
|
||||
*/
|
||||
public interface IErrorCode {
|
||||
long getCode();
|
||||
|
||||
String getMessage();
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.crtech.cloud.common.api;
|
||||
|
||||
/**
|
||||
* 枚举了一些常用API操作码
|
||||
*/
|
||||
public enum ResultCode implements IErrorCode {
|
||||
SUCCESS(200, "操作成功"),
|
||||
FAILED(500, "操作失败"),
|
||||
VALIDATE_FAILED(404, "参数检验失败"),
|
||||
UNAUTHORIZED(401, "暂未登录或token已经过期"),
|
||||
FORBIDDEN(403, "没有相关权限");
|
||||
private long code;
|
||||
private String message;
|
||||
|
||||
private ResultCode(long code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public long getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package cn.crtech.cloud.common.constant;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AuthConstant {
|
||||
public static final String AUTHORITY_PREFIX = "ROLE_";
|
||||
public static final String AUTHORITY_CLAIM_NAME = "authorities";
|
||||
public static final String APP_SPECIAL_AUTHORITY_SUFFIX = "_Limit_Authority";
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package cn.crtech.cloud.common.constant;
|
||||
|
||||
/**
|
||||
* 消息常量
|
||||
*/
|
||||
public class MessageConstant {
|
||||
public static final String LOGIN_SUCCESS = "登录成功!";
|
||||
public static final String USERNAME_PASSWORD_ERROR = "用户名或密码错误!";
|
||||
public static final String CREDENTIALS_EXPIRED = "该账户的登录凭证已过期,请重新登录!";
|
||||
public static final String ACCOUNT_DISABLED = "该账户已被禁用,请联系管理员!";
|
||||
public static final String ACCOUNT_LOCKED = "该账号已被锁定,请联系管理员!";
|
||||
public static final String ACCOUNT_EXPIRED = "该账号已过期,请联系管理员!";
|
||||
public static final String PERMISSION_DENIED = "没有访问权限,请联系管理员!";
|
||||
public static final String ACCOUNT_SIGNATURE_ERROR = "签名校验失败!";
|
||||
public static final String ACCOUNT_UN_REGISTER = "当前用户未注册!";
|
||||
public static final String ACCOUNT_ERROR = "未查找到当前用户!";
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package cn.crtech.cloud.common.constant;
|
||||
|
||||
/**
|
||||
* Redis常量
|
||||
*/
|
||||
public class RedisConstant {
|
||||
public static final String FREE_SERIES_APP_VERSION = "AUTH:FREE:SERIES:APP:VERSION";
|
||||
public static final String FREE_VERSION_API = "AUTH:FREE_RESOURCE_ROLES_MAP:${SERIESCODE}:${APPCODE}:${VERSION}";
|
||||
public static final String RESOURCE_ROLES_MAP = "AUTH:RESOURCE_ROLES_MAP";
|
||||
public static final String RESOURCE_ADMIN_MAP = "AUTH:RESOURCE_ADMIN_MAP";
|
||||
public static final String DEFAULT_ROLES_MAP = "AUTH:DEDEFAULT_ROLES_MAPFAULT_ROLES_MAP";
|
||||
public static final String CURRENT_USREINFO = "USER:CURRENT_USERINFO:";
|
||||
public static final String CURRENT_WX_USREINFO = "USER:CURRENT_WX_USERINFO:";
|
||||
public static final String LIMIT_AUTHORITY_API_MAP = "AUTH:LIMIT_AUTHORITY_API_MAP";
|
||||
public static final String APP_FEIGN_API_MAP = "AUTH:APP_FEIGN_API_MAP";
|
||||
}
|
||||
86
Common/src/main/java/cn/crtech/cloud/common/dto/Result.java
Normal file
86
Common/src/main/java/cn/crtech/cloud/common/dto/Result.java
Normal file
@ -0,0 +1,86 @@
|
||||
package cn.crtech.cloud.common.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 系统返统一回结果实体类
|
||||
*/
|
||||
public class Result implements Serializable {
|
||||
private String message;
|
||||
|
||||
private Object data;
|
||||
|
||||
private boolean success;
|
||||
|
||||
public Result() {
|
||||
}
|
||||
|
||||
public Result(String message, boolean success) {
|
||||
this.message = message;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Object data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static Result success() {
|
||||
Result result = new Result();
|
||||
result.message = "操作成功";
|
||||
result.success = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Result success(Object data) {
|
||||
Result result = Result.success();
|
||||
result.data = data;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Result success(Object data, String operation) {
|
||||
Result result = Result.success();
|
||||
result.data = data;
|
||||
result.message = operation;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Result error() {
|
||||
Result result = new Result();
|
||||
result.message = "操作失败";
|
||||
result.success = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Result error(Object data) {
|
||||
Result result = Result.error();
|
||||
result.data = data;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Result error(Object data, String operation) {
|
||||
Result result = Result.error();
|
||||
result.data = data;
|
||||
result.message = operation;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
76
Common/src/main/java/cn/crtech/cloud/common/dto/UserDto.java
Normal file
76
Common/src/main/java/cn/crtech/cloud/common/dto/UserDto.java
Normal file
@ -0,0 +1,76 @@
|
||||
package cn.crtech.cloud.common.dto;
|
||||
|
||||
import cn.crtech.cloud.common.annotation.DataExportAnnotation;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author : yj
|
||||
* Date : 2021-01-14
|
||||
* Description:
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class UserDto {
|
||||
private String companyCode;
|
||||
|
||||
private String companyName;
|
||||
|
||||
private String userName;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private List<String> roles;
|
||||
|
||||
private Boolean companyAdmin;
|
||||
|
||||
@DataExportAnnotation("主键id")
|
||||
private Integer id;
|
||||
|
||||
@DataExportAnnotation("姓名")
|
||||
private String name;
|
||||
|
||||
@DataExportAnnotation("身份证")
|
||||
private String idCard;
|
||||
|
||||
@DataExportAnnotation("昵称")
|
||||
private String nickName;
|
||||
|
||||
@DataExportAnnotation("最后修改人")
|
||||
private Long lastModifier;
|
||||
|
||||
@DataExportAnnotation("最后修时间")
|
||||
private Date lastModifyTime;
|
||||
|
||||
@DataExportAnnotation("状态")
|
||||
private Integer state;
|
||||
|
||||
@DataExportAnnotation("手机号码")
|
||||
private String mobile;
|
||||
|
||||
@DataExportAnnotation("邮箱")
|
||||
private String email;
|
||||
|
||||
@DataExportAnnotation("头像")
|
||||
private String avatar;
|
||||
|
||||
@DataExportAnnotation("密码")
|
||||
private String password;
|
||||
|
||||
@DataExportAnnotation("身份证正面")
|
||||
private String idCardPrev;
|
||||
|
||||
@DataExportAnnotation("身份证反面")
|
||||
private String idCardNext;
|
||||
|
||||
@DataExportAnnotation("真实姓名")
|
||||
private String realName;
|
||||
|
||||
@DataExportAnnotation("注册时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date regTime;
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package cn.crtech.cloud.common.plugins;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 自定义日志实体类
|
||||
*/
|
||||
public class Logger {
|
||||
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Logger.class);
|
||||
|
||||
public static void info(String msg) {
|
||||
logger.info(msg);
|
||||
}
|
||||
|
||||
public static void error(String msg) {
|
||||
logger.error(msg);
|
||||
}
|
||||
|
||||
public static void debug(String msg) {
|
||||
info(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化
|
||||
*
|
||||
* @param jsonStr 字符串
|
||||
* @return 返回处理结果
|
||||
*/
|
||||
public static String formatJson(String jsonStr) {
|
||||
if (null == jsonStr || "".equals(jsonStr)) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("\n");
|
||||
char last = '\0';
|
||||
char current = '\0';
|
||||
int indent = 0;
|
||||
for (int i = 0; i < jsonStr.length(); i++) {
|
||||
last = current;
|
||||
current = jsonStr.charAt(i);
|
||||
|
||||
//遇到{ [换行,且下一行缩进
|
||||
switch (current) {
|
||||
case '{':
|
||||
case '[':
|
||||
sb.append(current);
|
||||
sb.append('\n');
|
||||
indent++;
|
||||
addIndentBlank(sb, indent);
|
||||
break;
|
||||
|
||||
//遇到} ]换行,当前行缩进
|
||||
case '}':
|
||||
case ']':
|
||||
sb.append('\n');
|
||||
indent--;
|
||||
addIndentBlank(sb, indent);
|
||||
sb.append(current);
|
||||
break;
|
||||
|
||||
//遇到,换行
|
||||
case ',':
|
||||
sb.append(current);
|
||||
if (last != '\\') {
|
||||
sb.append('\n');
|
||||
addIndentBlank(sb, indent);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sb.append(current);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加space
|
||||
*
|
||||
* @param sb 字符串
|
||||
* @param indent 位置
|
||||
*/
|
||||
private static void addIndentBlank(StringBuilder sb, int indent) {
|
||||
for (int i = 0; i < indent; i++) {
|
||||
sb.append('\t');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package cn.crtech.cloud.common.plugins;
|
||||
|
||||
import cn.crtech.cloud.common.api.ALiYunSMSEnum;
|
||||
import cn.crtech.cloud.common.utils.SendSMSUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 阿里短信发送工具类
|
||||
*/
|
||||
@Component
|
||||
public class SendMessageService {
|
||||
public Map<String, Object> send(Map<String, Object> map) throws Exception {
|
||||
Map<String, Object> ret = null;
|
||||
if (!map.containsKey("cretch-cloud")) {
|
||||
Logger.info("采用凌凯短信平台发送...");
|
||||
ret = sendHttp(map);
|
||||
} else {
|
||||
Logger.info("采用阿里云平台发送...");
|
||||
ret = sendCloud(map);
|
||||
}
|
||||
Logger.info(JSON.toJSONString(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Map<String, Object> sendHttp(Map<String, Object> map) throws Exception {
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
if (!map.containsKey("mobile")) {
|
||||
resultMap.put("success", false);
|
||||
resultMap.put("message", "手机号不能为空!");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
if (!map.containsKey("content")) {
|
||||
resultMap.put("success", false);
|
||||
resultMap.put("message", "消息内容不能为空!");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
int success = SendSMSUtils.sendLingKaiSMS(map);
|
||||
if (success > 0) {
|
||||
resultMap.put("success", true);
|
||||
resultMap.put("message", "短信发送成功!");
|
||||
} else {
|
||||
resultMap.put("success", false);
|
||||
resultMap.put("message", "短信服务器出错!");
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
private Map<String, Object> sendCloud(Map<String, Object> map) {
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
if (map.get("mobiles") == null) {
|
||||
resultMap.put("success", false);
|
||||
resultMap.put("message", "手机号不能为空!");
|
||||
return resultMap;
|
||||
} else if (map.get("templateCode") == null) {
|
||||
resultMap.put("success", false);
|
||||
resultMap.put("message", "模版Code不能为空!");
|
||||
return resultMap;
|
||||
} else {
|
||||
String code = map.get("templateCode").toString();
|
||||
ALiYunSMSEnum codeEnum = ALiYunSMSEnum.getEnumValue(code);
|
||||
if (code == null || codeEnum == null) {
|
||||
resultMap.put("success", false);
|
||||
resultMap.put("message", "模版Code错误!");
|
||||
} else {
|
||||
String mobile = map.get("mobile").toString();
|
||||
JSONObject jo = SendSMSUtils.sendALiYunSMS(map, mobile, codeEnum.name());
|
||||
Logger.info(jo.toJSONString());
|
||||
if ("OK".equals(jo.get("Code"))) {
|
||||
resultMap.put("success", true);
|
||||
resultMap.put("message", "短信发送成功!");
|
||||
} else {
|
||||
Logger.info(jo.toJSONString());
|
||||
resultMap.put("success", false);
|
||||
resultMap.put("message", jo.toJSONString());
|
||||
}
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Common/src/main/java/cn/crtech/cloud/common/pojo/Tree.java
Normal file
27
Common/src/main/java/cn/crtech/cloud/common/pojo/Tree.java
Normal file
@ -0,0 +1,27 @@
|
||||
package cn.crtech.cloud.common.pojo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.persistence.Transient;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public abstract class Tree<T> {
|
||||
@Transient
|
||||
private Object realId;
|
||||
|
||||
@Transient
|
||||
private Object realParentId;
|
||||
|
||||
@Transient
|
||||
private List<T> children;
|
||||
|
||||
//判断是否根节点
|
||||
public abstract Boolean isRoot();
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package cn.crtech.cloud.common.utils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CommonFun {
|
||||
private static long startValue = 0;
|
||||
|
||||
/**
|
||||
* 获取时间戳式的ID值,每秒可取1000个
|
||||
* 长度16位
|
||||
* 格式为:1639 4620 6212 3001 最大为9999 9999 9999 9 999 -》 2286-11-21 01:46:39.999 + 999
|
||||
* @return
|
||||
*/
|
||||
public static synchronized long getSSID() {
|
||||
String id;
|
||||
startValue++;
|
||||
startValue = startValue % 1000;
|
||||
java.text.DecimalFormat format = new java.text.DecimalFormat("000");
|
||||
|
||||
String sStartValue = format.format(startValue);
|
||||
String sDate = String.valueOf(System.currentTimeMillis());
|
||||
id = sDate + sStartValue;
|
||||
return Long.parseLong(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取md5式的ID值
|
||||
* @return
|
||||
*/
|
||||
public static synchronized String getUUID() {
|
||||
String id = UUID.randomUUID().toString();
|
||||
id = id.replaceAll("-", "");
|
||||
id = id.toUpperCase();
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
package cn.crtech.cloud.common.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class EncryptUtil {
|
||||
protected static final Logger logger = LoggerFactory.getLogger(EncryptUtil.class);
|
||||
|
||||
public EncryptUtil() {
|
||||
}
|
||||
|
||||
public static String parseByte2HexStr(byte[] buf) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
for(int i = 0; i < buf.length; ++i) {
|
||||
String hex = Integer.toHexString(buf[i] & 255);
|
||||
if (hex.length() == 1) {
|
||||
hex = '0' + hex;
|
||||
}
|
||||
|
||||
sb.append(hex.toUpperCase());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static byte[] parseHexStr2Byte(String hexStr) {
|
||||
if (hexStr.length() < 1) {
|
||||
return null;
|
||||
} else {
|
||||
byte[] result = new byte[hexStr.length() / 2];
|
||||
|
||||
for(int i = 0; i < hexStr.length() / 2; ++i) {
|
||||
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
|
||||
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
|
||||
result[i] = (byte)(high * 16 + low);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] decrypt(byte[] content, String password) {
|
||||
try {
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes());
|
||||
kgen.init(128, secureRandom);
|
||||
SecretKey secretKey = kgen.generateKey();
|
||||
byte[] enCodeFormat = secretKey.getEncoded();
|
||||
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES");
|
||||
cipher.init(2, key);
|
||||
byte[] result = cipher.doFinal(content);
|
||||
return result;
|
||||
} catch (NoSuchAlgorithmException var9) {
|
||||
logger.error(var9.getMessage(), var9);
|
||||
} catch (NoSuchPaddingException var10) {
|
||||
logger.error(var10.getMessage(), var10);
|
||||
} catch (InvalidKeyException var11) {
|
||||
logger.error(var11.getMessage(), var11);
|
||||
} catch (IllegalBlockSizeException var12) {
|
||||
logger.error(var12.getMessage(), var12);
|
||||
} catch (BadPaddingException var13) {
|
||||
logger.error(var13.getMessage(), var13);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] encrypt(String content, String password) {
|
||||
try {
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes());
|
||||
kgen.init(128, secureRandom);
|
||||
SecretKey secretKey = kgen.generateKey();
|
||||
byte[] enCodeFormat = secretKey.getEncoded();
|
||||
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES");
|
||||
byte[] byteContent = content.getBytes("utf-8");
|
||||
cipher.init(1, key);
|
||||
byte[] result = cipher.doFinal(byteContent);
|
||||
return result;
|
||||
} catch (NoSuchAlgorithmException var10) {
|
||||
logger.error(var10.getMessage(), var10);
|
||||
} catch (NoSuchPaddingException var11) {
|
||||
logger.error(var11.getMessage(), var11);
|
||||
} catch (InvalidKeyException var12) {
|
||||
logger.error(var12.getMessage(), var12);
|
||||
} catch (UnsupportedEncodingException var13) {
|
||||
logger.error(var13.getMessage(), var13);
|
||||
} catch (IllegalBlockSizeException var14) {
|
||||
logger.error(var14.getMessage(), var14);
|
||||
} catch (BadPaddingException var15) {
|
||||
logger.error(var15.getMessage(), var15);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String content = "www.server41.com";
|
||||
String password = "THIS SHALL NOT BE SEEN.";
|
||||
System.out.println("加密前:" + content);
|
||||
byte[] encryptResult = encrypt(content, password);
|
||||
String encryptResultStr = parseByte2HexStr(encryptResult);
|
||||
System.out.println("加密后:" + encryptResultStr);
|
||||
byte[] decryptFrom = parseHexStr2Byte(encryptResultStr);
|
||||
byte[] decryptResult = decrypt(decryptFrom, password);
|
||||
System.out.println("解密后:" + new String(decryptResult));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package cn.crtech.cloud.common.utils;
|
||||
|
||||
import tk.mybatis.mapper.genid.GenId;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class IDGenerator implements GenId<String> {
|
||||
@Override
|
||||
public String genId(String s, String s1) {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,59 @@
|
||||
package cn.crtech.cloud.common.utils;
|
||||
|
||||
import cn.crtech.cloud.common.pojo.Tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* author 墨衣
|
||||
* date 2022/3/31
|
||||
* descript
|
||||
**/
|
||||
public class OrganizeTree<T extends Tree> {
|
||||
private List<T> treeList;
|
||||
|
||||
public OrganizeTree(List<T> treeList) {
|
||||
this.treeList = treeList;
|
||||
}
|
||||
|
||||
//建立树形结构
|
||||
public List<T> buildTree() {
|
||||
List<T> tree = new ArrayList<>();
|
||||
for (T node : getRootNode()) {
|
||||
node = buildChildTree(node);
|
||||
tree.add(node);
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
//递归,建立子树形结构
|
||||
private T buildChildTree(T pNode) {
|
||||
List<T> child = new ArrayList<>();
|
||||
for (T node : treeList) {
|
||||
//pNode的id必定存在,node可能存在,可能为null
|
||||
String parentId = node.getRealParentId() == null ? "" : node.getRealParentId().toString();
|
||||
if (pNode.getRealId().toString().equals(parentId)) {
|
||||
child.add(buildChildTree(node));
|
||||
}
|
||||
}
|
||||
if (child.size() != 0) {
|
||||
pNode.setChildren(child);
|
||||
} else {
|
||||
pNode.setChildren(null);
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
//获取根节点
|
||||
private List<T> getRootNode() {
|
||||
List<T> root = new ArrayList<>();
|
||||
for (T node : treeList) {
|
||||
if (node.isRoot()) {
|
||||
root.add(node);
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
package cn.crtech.cloud.common.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyuncs.CommonRequest;
|
||||
import com.aliyuncs.CommonResponse;
|
||||
import com.aliyuncs.DefaultAcsClient;
|
||||
import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.http.MethodType;
|
||||
import com.aliyuncs.profile.DefaultProfile;
|
||||
import jdk.nashorn.internal.runtime.logging.DebugLogger;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
|
||||
public class SendSMSUtils {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DebugLogger.class);
|
||||
private static final SendSMSUtils ourInstance = new SendSMSUtils();
|
||||
|
||||
public static SendSMSUtils getInstance() {
|
||||
return ourInstance;
|
||||
}
|
||||
|
||||
private SendSMSUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param map 模板参数
|
||||
* @param mobiles 手机号码
|
||||
* @param templateCode 模板code
|
||||
* signName
|
||||
* accessKeySecret
|
||||
* accessKeyId
|
||||
* domain
|
||||
* @return 返回处理结果
|
||||
*/
|
||||
public static JSONObject sendALiYunSMS(Map<String, Object> map, String mobiles, String templateCode) {
|
||||
|
||||
String accessKeyId = map.get("accessKeyId").toString();
|
||||
String accessKeySecret = map.get("accessKeySecret").toString();
|
||||
String signName = map.get("signName").toString();
|
||||
String domain = map.get("domain").toString();
|
||||
|
||||
DefaultProfile profile = DefaultProfile.getProfile("default", accessKeyId, accessKeySecret);
|
||||
IAcsClient client = new DefaultAcsClient(profile);
|
||||
|
||||
CommonRequest request = new CommonRequest();
|
||||
request.setMethod(MethodType.POST);
|
||||
request.setDomain(domain);
|
||||
request.setVersion("2017-05-25");
|
||||
request.setAction("SendSms");
|
||||
request.putQueryParameter("PhoneNumbers", mobiles);
|
||||
request.putQueryParameter("SignName", signName);
|
||||
request.putQueryParameter("TemplateCode", templateCode);
|
||||
//移除以下两个不必要的参数
|
||||
map.remove("templateCode");
|
||||
map.remove("platform");
|
||||
String str = JSONObject.toJSONString(map);
|
||||
logger.info("发文:" + str);
|
||||
request.putQueryParameter("TemplateParam", str);
|
||||
JSONObject jo = null;
|
||||
try {
|
||||
CommonResponse response = client.getCommonResponse(request);
|
||||
logger.info(response.getData());
|
||||
jo = JSON.parseObject(response.getData());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
logger.info("返回:" + jo);
|
||||
return jo;
|
||||
}
|
||||
|
||||
/**
|
||||
* int > 0 发送成功!
|
||||
*
|
||||
* mobile 手机号码
|
||||
* content 内容
|
||||
* pwd lingKai配置
|
||||
* domain
|
||||
* corpId
|
||||
*
|
||||
* @return 返回处理结果
|
||||
* @throws Exception 发送异常
|
||||
*/
|
||||
public static int sendLingKaiSMS(Map<String, Object> map) throws Exception {
|
||||
String mobile = map.get("mobile").toString();
|
||||
String content = map.get("content").toString();
|
||||
String corpId = map.get("corpId").toString();
|
||||
String pwd = map.get("pwd").toString();
|
||||
String domain = map.get("domain").toString();
|
||||
|
||||
String send_content = URLEncoder.encode(content, "GB2312");
|
||||
URL url = new URL(domain + "?CorpID=" + corpId + "&Pwd=" + pwd + "&Mobile=" + mobile + "&Content=" + send_content);
|
||||
BufferedReader in;
|
||||
int inputLine = 0;
|
||||
try {
|
||||
logger.info("开始发送短信手机号码为:" + mobile);
|
||||
in = new BufferedReader(new InputStreamReader(url.openStream()));
|
||||
inputLine = new Integer(in.readLine());
|
||||
} catch (Exception e) {
|
||||
logger.info("网络异常,发送短信失败!");
|
||||
inputLine = -2;
|
||||
}
|
||||
logger.info("发送成功!");
|
||||
return inputLine;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,409 @@
|
||||
package cn.crtech.cloud.common.utils;
|
||||
|
||||
import net.coobird.thumbnailator.Thumbnails;
|
||||
import net.coobird.thumbnailator.geometry.Coordinate;
|
||||
import net.coobird.thumbnailator.geometry.Position;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author : yj
|
||||
* Date : 2021-03-29
|
||||
* Description:
|
||||
*/
|
||||
public class ThumbnailatorUtil {
|
||||
/**
|
||||
* 图片尺寸不变,压缩图片文件大小
|
||||
*
|
||||
* @param bytes 图片文件二进制流
|
||||
* @param imageType 图片格式
|
||||
* @param quality 质量因子 1为最高质量
|
||||
* @return
|
||||
*/
|
||||
public static byte[] compressImage(byte[] bytes, String imageType, float quality) {
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
bout = new ByteArrayOutputStream(1024);
|
||||
|
||||
// 图片尺寸不变,压缩图片文件大小outputQuality实现,参数1为最高质量
|
||||
Thumbnails.of(in).scale(1f).outputFormat(imageType).outputQuality(quality).toOutputStream(bout);
|
||||
|
||||
byte[] compressiondata = bout.toByteArray();
|
||||
|
||||
return compressiondata;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (bout != null) {
|
||||
bout.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定宽高压缩图片
|
||||
*
|
||||
* @param bytes 图片文件二进制流
|
||||
* @param width 压缩宽度
|
||||
* @param height 压缩高度
|
||||
* @return
|
||||
*/
|
||||
public static byte[] compressImageWithWH(byte[] bytes, int width, int height) {
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
bout = new ByteArrayOutputStream(1024);
|
||||
|
||||
Thumbnails.of(in).size(width, height).toOutputStream(bout);
|
||||
|
||||
return bout.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (bout != null) {
|
||||
bout.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据比列压缩图片
|
||||
*
|
||||
* @param bytes
|
||||
* @param scale
|
||||
* @return
|
||||
*/
|
||||
public static byte[] compressImageWithScale(byte[] bytes, double scale) {
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
bout = new ByteArrayOutputStream(1024);
|
||||
|
||||
Thumbnails.of(in).scale(scale).toOutputStream(bout);
|
||||
|
||||
return bout.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (bout != null) {
|
||||
bout.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换图片格式
|
||||
*
|
||||
* @param bytes 源图片文件流
|
||||
* @param toformatImageType 转换后图片格式
|
||||
* @return
|
||||
*/
|
||||
public static byte[] formatImage(byte[] bytes, String toformatImageType, int width, int height) {
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
bout = new ByteArrayOutputStream(1024);
|
||||
|
||||
Thumbnails.of(in).size(width, height).outputFormat(toformatImageType).toOutputStream(bout);
|
||||
|
||||
return bout.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (bout != null) {
|
||||
bout.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据坐标裁剪图片
|
||||
*
|
||||
* @param bytes 源图片文件流
|
||||
* @param x 起始x坐标
|
||||
* @param y 起始y坐标
|
||||
* @param x1 结束x坐标
|
||||
* @param y1 结束y坐标
|
||||
* @param keepAspectRatio 默认是按照比例缩放的,值为false 时不按比例缩放
|
||||
* @return
|
||||
*/
|
||||
public static byte[] cutImage(byte[] bytes, int x, int y, int x1, int y1, boolean keepAspectRatio) {
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
bout = new ByteArrayOutputStream(1024);
|
||||
|
||||
int width = x1 - x;
|
||||
int height = y1 - y;
|
||||
Thumbnails.of(in).sourceRegion(x, y, x1, y1).size(width, height).keepAspectRatio(keepAspectRatio).toOutputStream(bout);
|
||||
|
||||
return bout.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (bout != null) {
|
||||
bout.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加图片水印
|
||||
*
|
||||
* @param bytes 源图片文件流
|
||||
* @param width 宽度
|
||||
* @param height 高度
|
||||
* @param position 位置 Positions.BOTTOM_RIGHT
|
||||
* @param watermark 水印图片地址
|
||||
* @param opacity 透明度 0.5f
|
||||
* @param quality 图片质量 0.8f
|
||||
* @return
|
||||
*/
|
||||
public static byte[] addImageWater(byte[] bytes, int width, int height, Position position, String watermark, float opacity, float quality) {
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
bout = new ByteArrayOutputStream(1024);
|
||||
|
||||
Thumbnails.of(in)
|
||||
.size(width, height)
|
||||
// 加水印 参数:1.水印位置 2.水印图片 3.不透明度0.0-1.0
|
||||
.watermark(position, ImageIO.read(new File(watermark)), opacity)
|
||||
.outputQuality(quality)
|
||||
.toOutputStream(bout);
|
||||
|
||||
return bout.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (bout != null) {
|
||||
bout.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加文字水印
|
||||
*
|
||||
* @param bytes
|
||||
* @param position
|
||||
* @param waterText
|
||||
* @param rotate
|
||||
* @param opacity
|
||||
* @param quality
|
||||
* @return
|
||||
*/
|
||||
public static byte[] addTextWater(byte[] bytes, Position position, String waterText, double rotate, float opacity, float quality) {
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
bout = new ByteArrayOutputStream(1024);
|
||||
|
||||
// 设置480x160的大小区域显示水印文本
|
||||
BufferedImage bi = new BufferedImage(480, 160, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = bi.createGraphics();
|
||||
|
||||
// 设置绘图区域透明
|
||||
bi = g.getDeviceConfiguration().createCompatibleImage(480, 160, Transparency.TRANSLUCENT);
|
||||
g.dispose();
|
||||
g = bi.createGraphics();
|
||||
|
||||
// 设置字体类型、大小、加粗、颜色
|
||||
g.setFont(new Font("微软雅黑", Font.BOLD, 32));
|
||||
g.setColor(new Color(0, 0, 0));
|
||||
char[] data = waterText.toCharArray();
|
||||
// 设置文本显示坐标(0,80)
|
||||
g.drawChars(data, 0, data.length, 0, 80);
|
||||
g.dispose();
|
||||
|
||||
Thumbnails.of(in).scale(1).watermark(position, bi, opacity).outputQuality(quality).toOutputStream(bout);
|
||||
|
||||
return bout.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (bout != null) {
|
||||
bout.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 整屏添加文字水印
|
||||
*
|
||||
* @param bytes 源图片二进制流
|
||||
* @param width 图片宽度
|
||||
* @param height 图片高度
|
||||
* @param intervalWidth 间隔宽度
|
||||
* @param intervalHeight 间隔高度
|
||||
* @param waterTextList 水印内容列表
|
||||
* @param fontSize 文字大小
|
||||
* @param opacity 透明度
|
||||
* @param quality 质量
|
||||
* @return
|
||||
*/
|
||||
public static byte[] addTextWaterFullScreen(byte[] bytes, int width, int height, int intervalWidth, int intervalHeight, List<String> waterTextList, int fontSize, float opacity, float quality) {
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
bout = new ByteArrayOutputStream(1024);
|
||||
|
||||
// 设置图片大小区域显示水印文本
|
||||
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
// 创建一个Graphics2D的对象
|
||||
Graphics2D g = bi.createGraphics();
|
||||
|
||||
// 设置绘图区域透明,即背景透明
|
||||
bi = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
|
||||
g.dispose();
|
||||
g = bi.createGraphics();
|
||||
|
||||
// 设置字体类型,加粗,字体大小
|
||||
Font font = new Font("微软雅黑", Font.BOLD, fontSize);
|
||||
g.setFont(font);
|
||||
// 旋转角度(单位:弧度),以圆点(0,0)为圆心,正代表顺时针,负代表逆时针
|
||||
g.rotate(Math.toRadians(-30), 0, 0);
|
||||
// 设置字体颜色
|
||||
g.setColor(new Color(0, 0, 0));
|
||||
int distance = fontSize + 12;
|
||||
int size = waterTextList.size();
|
||||
// 设置文字字体显示坐标位置
|
||||
for (int i = 0; i < size; i++) {
|
||||
char[] data = waterTextList.get(i).toCharArray();
|
||||
g.drawChars(data, 0, data.length, 0, height / 2 + i * distance);
|
||||
}
|
||||
g.dispose();
|
||||
|
||||
Thumbnails.Builder<? extends InputStream> builder = Thumbnails.of(in).scale(1);
|
||||
|
||||
// 添加文字水印
|
||||
int wMod = (int) Math.ceil(width / intervalWidth);
|
||||
int hMod = (int) Math.ceil(height / intervalHeight);
|
||||
for (int i = 0; i <= wMod; i++) {
|
||||
for (int j = 0; j <= hMod; j++) {
|
||||
int x = (i) * intervalWidth - intervalWidth / 2;
|
||||
int y = (j) * intervalHeight - intervalHeight / 2;
|
||||
System.out.println(x + "," + y);
|
||||
builder.watermark(new Coordinate(x, y), bi, opacity);
|
||||
}
|
||||
}
|
||||
|
||||
builder.outputQuality(quality).toOutputStream(bout);
|
||||
|
||||
return bout.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (bout != null) {
|
||||
bout.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 旋转 ,正数:顺时针 负数:逆时针
|
||||
*
|
||||
* @param bytes 源图片文件流
|
||||
* @param width 宽
|
||||
* @param height 高
|
||||
* @param rotate 角度
|
||||
*/
|
||||
public static byte[] rotateImage(byte[] bytes, int width, int height, double rotate) {
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
bout = new ByteArrayOutputStream(1024);
|
||||
|
||||
Thumbnails.of(in).size(width, height).rotate(rotate).toOutputStream(bout);
|
||||
|
||||
return bout.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (bout != null) {
|
||||
bout.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user