11111111111
This commit is contained in:
commit
03316551b3
|
@ -0,0 +1,327 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.2.6</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.tencent</groupId>
|
||||
<artifactId>materialFaceJar</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>materialFaceJar</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>17</java.version>
|
||||
<springboot.version>3.2.6</springboot.version>
|
||||
<httpcore.version>5.2.5</httpcore.version>
|
||||
<httpclilent.version>5.3.1</httpclilent.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.33</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.30</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>3.5.16</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.generator</groupId>
|
||||
<artifactId>mybatis-generator-core</artifactId>
|
||||
<version>1.4.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||
<version>3.5.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.16.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||
<version>4.5.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.10.2</version>
|
||||
<scope>test</scope>
|
||||
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.core5</groupId>
|
||||
<artifactId>httpcore5</artifactId>
|
||||
<version>${httpcore.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.core5</groupId>
|
||||
<artifactId>httpcore5-h2</artifactId>
|
||||
<version>${httpcore.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
<version>${httpclilent.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.3.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-common</artifactId>
|
||||
<version>3.1.1216</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-facefusion</artifactId>
|
||||
<version>3.1.1201</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</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-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>33.2.0-jre</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-commons -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<version>4.1.3</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<profile.active>dev</profile.active>
|
||||
<swaggerEnable>true</swaggerEnable>
|
||||
<jdbcUser>edu_train_dev_user</jdbcUser>
|
||||
<jdbcPassword>dev_user_123#!45*)6</jdbcPassword>
|
||||
<jdbcUrl>jdbc:mysql://${jdbcIp}:${jdbcPort}/edu-train-dev?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Hongkong&useSSL=false&allowMultiQueries=true</jdbcUrl>
|
||||
<jdbcIp>47.97.80.223</jdbcIp>
|
||||
<jdbcPort>13307</jdbcPort>
|
||||
<log4jFile>log4j2-dev.xml</log4jFile>
|
||||
<sqlPrintClass>org.apache.ibatis.logging.stdout.StdOutImpl</sqlPrintClass>
|
||||
<MAX_FILE_SIZE>300MB</MAX_FILE_SIZE>
|
||||
<MAX_REQUEST_FILE_SIZE>500MB</MAX_REQUEST_FILE_SIZE>
|
||||
<HTTP_DEFAULT_PROXY_HOST></HTTP_DEFAULT_PROXY_HOST>
|
||||
<HTTP_DEFAULT_PROXY_PORT>8080</HTTP_DEFAULT_PROXY_PORT>
|
||||
<HTTP_DEFAULT_PROXY_ENABLE>false</HTTP_DEFAULT_PROXY_ENABLE>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>test</id>
|
||||
<properties>
|
||||
<profile.active>test</profile.active>
|
||||
<swaggerEnable>true</swaggerEnable>
|
||||
<jdbcUser>edu_train_dev_user</jdbcUser>
|
||||
<jdbcPassword>dev_user_123#!45*)6</jdbcPassword>
|
||||
<jdbcUrl>jdbc:mysql://${jdbcIp}:${jdbcPort}/edu-train-dev?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Hongkong&useSSL=false&allowMultiQueries=true</jdbcUrl>
|
||||
<jdbcIp>47.97.80.223</jdbcIp>
|
||||
<jdbcPort>13307</jdbcPort>
|
||||
<log4jFile>log4j2</log4jFile>
|
||||
<MAX_FILE_SIZE>300MB</MAX_FILE_SIZE>
|
||||
<MAX_REQUEST_FILE_SIZE>500MB</MAX_REQUEST_FILE_SIZE>
|
||||
<sqlPrintClass>org.apache.ibatis.logging.stdout.StdOutImpl</sqlPrintClass>
|
||||
<HTTP_DEFAULT_PROXY_HOST></HTTP_DEFAULT_PROXY_HOST>
|
||||
<HTTP_DEFAULT_PROXY_PORT>8080</HTTP_DEFAULT_PROXY_PORT>
|
||||
<HTTP_DEFAULT_PROXY_ENABLE>false</HTTP_DEFAULT_PROXY_ENABLE>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>prod</id>
|
||||
<properties>
|
||||
<swaggerEnable>false</swaggerEnable>
|
||||
<jdbcUser>edu_train_dev_user</jdbcUser>
|
||||
<jdbcPassword>dev_user_123#!45*)6</jdbcPassword>
|
||||
<jdbcUrl>jdbc:mysql://${jdbcIp}:${jdbcPort}/edu-train-dev?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Hongkong&useSSL=false&allowMultiQueries=true</jdbcUrl>
|
||||
<jdbcIp>47.97.80.223</jdbcIp>
|
||||
<jdbcPort>13307</jdbcPort>
|
||||
<MAX_FILE_SIZE>300MB</MAX_FILE_SIZE>
|
||||
<MAX_REQUEST_FILE_SIZE>500MB</MAX_REQUEST_FILE_SIZE>
|
||||
<log4jFile>log4j2.xml</log4jFile>
|
||||
<sqlPrintClass>org.apache.ibatis.logging.log4j2.Log4j2Impl</sqlPrintClass>
|
||||
<HTTP_DEFAULT_PROXY_HOST></HTTP_DEFAULT_PROXY_HOST>
|
||||
<HTTP_DEFAULT_PROXY_PORT>8080</HTTP_DEFAULT_PROXY_PORT>
|
||||
<HTTP_DEFAULT_PROXY_ENABLE>false</HTTP_DEFAULT_PROXY_ENABLE>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>
|
||||
src/main/resources
|
||||
</directory>
|
||||
<includes>
|
||||
<include>rcb-${profile.active}/*</include>
|
||||
<include>application.yml</include>
|
||||
<include>application-${profile.active}.yml</include>
|
||||
<include>${log4jFile}</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>
|
||||
src/main/resources
|
||||
</directory>
|
||||
<includes>
|
||||
<include>i18n/*</include>
|
||||
<include>mapper/*</include>
|
||||
<include>*/*.xlsx</include>
|
||||
<include>*/*.xls</include>
|
||||
<include>fonts/*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<configuration>
|
||||
<compilerVersion>17</compilerVersion>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.face.Application</mainClass>
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
<layout>JAR</layout>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,17 @@
|
|||
package com.face;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
|
||||
@EnableScheduling
|
||||
@EnableAsync
|
||||
public class Application {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
|
||||
package com.face;
|
||||
import com.tencentcloudapi.common.AbstractModel;
|
||||
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.facefusion.v20220927.FacefusionClient;
|
||||
import com.tencentcloudapi.facefusion.v20220927.models.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Base64;
|
||||
|
||||
public class PuTongRongHe
|
||||
{
|
||||
public static void main(String [] args) {
|
||||
try{
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||
Credential cred = new Credential("AKIDdGj28B1jKl03tY2YxEJH6jGe8VgvzpbA", "PaXHn6B50pgWEoPr7EXxCIDvTr6AGFA4");
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("facefusion.tencentcloudapi.com");
|
||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||
FacefusionClient client = new FacefusionClient(cred, "ap-chengdu", clientProfile);
|
||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||
FuseFaceRequest req = new FuseFaceRequest();
|
||||
|
||||
|
||||
//活动ID
|
||||
req.setProjectId("at_1895073745956143104");
|
||||
|
||||
|
||||
|
||||
|
||||
Path imageFile = Paths.get("F:\\体验腾讯人脸融合-素材\\222.jpg");
|
||||
byte[] imageBytes = Files.readAllBytes(imageFile);
|
||||
|
||||
|
||||
/*
|
||||
InputStream imageInputStream = new FileInputStream("F:\\体验腾讯人脸融合-素材\\111.jpg");
|
||||
byte[] imageBytes = new byte[imageInputStream.available()];
|
||||
imageInputStream.read(imageBytes);
|
||||
imageInputStream.close();*/
|
||||
|
||||
String imgBase =Base64.getEncoder().encodeToString(imageBytes);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//{"MaterialInfos":[{"MaterialId":"mt_1895077021871144960","MaterialStatus":21,"CreateTime":"2025-02-27 19:42:25","UpdateTime":"2025-02-27 19:42:25","MaterialFaceList":[{"FaceId":"mt_1895077021871144960_1","FaceInfo":{"X":159,"Y":360,"Width":49,"Height":64}}],"MaterialName":"微信图片_20250227194033.png","AuditResult":""},{"MaterialId":"mt_1895077032491122688","MaterialStatus":21,"CreateTime":"2025-02-27 19:42:28","UpdateTime":"2025-02-27 19:42:28","MaterialFaceList":[{"FaceId":"mt_1895077032491122688_1","FaceInfo":{"X":373,"Y":362,"Width":49,"Height":69}}],"MaterialName":"微信图片_20250227194036.png","AuditResult":""},{"MaterialId":"mt_1895077041827643392","MaterialStatus":21,"CreateTime":"2025-02-27 19:42:30","UpdateTime":"2025-02-27 19:42:30","MaterialFaceList":[{"FaceId":"mt_1895077041827643392_1","FaceInfo":{"X":242,"Y":401,"Width":57,"Height":70}}],"MaterialName":"微信图片_20250227194038.png","AuditResult":""}],"Count":3,"RequestId":"3585e437-6a27-4dc9-b59b-11f66ca4382f"}
|
||||
|
||||
|
||||
/* Activity_Id 活动ID
|
||||
Material_Id 素材ID
|
||||
Face_Id 人脸模版*/
|
||||
|
||||
|
||||
//活动里面的素材ID
|
||||
req.setModelId("mt_1895077021871144960");
|
||||
//图片返回方式
|
||||
req.setRspImgType("url");
|
||||
|
||||
MergeInfo mergeInfo=new MergeInfo();
|
||||
mergeInfo.setImage(imgBase);
|
||||
|
||||
//素材人脸和对应FaceID
|
||||
mergeInfo.setTemplateFaceID("mt_1895077021871144960_1");
|
||||
|
||||
MergeInfo [] mergeInfos =new MergeInfo[1];
|
||||
mergeInfos[0]=mergeInfo;
|
||||
|
||||
req.setMergeInfos(mergeInfos);
|
||||
|
||||
// 返回的resp是一个FuseFaceResponse的实例,与请求对象对应
|
||||
FuseFaceResponse resp = client.FuseFace(req);
|
||||
// 输出json格式的字符串回包
|
||||
System.out.println(AbstractModel.toJsonString(resp));
|
||||
} catch (TencentCloudSDKException e) {
|
||||
System.out.println(e.toString());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
package com.face;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.face.jsonBean.QiuTestRoot;
|
||||
import com.tencentcloudapi.common.AbstractModel;
|
||||
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.facefusion.v20220927.FacefusionClient;
|
||||
import com.tencentcloudapi.facefusion.v20220927.models.*;
|
||||
|
||||
public class SuCaiTest
|
||||
{
|
||||
public static void main(String [] args) {
|
||||
try{
|
||||
|
||||
// SecretId:AKIDufDXigQwFWgdNuCG7kCRTHsFPN8fy3yg
|
||||
// SecretKey:kGZheSFrHVWKvHPJ0TikZAXjicJm490d
|
||||
|
||||
// SecretId:AKIDdGj28B1jKl03tY2YxEJH6jGe8VgvzpbA
|
||||
// SecretKey:PaXHn6B50pgWEoPr7EXxCIDvTr6AGFA4
|
||||
|
||||
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||
Credential cred = new Credential("AKIDdGj28B1jKl03tY2YxEJH6jGe8VgvzpbA", "PaXHn6B50pgWEoPr7EXxCIDvTr6AGFA4");
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("facefusion.tencentcloudapi.com");
|
||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||
FacefusionClient client = new FacefusionClient(cred, "ap-chengdu", clientProfile);
|
||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||
DescribeMaterialListRequest req = new DescribeMaterialListRequest();
|
||||
//必须传这个参数
|
||||
//测试API接口 at_1895073745956143104
|
||||
//二次API接口 at_1895077148660760576
|
||||
req.setActivityId("at_1902232245937274880");
|
||||
// 返回的resp是一个DescribeMaterialListResponse的实例,与请求对象对应
|
||||
DescribeMaterialListResponse resp = client.DescribeMaterialList(req);
|
||||
// 输出json格式的字符串回包
|
||||
|
||||
|
||||
String qtest=AbstractModel.toJsonString(resp);
|
||||
System.out.println(qtest);
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
QiuTestRoot person = mapper.readValue(qtest, QiuTestRoot.class);
|
||||
System.out.println(person.getMaterialInfos().get(0).getMaterialFaceList().get(0).getFaceId()); // 输出: John Doe
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
} catch (TencentCloudSDKException e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
package com.face;
|
||||
import com.tencentcloudapi.common.AbstractModel;
|
||||
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.facefusion.v20220927.FacefusionClient;
|
||||
import com.tencentcloudapi.facefusion.v20220927.models.*;
|
||||
|
||||
public class ZhuanYeRongHe
|
||||
{
|
||||
public static void main(String [] args) {
|
||||
try{
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||
Credential cred = new Credential("AKIDdGj28B1jKl03tY2YxEJH6jGe8VgvzpbA", "PaXHn6B50pgWEoPr7EXxCIDvTr6AGFA4");
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("facefusion.tencentcloudapi.com");
|
||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||
FacefusionClient client = new FacefusionClient(cred, "ap-chengdu", clientProfile);
|
||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||
FuseFaceUltraRequest req = new FuseFaceUltraRequest();
|
||||
|
||||
// 返回的resp是一个FuseFaceUltraResponse的实例,与请求对象对应
|
||||
FuseFaceUltraResponse resp = client.FuseFaceUltra(req);
|
||||
// 输出json格式的字符串回包
|
||||
System.out.println(AbstractModel.toJsonString(resp));
|
||||
} catch (TencentCloudSDKException e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.face.attachment.controller;
|
||||
|
||||
import com.face.global.controller.ApiBaseController;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/customer/v1.0/attachment")
|
||||
@Slf4j
|
||||
@Tag(name = "人脸融合基础管理")
|
||||
public class ApiFaceInfoCustomerController extends ApiBaseController {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.face.attachment.controller;
|
||||
|
||||
import com.face.global.controller.ApiBaseController;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/manage/v1.0/attachment")
|
||||
@Slf4j
|
||||
public class ApiFaceInfoManageController extends ApiBaseController {
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
package com.face.attachment.controller;
|
||||
|
||||
|
||||
import com.face.attachment.entity.FaceInfo;
|
||||
import com.face.attachment.service.IFaceInfoService;
|
||||
import com.face.attachment.service.vo.AttachmentVO;
|
||||
import com.face.attachment.vo.*;
|
||||
import com.face.global.controller.ManageBaseController;
|
||||
import com.face.global.vo.ApiResult;
|
||||
import com.face.global.vo.PageResponseVO;
|
||||
import com.face.util.ApiResultBuilder;
|
||||
import com.tencentcloudapi.common.AbstractModel;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import com.tencentcloudapi.facefusion.v20220927.FacefusionClient;
|
||||
import com.tencentcloudapi.facefusion.v20220927.models.FuseFaceRequest;
|
||||
import com.tencentcloudapi.facefusion.v20220927.models.FuseFaceResponse;
|
||||
import com.tencentcloudapi.facefusion.v20220927.models.MergeInfo;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/manage/v1.0/attachment")
|
||||
@Slf4j
|
||||
@Tag(name = "人脸融合基础管理")
|
||||
public class FaceInfoManagerController extends ManageBaseController {
|
||||
|
||||
@Autowired
|
||||
private IFaceInfoService faceInfoService;
|
||||
|
||||
|
||||
|
||||
@Operation(summary = "修改人脸融合基础")
|
||||
@PutMapping("/updateFaceInfo")
|
||||
public ApiResult<Integer> updateFaceInfo(@Valid @RequestBody FaceInfoModRequestVO modRequestVO) throws Exception {
|
||||
FaceInfo faceInfo = faceInfoService.updateFaceInfo(modRequestVO);
|
||||
return ApiResultBuilder.getCommonBuilder(Integer.class).success(faceInfo != null
|
||||
? BigInteger.ONE.intValue() : BigInteger.ZERO.intValue()).build();
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "修改人模版脸图片")
|
||||
@PostMapping("/updateImgFaceInfo")
|
||||
public ApiResult<Integer> updateImgFaceInfo(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam(required = true, value = "faceId") String faceId) throws Exception {
|
||||
FaceInfo faceInfo = faceInfoService.updateImgFaceInfo(file,faceId);
|
||||
return ApiResultBuilder.getCommonBuilder(Integer.class).success(faceInfo != null
|
||||
? BigInteger.ONE.intValue() : BigInteger.ZERO.intValue()).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Operation(summary = "获取人脸融合基础详情")
|
||||
@GetMapping("/getFaceInfo")
|
||||
public ApiResult<FaceInfoDetailResponseVO> getFaceInfo(@RequestParam(value = "id") String id) throws Exception {
|
||||
FaceInfoDetailResponseVO responseVO = faceInfoService.getFaceInfo(id);
|
||||
return ApiResultBuilder.getCommonBuilder(FaceInfoDetailResponseVO.class).success(responseVO).build();
|
||||
}
|
||||
|
||||
@Operation(summary = "分页查询人脸融合基础,包含总数")
|
||||
@PostMapping("/pageAllFaceInfo")
|
||||
public ApiResult<PageResponseVO<FaceInfoPageResponseVO>> pageAll(@Valid @RequestBody FaceInfoPageRequestVO pageRequestVO) throws Exception {
|
||||
PageResponseVO<FaceInfoPageResponseVO> pageResponseVO = this.faceInfoService.pageAll(pageRequestVO);
|
||||
return ApiResultBuilder.getPageCommonBuilder(FaceInfoPageResponseVO.class).success(pageResponseVO).build();
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "根据腾讯活动ID和名称获取数据存入数据库")
|
||||
@PostMapping("/addAllFaceInfoByTx")
|
||||
public ApiResult<List<FaceInfo>> addAllFaceInfoByTx(@Valid @RequestBody FaceInfoTxRequestVO requestVO) throws Exception {
|
||||
return ApiResultBuilder.getListBuilder(FaceInfo.class).success(faceInfoService.addAllFaceInfoByTx(requestVO)).build();
|
||||
}
|
||||
|
||||
@Operation(summary = "获取所有活动")
|
||||
@GetMapping("/queryAllActivity")
|
||||
public ApiResult<List<FaceInfoTxRequestVO>> queryAllActivity() throws Exception {
|
||||
return ApiResultBuilder.getListBuilder(FaceInfoTxRequestVO.class).success(faceInfoService.queryAllActivity()).build();
|
||||
}
|
||||
|
||||
@Operation(summary = "获取所有人脸模版")
|
||||
@PostMapping("/queryAllFaceInfo")
|
||||
public ApiResult<List<FaceInfoDetailResponseVO>> queryAllFaceInfo(@Valid @RequestBody FaceInfoTxRequestVO requestVO) throws Exception {
|
||||
return ApiResultBuilder.getListBuilder(FaceInfoDetailResponseVO.class).success(faceInfoService.queryAllFaceInfo(requestVO)).build();
|
||||
}
|
||||
|
||||
@Operation(summary = "上传单个文件")
|
||||
@PostMapping("/uploadSingleFile")
|
||||
public ApiResult<FuseFaceResponse> uploadSingleFile(
|
||||
@RequestParam("file") MultipartFile file,
|
||||
@RequestParam(required = true, value = "activityId") String activityId,
|
||||
@RequestParam(required = true, value = "materialId") String materialId,
|
||||
@RequestParam(required = true, value = "faceId") String faceId
|
||||
) throws Exception {
|
||||
String imgUrl="";
|
||||
FuseFaceResponse resp=null;
|
||||
|
||||
try{
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||
Credential cred = new Credential("AKIDdGj28B1jKl03tY2YxEJH6jGe8VgvzpbA", "PaXHn6B50pgWEoPr7EXxCIDvTr6AGFA4");
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("facefusion.tencentcloudapi.com");
|
||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||
FacefusionClient client = new FacefusionClient(cred, "ap-chengdu", clientProfile);
|
||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||
FuseFaceRequest req = new FuseFaceRequest();
|
||||
|
||||
|
||||
//活动ID
|
||||
req.setProjectId(activityId);
|
||||
|
||||
|
||||
|
||||
|
||||
// Path imageFile = Paths.get("F:\\体验腾讯人脸融合-素材\\222.jpg");
|
||||
byte[] imageBytes = file.getBytes();
|
||||
|
||||
|
||||
|
||||
/*
|
||||
InputStream imageInputStream = new FileInputStream("F:\\体验腾讯人脸融合-素材\\111.jpg");
|
||||
byte[] imageBytes = new byte[imageInputStream.available()];
|
||||
imageInputStream.read(imageBytes);
|
||||
imageInputStream.close();*/
|
||||
|
||||
String imgBase = Base64.getEncoder().encodeToString(imageBytes);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//{"MaterialInfos":[{"MaterialId":"mt_1895077021871144960","MaterialStatus":21,"CreateTime":"2025-02-27 19:42:25","UpdateTime":"2025-02-27 19:42:25","MaterialFaceList":[{"FaceId":"mt_1895077021871144960_1","FaceInfo":{"X":159,"Y":360,"Width":49,"Height":64}}],"MaterialName":"微信图片_20250227194033.png","AuditResult":""},{"MaterialId":"mt_1895077032491122688","MaterialStatus":21,"CreateTime":"2025-02-27 19:42:28","UpdateTime":"2025-02-27 19:42:28","MaterialFaceList":[{"FaceId":"mt_1895077032491122688_1","FaceInfo":{"X":373,"Y":362,"Width":49,"Height":69}}],"MaterialName":"微信图片_20250227194036.png","AuditResult":""},{"MaterialId":"mt_1895077041827643392","MaterialStatus":21,"CreateTime":"2025-02-27 19:42:30","UpdateTime":"2025-02-27 19:42:30","MaterialFaceList":[{"FaceId":"mt_1895077041827643392_1","FaceInfo":{"X":242,"Y":401,"Width":57,"Height":70}}],"MaterialName":"微信图片_20250227194038.png","AuditResult":""}],"Count":3,"RequestId":"3585e437-6a27-4dc9-b59b-11f66ca4382f"}
|
||||
|
||||
|
||||
/* Activity_Id 活动ID
|
||||
Material_Id 素材ID
|
||||
Face_Id 人脸模版*/
|
||||
|
||||
|
||||
//活动里面的素材ID
|
||||
req.setModelId(materialId);
|
||||
//图片返回方式
|
||||
req.setRspImgType("url");
|
||||
|
||||
MergeInfo mergeInfo=new MergeInfo();
|
||||
mergeInfo.setImage(imgBase);
|
||||
|
||||
//素材人脸和对应FaceID
|
||||
mergeInfo.setTemplateFaceID(faceId);
|
||||
|
||||
MergeInfo [] mergeInfos =new MergeInfo[1];
|
||||
mergeInfos[0]=mergeInfo;
|
||||
|
||||
req.setMergeInfos(mergeInfos);
|
||||
|
||||
// 返回的resp是一个FuseFaceResponse的实例,与请求对象对应
|
||||
resp = client.FuseFace(req);
|
||||
// 输出json格式的字符串回包
|
||||
System.out.println(AbstractModel.toJsonString(resp));
|
||||
|
||||
} catch (TencentCloudSDKException e) {
|
||||
System.out.println(e.toString());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
AttachmentVO vo = new AttachmentVO();
|
||||
return ApiResultBuilder.getCommonBuilder(FuseFaceResponse.class).success(resp).build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.face.attachment.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 人脸融合基础表
|
||||
*
|
||||
* @author admin
|
||||
* @date 2025/03/15
|
||||
*/
|
||||
@Data
|
||||
@TableName("t_face_info")
|
||||
public class FaceInfo {
|
||||
/**
|
||||
* 人脸模版ID
|
||||
*/
|
||||
@TableId
|
||||
private String faceId;
|
||||
|
||||
/**
|
||||
* 横向坐标x
|
||||
*/
|
||||
private Integer x;
|
||||
|
||||
/**
|
||||
* 纵向坐标y
|
||||
*/
|
||||
private Integer y;
|
||||
|
||||
/**
|
||||
* 横向坐标
|
||||
*/
|
||||
private Integer width;
|
||||
|
||||
/**
|
||||
* 坐标高
|
||||
*/
|
||||
private Integer height;
|
||||
|
||||
/**
|
||||
* 素材ID
|
||||
*/
|
||||
private String materialId;
|
||||
|
||||
/**
|
||||
* 素材名称
|
||||
*/
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 活动ID 一个活动多个素材 一个素材多个人脸模版
|
||||
*/
|
||||
private String activityId;
|
||||
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
private String faceUrl;
|
||||
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
private String activityName;
|
||||
|
||||
/**
|
||||
* 图片BASE64编码
|
||||
*/
|
||||
private byte[] faceBase;
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.face.attachment.mapper;
|
||||
|
||||
import com.face.attachment.entity.FaceInfo;
|
||||
import java.util.List;
|
||||
import com.face.attachment.vo.FaceInfoPageRequestVO;
|
||||
import com.face.attachment.vo.FaceInfoPageResponseVO;
|
||||
import com.face.attachment.vo.FaceInfoTxRequestVO;
|
||||
import com.face.global.mapper.GlobalBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@Mapper
|
||||
public interface FaceInfoMapper extends GlobalBaseMapper<FaceInfo, String> {
|
||||
List<FaceInfoPageResponseVO> pageAll(@Param("page") FaceInfoPageRequestVO pageRequestVO);
|
||||
|
||||
Long pageCountAll(@Param("page") FaceInfoPageRequestVO pageRequestVO);
|
||||
|
||||
List<FaceInfoTxRequestVO> queryAllActivity();
|
||||
|
||||
List<FaceInfo> queryAllFaceInfo(@Param("vo") FaceInfoTxRequestVO vo);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.face.attachment.service;
|
||||
|
||||
|
||||
import com.face.attachment.service.vo.AttachmentVO;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
|
||||
|
||||
public interface IAttachmentService {
|
||||
AttachmentVO uploadFile(MultipartFile file) throws Exception;
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.face.attachment.service;
|
||||
|
||||
import com.face.attachment.entity.FaceInfo;
|
||||
import com.face.attachment.vo.*;
|
||||
import com.face.global.service.IGlobalBaseService;
|
||||
import com.face.global.vo.PageResponseVO;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 人脸融合基础表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author admin
|
||||
* @since 2025-03-15
|
||||
*/
|
||||
public interface IFaceInfoService extends IGlobalBaseService<FaceInfo, String> {
|
||||
|
||||
FaceInfo updateFaceInfo(FaceInfoModRequestVO modRequestVO) throws Exception;
|
||||
|
||||
FaceInfo updateImgFaceInfo(MultipartFile file,String faceId) throws Exception;
|
||||
|
||||
|
||||
|
||||
|
||||
FaceInfoDetailResponseVO getFaceInfo(String id) throws Exception;
|
||||
|
||||
PageResponseVO<FaceInfoPageResponseVO> pageAll(FaceInfoPageRequestVO pageRequestVO) throws Exception;
|
||||
|
||||
List<FaceInfo> addAllFaceInfoByTx(FaceInfoTxRequestVO requestVO);
|
||||
|
||||
List<FaceInfoTxRequestVO> queryAllActivity();
|
||||
|
||||
List<FaceInfoDetailResponseVO> queryAllFaceInfo(FaceInfoTxRequestVO requestVO);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.face.attachment.service.impl;
|
||||
|
||||
|
||||
|
||||
import com.face.attachment.service.IAttachmentService;
|
||||
import com.face.attachment.service.vo.AttachmentVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AttachmentServiceImpl implements IAttachmentService {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public AttachmentVO uploadFile(MultipartFile file) throws Exception {
|
||||
String fileName = file.getOriginalFilename();
|
||||
AttachmentVO vo =new AttachmentVO();
|
||||
return vo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
package com.face.attachment.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
||||
import com.face.attachment.entity.FaceInfo;
|
||||
import com.face.attachment.mapper.FaceInfoMapper;
|
||||
import com.face.attachment.service.IFaceInfoService;
|
||||
import com.face.attachment.vo.*;
|
||||
import com.face.global.mapper.GlobalBaseMapper;
|
||||
import com.face.global.service.impl.GlobalBaseService;
|
||||
import com.face.global.vo.PageResponseVO;
|
||||
import com.face.jsonBean.QiuTestRoot;
|
||||
import com.face.util.DataCopy;
|
||||
import com.face.util.SystemExceptionUtils;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.tencentcloudapi.common.AbstractModel;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import com.tencentcloudapi.facefusion.v20220927.FacefusionClient;
|
||||
import com.tencentcloudapi.facefusion.v20220927.models.DescribeMaterialListRequest;
|
||||
import com.tencentcloudapi.facefusion.v20220927.models.DescribeMaterialListResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 人脸融合基础表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author admin
|
||||
* @since 2025-03-15
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class FaceInfoServiceImpl extends GlobalBaseService<FaceInfo, String> implements IFaceInfoService {
|
||||
|
||||
@Autowired
|
||||
private FaceInfoMapper faceInfoMapper;
|
||||
|
||||
public FaceInfoServiceImpl(GlobalBaseMapper<FaceInfo, String> globalBaseMapper, IdentifierGenerator identifierGenerator) {
|
||||
super(globalBaseMapper, identifierGenerator);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public FaceInfo updateFaceInfo(FaceInfoModRequestVO modRequestVO) throws Exception {
|
||||
FaceInfo faceInfo = this.getById(modRequestVO.getFaceId());
|
||||
if (faceInfo == null) {
|
||||
throw SystemExceptionUtils.buildBusinessException("dataNotExists");
|
||||
}
|
||||
DataCopy.copyExistsField(modRequestVO, faceInfo);
|
||||
this.updateById(faceInfo);
|
||||
return faceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaceInfo updateImgFaceInfo(MultipartFile file, String faceId) throws Exception {
|
||||
FaceInfo faceInfo = this.getById(faceId);
|
||||
|
||||
|
||||
byte[] imageBytes = file.getBytes();
|
||||
|
||||
|
||||
String imgBase = Base64.getEncoder().encodeToString(imageBytes);
|
||||
faceInfo.setFaceBase(imageBytes);
|
||||
|
||||
faceInfoMapper.updateById(faceInfo);
|
||||
|
||||
return faceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaceInfoDetailResponseVO getFaceInfo(String id) throws Exception {
|
||||
FaceInfo faceInfo = this.getById(id);
|
||||
if (faceInfo == null) {
|
||||
throw SystemExceptionUtils.buildBusinessException("dataNotExists");
|
||||
}
|
||||
return DataCopy.deepCopyData(faceInfo, FaceInfoDetailResponseVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResponseVO<FaceInfoPageResponseVO> pageAll(FaceInfoPageRequestVO pageRequestVO) throws Exception {
|
||||
PageResponseVO<FaceInfoPageResponseVO> pageResponseVO = new PageResponseVO<>();
|
||||
List<FaceInfoPageResponseVO> pageData = this.faceInfoMapper.pageAll(pageRequestVO);
|
||||
pageResponseVO.setData(pageData);
|
||||
pageResponseVO.setTotalSize(Optional.ofNullable(this.faceInfoMapper.pageCountAll(pageRequestVO)).orElse(0L));
|
||||
return pageResponseVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FaceInfo> addAllFaceInfoByTx(FaceInfoTxRequestVO requestVO) {
|
||||
List<FaceInfo> list=new ArrayList<>();
|
||||
try{
|
||||
|
||||
// SecretId:AKIDufDXigQwFWgdNuCG7kCRTHsFPN8fy3yg
|
||||
// SecretKey:kGZheSFrHVWKvHPJ0TikZAXjicJm490d
|
||||
|
||||
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||
Credential cred = new Credential("AKIDdGj28B1jKl03tY2YxEJH6jGe8VgvzpbA", "PaXHn6B50pgWEoPr7EXxCIDvTr6AGFA4");
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("facefusion.tencentcloudapi.com");
|
||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||
FacefusionClient client = new FacefusionClient(cred, "ap-chengdu", clientProfile);
|
||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||
DescribeMaterialListRequest req = new DescribeMaterialListRequest();
|
||||
//必须传这个参数
|
||||
//测试API接口 at_1895073745956143104
|
||||
//二次API接口 at_1895077148660760576
|
||||
req.setActivityId(requestVO.getActivityId());
|
||||
// 返回的resp是一个DescribeMaterialListResponse的实例,与请求对象对应
|
||||
DescribeMaterialListResponse resp = client.DescribeMaterialList(req);
|
||||
// 输出json格式的字符串回包
|
||||
|
||||
String qtest= AbstractModel.toJsonString(resp);
|
||||
System.out.println(qtest);
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
QiuTestRoot person = mapper.readValue(qtest, QiuTestRoot.class);
|
||||
person.getMaterialInfos().forEach(r->{
|
||||
r.getMaterialFaceList().forEach(g->{
|
||||
FaceInfo faceInfo=new FaceInfo();
|
||||
faceInfo.setActivityName(requestVO.getActivityName());
|
||||
faceInfo.setActivityId(requestVO.getActivityId());
|
||||
faceInfo.setMaterialId(r.getMaterialId());
|
||||
faceInfo.setMaterialName(r.getMaterialName());
|
||||
faceInfo.setFaceId(g.getFaceId());
|
||||
faceInfo.setHeight(g.getFaceInfo().getHeight());
|
||||
faceInfo.setWidth(g.getFaceInfo().getWidth());
|
||||
faceInfo.setX(g.getFaceInfo().getX());
|
||||
faceInfo.setY(g.getFaceInfo().getY());
|
||||
if(null==this.getById(faceInfo.getFaceId())){
|
||||
this.insert(faceInfo);
|
||||
list.add(faceInfo);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
//System.out.println(person.getMaterialInfos().get(0).getMaterialFaceList().get(0).getFaceId()); // 输出: John Doe
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
} catch (TencentCloudSDKException e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FaceInfoTxRequestVO> queryAllActivity() {
|
||||
return faceInfoMapper.queryAllActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FaceInfoDetailResponseVO> queryAllFaceInfo(FaceInfoTxRequestVO requestVO) {
|
||||
List<FaceInfo> list=faceInfoMapper.queryAllFaceInfo(requestVO);
|
||||
|
||||
List<FaceInfoDetailResponseVO> faceInfoDetailResponseVOList=DataCopy.deepCopyList(list,FaceInfoDetailResponseVO.class);
|
||||
faceInfoDetailResponseVOList.forEach(c->{
|
||||
if(c.getFaceBase() !=null ){
|
||||
c.setFaceBase64Code(Base64.getEncoder().encodeToString(c.getFaceBase()));
|
||||
}
|
||||
});
|
||||
|
||||
return faceInfoDetailResponseVOList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.face.attachment.service.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AttachmentVO {
|
||||
|
||||
private String originalFilename;
|
||||
|
||||
private long size;
|
||||
|
||||
private String downloadUrl;
|
||||
|
||||
private String thumbnailUrl;
|
||||
|
||||
private String thumbnailFileUrl;
|
||||
|
||||
private String downloadFileUrl;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.face.attachment.service.vo;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class DownloadAttachmentVO {
|
||||
private String originalFilename;
|
||||
|
||||
private long size;
|
||||
|
||||
private String contentType;
|
||||
|
||||
private InputStream inputStream;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.face.attachment.service.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ExcelGenerateCommVO {
|
||||
@Schema(title = "机构全称")
|
||||
String orgFullName;
|
||||
|
||||
@Schema(title = "机构状态(0-入驻,1-关闭)")
|
||||
String orgStatus;
|
||||
|
||||
@Schema(title = "订单名称")
|
||||
String orderName;
|
||||
|
||||
@Schema(title = "电话")
|
||||
String phone;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.face.attachment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FaceInfoAddRequestVO {
|
||||
@Schema(title = "人脸模版ID")
|
||||
@NotBlank(message = "人脸模版ID不能为空")
|
||||
@Size(min = 1, max = 32, message = "人脸模版ID长度必须在1到32之间")
|
||||
String faceId;
|
||||
|
||||
@Schema(title = "横向坐标x")
|
||||
Integer x;
|
||||
|
||||
@Schema(title = "纵向坐标y")
|
||||
Integer y;
|
||||
|
||||
@Schema(title = "横向坐标")
|
||||
Integer width;
|
||||
|
||||
@Schema(title = "坐标高")
|
||||
Integer height;
|
||||
|
||||
@Schema(title = "素材ID")
|
||||
String materialId;
|
||||
|
||||
@Schema(title = "素材名称")
|
||||
@Size(max = 255, message = "素材名称长度需要小于等于255")
|
||||
String materialName;
|
||||
|
||||
@Schema(title = "活动ID 一个活动多个素材 一个素材多个人脸模版")
|
||||
@Size(max = 32, message = "活动ID 一个活动多个素材 一个素材多个人脸模版长度需要小于等于32")
|
||||
String activityId;
|
||||
|
||||
@Schema(title = "图片地址")
|
||||
@Size(max = 255, message = "图片地址长度需要小于等于255")
|
||||
String faceUrl;
|
||||
|
||||
@Schema(title = "活动名称")
|
||||
@Size(max = 255, message = "活动名称长度需要小于等于255")
|
||||
String activityName;
|
||||
|
||||
@Schema(title = "图片BASE64编码")
|
||||
byte[] faceBase;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.face.attachment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FaceInfoDetailResponseVO {
|
||||
@Schema(title = "人脸模版ID")
|
||||
String faceId;
|
||||
|
||||
@Schema(title = "横向坐标x")
|
||||
Integer x;
|
||||
|
||||
@Schema(title = "纵向坐标y")
|
||||
Integer y;
|
||||
|
||||
@Schema(title = "横向坐标")
|
||||
Integer width;
|
||||
|
||||
@Schema(title = "坐标高")
|
||||
Integer height;
|
||||
|
||||
@Schema(title = "素材ID")
|
||||
String materialId;
|
||||
|
||||
@Schema(title = "素材名称")
|
||||
String materialName;
|
||||
|
||||
@Schema(title = "活动ID 一个活动多个素材 一个素材多个人脸模版")
|
||||
String activityId;
|
||||
|
||||
@Schema(title = "图片地址")
|
||||
String faceUrl;
|
||||
|
||||
@Schema(title = "活动名称")
|
||||
String activityName;
|
||||
|
||||
@Schema(title = "图片BASE64编码")
|
||||
byte[] faceBase;
|
||||
|
||||
@Schema(title = "图片BASE64编码")
|
||||
String faceBase64Code;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.face.attachment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FaceInfoModImgRequestVO {
|
||||
@Schema(title = "人脸模版ID")
|
||||
@NotBlank(message = "人脸模版ID不能为空")
|
||||
@Size(min = 1, max = 32, message = "人脸模版ID长度必须在1到32之间")
|
||||
String faceId;
|
||||
|
||||
@Schema(title = "横向坐标x")
|
||||
Integer x;
|
||||
|
||||
@Schema(title = "纵向坐标y")
|
||||
Integer y;
|
||||
|
||||
@Schema(title = "横向坐标")
|
||||
Integer width;
|
||||
|
||||
@Schema(title = "坐标高")
|
||||
Integer height;
|
||||
|
||||
@Schema(title = "素材ID")
|
||||
String materialId;
|
||||
|
||||
@Schema(title = "素材名称")
|
||||
@Size(max = 255, message = "素材名称长度需要小于等于255")
|
||||
String materialName;
|
||||
|
||||
@Schema(title = "活动ID 一个活动多个素材 一个素材多个人脸模版")
|
||||
@Size(max = 32, message = "活动ID 一个活动多个素材 一个素材多个人脸模版长度需要小于等于32")
|
||||
String activityId;
|
||||
|
||||
@Schema(title = "图片地址")
|
||||
@Size(max = 255, message = "图片地址长度需要小于等于255")
|
||||
String faceUrl;
|
||||
|
||||
@Schema(title = "活动名称")
|
||||
@Size(max = 255, message = "活动名称长度需要小于等于255")
|
||||
String activityName;
|
||||
|
||||
@Schema(title = "图片BASE64编码")
|
||||
byte[] faceBase;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.face.attachment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FaceInfoModRequestVO {
|
||||
@Schema(title = "人脸模版ID")
|
||||
@NotBlank(message = "人脸模版ID不能为空")
|
||||
@Size(min = 1, max = 32, message = "人脸模版ID长度必须在1到32之间")
|
||||
String faceId;
|
||||
|
||||
@Schema(title = "横向坐标x")
|
||||
Integer x;
|
||||
|
||||
@Schema(title = "纵向坐标y")
|
||||
Integer y;
|
||||
|
||||
@Schema(title = "横向坐标")
|
||||
Integer width;
|
||||
|
||||
@Schema(title = "坐标高")
|
||||
Integer height;
|
||||
|
||||
@Schema(title = "素材ID")
|
||||
String materialId;
|
||||
|
||||
@Schema(title = "素材名称")
|
||||
@Size(max = 255, message = "素材名称长度需要小于等于255")
|
||||
String materialName;
|
||||
|
||||
@Schema(title = "活动ID 一个活动多个素材 一个素材多个人脸模版")
|
||||
@Size(max = 32, message = "活动ID 一个活动多个素材 一个素材多个人脸模版长度需要小于等于32")
|
||||
String activityId;
|
||||
|
||||
@Schema(title = "图片地址")
|
||||
@Size(max = 255, message = "图片地址长度需要小于等于255")
|
||||
String faceUrl;
|
||||
|
||||
@Schema(title = "活动名称")
|
||||
@Size(max = 255, message = "活动名称长度需要小于等于255")
|
||||
String activityName;
|
||||
|
||||
@Schema(title = "图片BASE64编码")
|
||||
byte[] faceBase;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.face.attachment.vo;
|
||||
|
||||
import com.face.global.vo.PageRequestVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FaceInfoPageRequestVO extends PageRequestVO {
|
||||
@Schema(title = "人脸模版ID")
|
||||
String faceId;
|
||||
|
||||
@Schema(title = "横向坐标x")
|
||||
Integer x;
|
||||
|
||||
@Schema(title = "纵向坐标y")
|
||||
Integer y;
|
||||
|
||||
@Schema(title = "横向坐标")
|
||||
Integer width;
|
||||
|
||||
@Schema(title = "坐标高")
|
||||
Integer height;
|
||||
|
||||
@Schema(title = "素材ID")
|
||||
String materialId;
|
||||
|
||||
@Schema(title = "素材名称")
|
||||
String materialName;
|
||||
|
||||
@Schema(title = "活动ID 一个活动多个素材 一个素材多个人脸模版")
|
||||
String activityId;
|
||||
|
||||
@Schema(title = "图片地址")
|
||||
String faceUrl;
|
||||
|
||||
@Schema(title = "活动名称")
|
||||
String activityName;
|
||||
|
||||
@Schema(title = "图片BASE64编码")
|
||||
byte[] faceBase;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.face.attachment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FaceInfoPageResponseVO {
|
||||
@Schema(title = "人脸模版ID")
|
||||
String faceId;
|
||||
|
||||
@Schema(title = "横向坐标x")
|
||||
Integer x;
|
||||
|
||||
@Schema(title = "纵向坐标y")
|
||||
Integer y;
|
||||
|
||||
@Schema(title = "横向坐标")
|
||||
Integer width;
|
||||
|
||||
@Schema(title = "坐标高")
|
||||
Integer height;
|
||||
|
||||
@Schema(title = "素材ID")
|
||||
String materialId;
|
||||
|
||||
@Schema(title = "素材名称")
|
||||
String materialName;
|
||||
|
||||
@Schema(title = "活动ID 一个活动多个素材 一个素材多个人脸模版")
|
||||
String activityId;
|
||||
|
||||
@Schema(title = "图片地址")
|
||||
String faceUrl;
|
||||
|
||||
@Schema(title = "活动名称")
|
||||
String activityName;
|
||||
|
||||
@Schema(title = "图片BASE64编码")
|
||||
byte[] faceBase;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.face.attachment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FaceInfoTxRequestVO {
|
||||
@Schema(title = "活动ID")
|
||||
|
||||
String activityId;
|
||||
@Schema(title = "活动名称")
|
||||
String activityName;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.face.global;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class GlobalThreadPool {
|
||||
public static final ThreadPoolExecutor SMALL_THREAD_POOL_ABORT =
|
||||
new ThreadPoolExecutor(5, 10,
|
||||
60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(200),
|
||||
new ThreadPoolExecutor.AbortPolicy());
|
||||
|
||||
public static final ThreadPoolExecutor IO_THREAD_POOL_CALL_RUN =
|
||||
new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
|
||||
Runtime.getRuntime().availableProcessors() * 2,
|
||||
60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(200),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
|
||||
|
||||
public static final ThreadPoolExecutor IO_THREAD_POOL_ABORT =
|
||||
new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
|
||||
Runtime.getRuntime().availableProcessors() * 2,
|
||||
60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(200),
|
||||
new ThreadPoolExecutor.AbortPolicy());
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.face.global.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.BufferingClientHttpRequestFactory;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(HttpClientConfig.ProxyConfigProperties.class)
|
||||
public class HttpClientConfig {
|
||||
|
||||
@Autowired
|
||||
private ProxyConfigProperties properties;
|
||||
|
||||
@Bean
|
||||
public RestTemplate proxyRestTemplate() {
|
||||
return new RestTemplate(
|
||||
new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory(
|
||||
HttpClientFactory.getHttpClient(properties.getProxy(),
|
||||
properties.getClient()))));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestTemplate noProxyRestTemplate() {
|
||||
return new RestTemplate(
|
||||
new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory(
|
||||
HttpClientFactory.getHttpClient(null,
|
||||
properties.getClient()))));
|
||||
}
|
||||
|
||||
@ConfigurationProperties(value = "app.http.default")
|
||||
@Data
|
||||
public static class ProxyConfigProperties {
|
||||
|
||||
private ProxyProperties proxy;
|
||||
|
||||
private HttpClientProperties client;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package com.face.global.config;
|
||||
|
||||
|
||||
import com.face.global.consts.GlobalConstant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
|
||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
||||
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.ssl.SSLContexts;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
public class HttpClientFactory {
|
||||
private static final String REQUEST_START_TIME_KEY = "requestStartTime";
|
||||
|
||||
private static final String REQUEST_START_URI_KEY = "requestStartUri";
|
||||
|
||||
private static final String REQUEST_START_MARK_KEY = "requestStartMark";
|
||||
|
||||
public static CloseableHttpClient getHttpClient(ProxyProperties proxyProperties,
|
||||
HttpClientProperties httpClientProperties) {
|
||||
PoolingHttpClientConnectionManager clientConnectionManager = buildConnectionManager(httpClientProperties);
|
||||
return HttpClients.custom().setProxy(getProxy(proxyProperties))
|
||||
.setConnectionManager(clientConnectionManager)
|
||||
.addRequestInterceptorLast((request, entity, context) -> {
|
||||
String traceId = MDC.get(GlobalConstant.TRACE_ID_KEY);
|
||||
if (StringUtils.isBlank(traceId)) {
|
||||
traceId = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
request.setHeader(GlobalConstant.TRACE_ID_KEY, traceId);
|
||||
long timestamp = System.currentTimeMillis();
|
||||
String mark = UUID.randomUUID().toString().replace("-", "");
|
||||
context.setAttribute(REQUEST_START_TIME_KEY, timestamp);
|
||||
context.setAttribute(REQUEST_START_TIME_KEY, timestamp);
|
||||
context.setAttribute(REQUEST_START_MARK_KEY, mark);
|
||||
context.setAttribute(REQUEST_START_URI_KEY, request.getRequestUri());
|
||||
log.info("startRequest {} {} {} {}", request.getRequestUri(), request.getHeaders(), timestamp, mark);
|
||||
})
|
||||
.addResponseInterceptorFirst((response, entity, context) -> {
|
||||
Long requestTime = (Long) context.getAttribute(REQUEST_START_TIME_KEY);
|
||||
Long timeCost = null;
|
||||
if (requestTime != null && requestTime > 0) {
|
||||
timeCost = System.currentTimeMillis() - requestTime;
|
||||
}
|
||||
log.info("endRequest {} {} {} {} {} {}", context.getAttribute(REQUEST_START_URI_KEY), requestTime,
|
||||
context.getAttribute(REQUEST_START_MARK_KEY), response.getCode(), response.getHeaders(), timeCost);
|
||||
})
|
||||
.setRetryStrategy(new DefaultHttpRequestRetryStrategy() {
|
||||
@Override
|
||||
public boolean retryRequest(HttpRequest request, IOException exception, int execCount, HttpContext context) {
|
||||
log.warn("retryRequestCountForRequest {} {} {} {} {}", request.getRequestUri(),
|
||||
context.getAttribute(REQUEST_START_TIME_KEY),
|
||||
context.getAttribute(REQUEST_START_MARK_KEY),
|
||||
httpClientProperties.getRetryCount(), execCount, exception);
|
||||
if (httpClientProperties.getRetryCount() < execCount) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retryRequest(HttpResponse response, int execCount, HttpContext context) {
|
||||
log.warn("retryRequestCountForResponse {} {} {} {} {} {}", context.getAttribute(REQUEST_START_URI_KEY),
|
||||
context.getAttribute(REQUEST_START_TIME_KEY),
|
||||
context.getAttribute(REQUEST_START_MARK_KEY),
|
||||
response.getHeaders(), response.getCode(), execCount);
|
||||
return false;
|
||||
}
|
||||
}).build();
|
||||
|
||||
}
|
||||
|
||||
private static HttpHost getProxy(ProxyProperties proxyProperties) {
|
||||
if (proxyProperties == null || StringUtils.isBlank(proxyProperties.getHost())) {
|
||||
return null;
|
||||
}
|
||||
return new HttpHost(proxyProperties.getHost(), proxyProperties.getPort());
|
||||
}
|
||||
|
||||
private static PoolingHttpClientConnectionManager buildConnectionManager(HttpClientProperties httpClientProperties) {
|
||||
return PoolingHttpClientConnectionManagerBuilder.create()
|
||||
.setConnectionConfigResolver(route -> ConnectionConfig.custom()
|
||||
.setConnectTimeout(Timeout.of(Optional.ofNullable(httpClientProperties.getConnectTimeout()).orElse(Duration.ofSeconds(3))))
|
||||
.setSocketTimeout(Timeout.of(Optional.ofNullable(httpClientProperties.getSocketTimeout()).orElse(Duration.ofSeconds(30))))
|
||||
.setValidateAfterInactivity(Timeout.of(Optional.ofNullable(httpClientProperties.getValidateAfterInactivity())
|
||||
.orElse(Duration.ofSeconds(30))))
|
||||
.setTimeToLive(Timeout.of(Optional.ofNullable(httpClientProperties.getTimeToLive()).orElse(Duration.ofSeconds(300))))
|
||||
.build())
|
||||
.setMaxConnTotal(httpClientProperties.getMaxConnTotal())
|
||||
.setMaxConnPerRoute(httpClientProperties.getMaxConnPerRoute())
|
||||
.setSSLSocketFactory(new SSLConnectionSocketFactory(SSLContexts.createDefault(), (s, sslSession) -> true))
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.face.global.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Data
|
||||
public class HttpClientProperties {
|
||||
private Duration connectTimeout;
|
||||
private Duration socketTimeout;
|
||||
private Duration validateAfterInactivity;
|
||||
private Duration timeToLive;
|
||||
private Integer maxConnTotal;
|
||||
private Integer maxConnPerRoute;
|
||||
private int retryCount;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.face.global.config;
|
||||
|
||||
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
|
||||
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.commons.util.InetUtilsProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class IdConfig {
|
||||
|
||||
@Bean
|
||||
public IdentifierGenerator identifierGenerator() {
|
||||
try (InetUtils inetUtils = new InetUtils(new InetUtilsProperties());){
|
||||
return new DefaultIdentifierGenerator(inetUtils.findFirstNonLoopbackAddress());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.face.global.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ProxyProperties {
|
||||
private String host;
|
||||
private int port;
|
||||
private boolean enable;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package com.face.global.config;
|
||||
|
||||
|
||||
import com.face.global.consts.GlobalConstant;
|
||||
import io.swagger.v3.oas.models.Components;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.media.StringSchema;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
import org.springdoc.core.models.GroupedOpenApi;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(GroupedOpenApi.class)
|
||||
@ConditionalOnProperty(value = "springdoc.swagger-ui.enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
public class SwaggerConfig {
|
||||
|
||||
@Bean
|
||||
public GroupedOpenApi publicApi() {
|
||||
return GroupedOpenApi.builder()
|
||||
.group("public")
|
||||
.pathsToMatch("/api/customer/**")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public GroupedOpenApi mobileManageApi() {
|
||||
return GroupedOpenApi.builder()
|
||||
.group("mobileAdmin")
|
||||
.pathsToMatch("/api/manage/**")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GroupedOpenApi adminApi() {
|
||||
return GroupedOpenApi.builder()
|
||||
.group("admin")
|
||||
.pathsToMatch("/manage/**")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAPI openApi() {
|
||||
return new OpenAPI()
|
||||
.addSecurityItem(new SecurityRequirement()
|
||||
.addList(GlobalConstant.TOKEN_KEY))
|
||||
.components(new Components()
|
||||
.addSecuritySchemes(GlobalConstant.TOKEN_KEY, new SecurityScheme()
|
||||
.scheme("bearer")
|
||||
.description("使用" + GlobalConstant.TOKEN_START_WITH_KEY + "+返回的token," +
|
||||
"这里只使用返回的token,前端需要安置这种方式做,header的key为" + GlobalConstant.TOKEN_KEY)
|
||||
.bearerFormat("JWT")
|
||||
.type(SecurityScheme.Type.HTTP))
|
||||
.addParameters(GlobalConstant.TOKEN_AUTH_TYPE, new Parameter()
|
||||
.in("header").name(GlobalConstant.TOKEN_AUTH_TYPE)
|
||||
.required(false).schema(new StringSchema())
|
||||
.description("用户的授权类型header里面key为:" + GlobalConstant.TOKEN_AUTH_TYPE + ",值为登录的时候返回的授权类型"))
|
||||
.addParameters(GlobalConstant.ORG_KEY, new Parameter()
|
||||
.in("header").name(GlobalConstant.ORG_KEY)
|
||||
.required(false).schema(new StringSchema())
|
||||
.description("切换的机构信息header里面key为:" + GlobalConstant.ORG_KEY + ",用户选择的机构ID"))
|
||||
|
||||
)
|
||||
// 文档描述信息
|
||||
.info(new Info()
|
||||
.title("api")
|
||||
.description("api document")
|
||||
.version("1.0")
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.face.global.config;
|
||||
|
||||
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(TaskExecutionProperties.class)
|
||||
public class TaskExecutorConfig {
|
||||
|
||||
@Primary
|
||||
@Bean
|
||||
public ThreadPoolTaskExecutor threadPoolTaskExecutor(TaskExecutionProperties taskExecutionProperties) {
|
||||
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
|
||||
threadPoolTaskExecutor.setCorePoolSize(taskExecutionProperties.getPool().getCoreSize());
|
||||
threadPoolTaskExecutor.setMaxPoolSize(taskExecutionProperties.getPool().getMaxSize());
|
||||
threadPoolTaskExecutor.setKeepAliveSeconds((int) taskExecutionProperties.getPool().getKeepAlive().toSeconds());
|
||||
threadPoolTaskExecutor.setQueueCapacity(taskExecutionProperties.getPool().getQueueCapacity());
|
||||
threadPoolTaskExecutor.setAllowCoreThreadTimeOut(taskExecutionProperties.getPool().isAllowCoreThreadTimeout());
|
||||
return threadPoolTaskExecutor;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.face.global.consts;
|
||||
|
||||
import java.time.ZoneId;
|
||||
|
||||
public class GlobalConstant {
|
||||
public static final String TOKEN_KEY = "Authorization";
|
||||
|
||||
public static final String TRACE_ID_KEY = "x-request-trace-id";
|
||||
|
||||
public static final String ALI_TRACE_ID_KEY = "x-ali-request-trace-id";
|
||||
|
||||
public static final String ALI_MDC_KEY = "EagleEye-TraceID";
|
||||
|
||||
public static final String TIME_COST_KEY = "x-request-time-cost";
|
||||
|
||||
public static final String CUSTOMER_API_PATH = "/api/customer/*";
|
||||
|
||||
public static final String MANAGE_API_PATH = "/api/manage/*";
|
||||
|
||||
public static final String MANAGE_PATH = "/manage/*";
|
||||
|
||||
public static final String MANAGE_INTERCEPTOR_API_PATH = "/api/manage/**";
|
||||
|
||||
public static final String MANAGE_INTERCEPTOR_PATH = "/manage/**";
|
||||
|
||||
public static final String ALL_PATH = "/*";
|
||||
|
||||
public static final String TOKEN_START_WITH_KEY = "Bearer ";
|
||||
|
||||
public static final String TOKEN_AUTH_TYPE = "Authorization-Type";
|
||||
|
||||
public static final String ORG_KEY = "Authorization-Org";
|
||||
|
||||
public static final String CACHE_NAME_AND_TIME_SPLIT = "#";
|
||||
|
||||
public static final String STAR_SPLIT = "*";
|
||||
|
||||
public static final String SYSTEM_OPERATE_USER_ID = "system";
|
||||
|
||||
public static final ZoneId ZONE_ID = ZoneId.systemDefault();
|
||||
|
||||
public static final String GLOBAL_ROLE_ORG_ID = "0";
|
||||
|
||||
public static final String ORG_ADMIN_ROLE = "orgAdmin";
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.face.global.controller;
|
||||
|
||||
public class ApiBaseController extends BaseController {
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package com.face.global.controller;
|
||||
|
||||
public class BaseController {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package com.face.global.controller;
|
||||
|
||||
public class ManageBaseController extends BaseController {
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.face.global.entity;
|
||||
|
||||
|
||||
import com.face.global.enums.DeleteType;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
@Data
|
||||
public class BaseEntity {
|
||||
|
||||
private Date createDate;
|
||||
|
||||
private String createUser;
|
||||
|
||||
private String createUserType;
|
||||
|
||||
private String modifyUser;
|
||||
|
||||
private Date modifyDate;
|
||||
|
||||
private String modifyUserType;
|
||||
|
||||
private String isDelete;
|
||||
|
||||
public boolean checkDelete() {
|
||||
return DeleteType.DELETE.getCode().equals(isDelete);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void recoverForModify(BaseEntity dbBaseEntity) {
|
||||
this.setCreateUser(dbBaseEntity.getCreateUser());
|
||||
this.setCreateDate(dbBaseEntity.getCreateDate());
|
||||
this.setCreateUserType(dbBaseEntity.getCreateUserType());
|
||||
this.setIsDelete(dbBaseEntity.getIsDelete());
|
||||
}
|
||||
|
||||
|
||||
public void init(String user, String userType) {
|
||||
this.initCreate(user,userType);
|
||||
this.initModify(user,userType);
|
||||
this.initDelete();
|
||||
}
|
||||
|
||||
public void initCreate(String createUser, String createUserType) {
|
||||
this.setCreateDate(new Date());
|
||||
this.setCreateUser(createUser);
|
||||
this.setCreateUserType(createUserType);
|
||||
}
|
||||
|
||||
public void initModify(String modifyUser, String modifyUserType) {
|
||||
this.setModifyDate(new Date());
|
||||
this.setModifyUser(modifyUser);
|
||||
this.setModifyUserType(modifyUserType);
|
||||
}
|
||||
|
||||
public void initDelete() {
|
||||
this.setIsDelete(DeleteType.NO_DELETE.getCode());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum CommonCode {
|
||||
SUCCESS("200"),
|
||||
NOT_VALID_TOKEN("401"),
|
||||
NO_TOKEN("402"),
|
||||
TOKEN_PRE_FORMATTER_ERROR("405"),
|
||||
TOKEN_AUTH_TYPE_ERROR("406"),
|
||||
USER_STATUS_ERROR("407"),
|
||||
USER_TOKEN_ANALYSIS_ERROR("408"),
|
||||
ORG_INFO_NOT_EXISTS("101"),
|
||||
ORG_CHECK_ERROR("102"),
|
||||
ORG_NO_PERMIT("103"),
|
||||
NO_PERMIT("403"),
|
||||
ERROR("500");
|
||||
@Getter
|
||||
private String code;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum DeleteType {
|
||||
DELETE("1"), NO_DELETE("0");
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum EnableType {
|
||||
DISABLE("0"), ENABLE("1");
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum OperateType {
|
||||
ADD("1"), UPDATE("2"), DELETE("3"), RECOVER("4"), RECOVER_INSERT("5"),
|
||||
REF_TRIGGER_ADD("6"), REF_TRIGGER_UPDATE("7"), REF_TRIGGER_DELETE("8");
|
||||
@Getter
|
||||
private String operateType;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum TransDirectEnum {
|
||||
INCOME("1","收入"), OUTLAY("2","支出");
|
||||
|
||||
@Getter
|
||||
private String key;
|
||||
|
||||
@Getter
|
||||
private String desc;
|
||||
|
||||
public static TransDirectEnum getByCode(String code) {
|
||||
return Arrays.stream(TransDirectEnum.values()).filter(e -> e.getKey().equals(code)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
public enum UserEventEnum {
|
||||
ADD, UPDATE, DELETE, LOCK, UNLOCK, RECOVER, ADD_USER_ORG, UPDATE_USER_ORG, ADD_TEACHER;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum UserStatusEnum {
|
||||
NORMAL("1"), LOCK("2");
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
|
||||
public static UserStatusEnum codeOf(String code) {
|
||||
return Arrays.stream(UserStatusEnum.values()).filter(value ->
|
||||
StringUtils.equals(code, value.name())
|
||||
|| StringUtils.equals(code, value.getCode())).findAny().orElse(null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum UserTerminalEnum {
|
||||
TEACHER("teacher","教师端");
|
||||
|
||||
@Getter
|
||||
private String key;
|
||||
|
||||
@Getter
|
||||
private String desc;
|
||||
|
||||
public static UserTerminalEnum getByCode(String status) {
|
||||
return Arrays.stream(UserTerminalEnum.values()).filter(e -> e.getKey().equals(status)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum UserTypeEnum {
|
||||
SYS_USER("sysUser"), CUSTOMER("customer");
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
|
||||
public static UserTypeEnum codeOf(String codeArg) {
|
||||
return Arrays.stream(UserTypeEnum.values()).filter(value ->
|
||||
StringUtils.equals(codeArg, value.name())
|
||||
|| StringUtils.equals(codeArg, value.getCode()))
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
|
||||
import com.face.global.validator.EnumValidator;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum ValidCodeModuleEnum implements EnumValidator {
|
||||
|
||||
CUSTOMER_LOGIN("customerLogin");
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
|
||||
import com.face.global.validator.EnumValidator;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum ViewFlagFlagEnum implements EnumValidator {
|
||||
|
||||
NOT_SHOW_MENU("0"), SHOW_MENU("1");
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum WXResponseCode {
|
||||
USER_REFUSE(43101);
|
||||
|
||||
@Getter
|
||||
private int code;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public enum WeekDayEnum {
|
||||
MONDAY("1", "星期一"),
|
||||
TUESDAY("2", "星期二"),
|
||||
WEDNESDAY("3", "星期三"),
|
||||
THURSDAY("4", "星期四"),
|
||||
FRIDAY("5", "星期五"),
|
||||
SATURDAY("6", "星期六"),
|
||||
SUNDAY("0", "星期日");
|
||||
|
||||
@Getter
|
||||
private String value;
|
||||
|
||||
@Getter
|
||||
private String chineseName;
|
||||
|
||||
WeekDayEnum(String value, String chineseName) {
|
||||
this.chineseName = chineseName;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static WeekDayEnum getWeekDayEnumByValue(String value) {
|
||||
for (WeekDayEnum weekDayEnum : WeekDayEnum.values()) {
|
||||
if (weekDayEnum.getValue().equals(value)) {
|
||||
return weekDayEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
|
||||
import com.face.global.validator.EnumValidator;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum WxConfigTypeEnum implements EnumValidator {
|
||||
|
||||
CUSTOMER("customer"), SYS_USER("sysUser");
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
|
||||
public static WxConfigTypeEnum getByCode(String type) {
|
||||
WxConfigTypeEnum[] values = WxConfigTypeEnum.values();
|
||||
for (WxConfigTypeEnum value : values) {
|
||||
if (value.getCode().equals(type)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum WxResultEnum {
|
||||
SUCCESS(0, "SUCCESS","OK"), COMMON_ERROR(-1, "ERROR", "error");
|
||||
@Getter
|
||||
private int code;
|
||||
|
||||
@Getter
|
||||
private String name;
|
||||
|
||||
@Getter
|
||||
private String msg;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
|
||||
import com.face.global.validator.EnumValidator;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum WxTypeEnum implements EnumValidator {
|
||||
|
||||
OFFICIAL("1"), MINI("2");
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
|
||||
public static WxTypeEnum getByCode(String type) {
|
||||
WxTypeEnum[] values = WxTypeEnum.values();
|
||||
for (WxTypeEnum value : values) {
|
||||
if (value.getCode().equals(type)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.face.global.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum YesOrNoEnum {
|
||||
YES("1"), NO("0");
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
|
||||
public static YesOrNoEnum codeOf(String codeArg) {
|
||||
return Arrays.stream(YesOrNoEnum.values()).filter(value ->
|
||||
StringUtils.equals(codeArg, value.name())
|
||||
|| StringUtils.equals(codeArg, value.getCode()))
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.face.global.exception;
|
||||
|
||||
public class BusinessException extends RuntimeException {
|
||||
private String code;
|
||||
|
||||
private String message;
|
||||
|
||||
private BusinessException realBusinessException;
|
||||
|
||||
public BusinessException(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public BusinessException(String code, String message, Throwable cause) {
|
||||
super(cause);
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
if (cause instanceof BusinessException && this.realBusinessException == null) {
|
||||
this.realBusinessException = this;
|
||||
}
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
if (this.realBusinessException != null && this != this.realBusinessException) {
|
||||
return this.realBusinessException.getCode();
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
if (this.realBusinessException != null && this != this.realBusinessException) {
|
||||
return this.realBusinessException.getMessage();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,233 @@
|
|||
package com.face.global.exception;
|
||||
|
||||
|
||||
import com.face.global.enums.CommonCode;
|
||||
import com.face.global.language.LanguageStore;
|
||||
import com.face.util.ApiResultBuilder;
|
||||
import com.face.util.HttpUtils;
|
||||
import com.face.util.MessageUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.ConversionNotSupportedException;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.validation.method.MethodValidationException;
|
||||
import org.springframework.web.ErrorResponseException;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingPathVariableException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.ServletRequestBindingException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
|
||||
import org.springframework.web.method.annotation.HandlerMethodValidationException;
|
||||
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||
import org.springframework.web.multipart.support.MissingServletRequestPartException;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class GlobalErrorController extends ResponseEntityExceptionHandler {
|
||||
|
||||
public GlobalErrorController(MessageSource messageSource) {
|
||||
this.setMessageSource(messageSource);
|
||||
}
|
||||
|
||||
@ExceptionHandler(value = BusinessException.class)
|
||||
public ResponseEntity<Object> dealBusinessException(HttpServletRequest request, BusinessException ex) {
|
||||
this.printHttpLog(request, null, null, ex);
|
||||
return this.buildErrorResponseEntity(ex.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@ExceptionHandler(value = Throwable.class)
|
||||
public ResponseEntity<Object> dealException(HttpServletRequest request, Throwable ex) {
|
||||
this.printHttpLog(request, null, null, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), null);
|
||||
}
|
||||
|
||||
private ResponseEntity<Object> buildErrorResponseEntity(String code, String message) {
|
||||
String errorMessage = null;
|
||||
if (StringUtils.isBlank(message)) {
|
||||
errorMessage = MessageUtils.getMessage(code, null, LanguageStore.getLocale());
|
||||
}
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
return new ResponseEntity<>(ApiResultBuilder.getRawBuilder().baseInfo(code,
|
||||
Optional.ofNullable(errorMessage)
|
||||
.orElse(message)).build(), headers, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers,
|
||||
HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleHttpMediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleMissingServletRequestPart(MissingServletRequestPartException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleServletRequestBindingException(ServletRequestBindingException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
List<String> datas = new ArrayList<>();
|
||||
if (ex.getDetailMessageArguments() == null || ex.getDetailMessageArguments().length <= 0) {
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
for (Object obj : ex.getDetailMessageArguments()) {
|
||||
if (obj instanceof String && StringUtils.isNotBlank(obj.toString())) {
|
||||
if (obj.toString().contains(":")) {
|
||||
datas.add(obj.toString().split(":")[1]);
|
||||
} else {
|
||||
datas.add(obj.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isEmpty(datas)) {
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), StringUtils.join(datas, ","));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleHandlerMethodValidationException(HandlerMethodValidationException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleNoResourceFoundException(NoResourceFoundException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleErrorResponseException(ErrorResponseException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleConversionNotSupported(ConversionNotSupportedException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleHttpMessageNotWritable(HttpMessageNotWritableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleMethodValidationException(MethodValidationException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||
this.printLog(request, headers, status, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatusCode statusCode, WebRequest request) {
|
||||
this.printLog(request, headers, statusCode, ex);
|
||||
return this.buildErrorResponseEntity(CommonCode.ERROR.getCode(), ex.getMessage());
|
||||
}
|
||||
|
||||
private void printLog(WebRequest request, HttpHeaders headers, HttpStatusCode status, Throwable ex) {
|
||||
if (request instanceof HttpServletRequest) {
|
||||
this.printHttpLog(((HttpServletRequest) request), headers, status, ex);
|
||||
} else {
|
||||
log.error("requestUrlFail", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void printHttpLog(HttpServletRequest request, HttpHeaders headers, HttpStatusCode status, Throwable ex) {
|
||||
log.error("requestUrlFail {} {} {} {}", request.getRequestURI(), request.getParameterMap(), HttpUtils.getHeadersInfo(request, headers),
|
||||
this.getStatusInfo(status), ex);
|
||||
}
|
||||
|
||||
private Integer getStatusInfo(HttpStatusCode status) {
|
||||
if (status != null) {
|
||||
return status.value();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.face.global.language;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
public class LanguageStore {
|
||||
|
||||
private static final Locale CN = new Locale( "zh" , "CN" );
|
||||
|
||||
private final static ThreadLocal<Locale> THREAD_LOCAL = new ThreadLocal<>();
|
||||
|
||||
public static Locale getLocale() {
|
||||
return Optional.ofNullable(THREAD_LOCAL.get()).orElse(CN);
|
||||
}
|
||||
|
||||
public static void setLocale(Locale locale) {
|
||||
THREAD_LOCAL.set(locale);
|
||||
}
|
||||
|
||||
|
||||
public static void clearLocale() {
|
||||
THREAD_LOCAL.remove();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.face.global.log;
|
||||
|
||||
public class LogStore {
|
||||
private static final ThreadLocal<String> LOG_MDC_ID_STORE = new InheritableThreadLocal<>();
|
||||
|
||||
public static void setLogMdcId(String mdcId) {
|
||||
LOG_MDC_ID_STORE.set(mdcId);
|
||||
}
|
||||
public static String getLogMdcId() {
|
||||
return LOG_MDC_ID_STORE.get();
|
||||
}
|
||||
|
||||
public static void clearLogMdcId() {
|
||||
LOG_MDC_ID_STORE.remove();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.face.global.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface GlobalBaseMapper<T, ID extends Serializable> extends BaseMapper<T> {
|
||||
int insertH(Map<Object, Object> data);
|
||||
|
||||
int insertBatchSomeColumn(List<T> entityList);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.face.global.mybatisplus;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
|
||||
import com.face.global.mybatisplus.method.InsertH;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MybatisPlusSqlInjector extends DefaultSqlInjector {
|
||||
|
||||
@Override
|
||||
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
|
||||
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
|
||||
methodList.add(new InsertH());
|
||||
methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
|
||||
return methodList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.face.global.mybatisplus.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface HistoryColumn {
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.face.global.mybatisplus.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.face.global.mybatisplus.MybatisPlusSqlInjector;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
/**
|
||||
* <a>https://baomidou.com/pages/49cc81/#insertbatchsomecolumn</a>
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusSqlInjector sqlInjector() {
|
||||
return new MybatisPlusSqlInjector();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2022, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.face.global.mybatisplus.method;
|
||||
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.face.global.entity.BaseEntity;
|
||||
import com.face.global.mybatisplus.annotation.HistoryColumn;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlSource;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 插入一条历史数据
|
||||
*/
|
||||
public class InsertH extends AbstractMethod {
|
||||
|
||||
private final static String SQL = "<script>\nINSERT INTO %s_h (%s) VALUES (%s)\n</script>";
|
||||
|
||||
public InsertH() {
|
||||
super("insertH");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||
Field[] baseFields = FieldUtils.getAllFields(BaseEntity.class);
|
||||
List<String> baseColumns = new ArrayList<>();
|
||||
List<String> baseFieldNames = new ArrayList<>();
|
||||
for (Field field : baseFields) {
|
||||
baseColumns.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName()));
|
||||
baseFieldNames.add(HASH_LEFT_BRACE.concat(field.getName()).concat(RIGHT_BRACE));
|
||||
}
|
||||
List<String> extraColumns = new ArrayList<>();
|
||||
List<Field> extraFields = Arrays.stream(FieldUtils.getAllFields(modelClass))
|
||||
.filter(field -> field.getAnnotation(HistoryColumn.class) != null).toList();
|
||||
List<String> extraFieldNames = new ArrayList<>();
|
||||
for (Field field : extraFields) {
|
||||
extraColumns.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName()));
|
||||
extraFieldNames.add(HASH_LEFT_BRACE.concat(field.getName()).concat(RIGHT_BRACE));
|
||||
}
|
||||
List<String> defaultColumns = new ArrayList<>();
|
||||
defaultColumns.add("id");
|
||||
defaultColumns.add("main_id");
|
||||
defaultColumns.add("content");
|
||||
defaultColumns.add("seqno");
|
||||
defaultColumns.add("operate_type");
|
||||
List<String> defaultFields = new ArrayList<>();
|
||||
defaultFields.add(HASH_LEFT_BRACE.concat("id").concat(RIGHT_BRACE));
|
||||
defaultFields.add(HASH_LEFT_BRACE.concat("mainId").concat(RIGHT_BRACE));
|
||||
defaultFields.add(HASH_LEFT_BRACE.concat("content").concat(RIGHT_BRACE));
|
||||
defaultFields.add(HASH_LEFT_BRACE.concat("seqno").concat(RIGHT_BRACE));
|
||||
defaultFields.add(HASH_LEFT_BRACE.concat("operateType").concat(RIGHT_BRACE));
|
||||
List<String> allColumns = new ArrayList<>();
|
||||
allColumns.addAll(defaultColumns);
|
||||
allColumns.addAll(baseColumns);
|
||||
allColumns.addAll(extraColumns);
|
||||
String defaultInsertColumn = StringUtils.join(allColumns, ",");
|
||||
List<String> allFields = new ArrayList<>();
|
||||
allFields.addAll(defaultFields);
|
||||
allFields.addAll(baseFieldNames);
|
||||
allFields.addAll(extraFieldNames);
|
||||
String defaultValuesColumn = StringUtils.join(allFields, ",");
|
||||
String sql = String.format(SQL, tableInfo.getTableName(), defaultInsertColumn, defaultValuesColumn);
|
||||
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Object.class);
|
||||
return this.addInsertMappedStatement(mapperClass, modelClass, methodName, sqlSource,
|
||||
NoKeyGenerator.INSTANCE, null, null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package com.face.global.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.face.global.vo.GlobalUser;
|
||||
import com.face.global.vo.Operate;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface IGlobalBaseService<T, ID extends Serializable> extends IService<T> {
|
||||
|
||||
int insert(T entity);
|
||||
|
||||
int deleteById(ID id);
|
||||
|
||||
int deleteById(T entity);
|
||||
|
||||
int deleteByMap(Map columnMap);
|
||||
|
||||
|
||||
int delete(Wrapper<T> queryWrapper);
|
||||
|
||||
|
||||
int updateByIdForInt(T entity);
|
||||
|
||||
|
||||
int updateForInt(T entity, Wrapper<T> updateWrapper);
|
||||
|
||||
|
||||
int updateForInt(Wrapper<T> updateWrapper);
|
||||
|
||||
|
||||
T selectById(ID id);
|
||||
|
||||
|
||||
T selectOne(Wrapper<T> queryWrapper);
|
||||
|
||||
|
||||
T selectOne(Wrapper<T> queryWrapper, boolean throwEx);
|
||||
|
||||
|
||||
boolean exists(Wrapper<T> queryWrapper);
|
||||
|
||||
|
||||
List<T> selectByMap(Map columnMap);
|
||||
|
||||
|
||||
Long selectCount(Wrapper<T> queryWrapper);
|
||||
|
||||
List<T> selectList(Wrapper<T> queryWrapper);
|
||||
|
||||
List<T> selectBatchIds(Collection<ID> idList);
|
||||
|
||||
int deleteBatchIds(Collection<ID> idList);
|
||||
|
||||
String generatorStringId();
|
||||
|
||||
long generatorLongId();
|
||||
|
||||
/**
|
||||
* 根据entity条件复制
|
||||
* @return
|
||||
*/
|
||||
int insertH(ID id, Function<ID, Map<String, Object>> content, @Param("operate") Operate operate);
|
||||
|
||||
Operate getUpdateOperate(boolean generateSeq);
|
||||
|
||||
Operate getInsertOperate(boolean generateSeq);
|
||||
|
||||
Operate getDeleteOperate(boolean generateSeq);
|
||||
|
||||
boolean updateSomeColumnById(List dataEntity);
|
||||
|
||||
GlobalUser getOperateUser();
|
||||
}
|
|
@ -0,0 +1,475 @@
|
|||
package com.face.global.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.enums.SqlMethod;
|
||||
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
|
||||
import com.baomidou.mybatisplus.core.toolkit.*;
|
||||
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.face.global.consts.GlobalConstant;
|
||||
import com.face.global.enums.DeleteType;
|
||||
import com.face.global.enums.UserTypeEnum;
|
||||
import com.face.global.mapper.GlobalBaseMapper;
|
||||
import com.face.global.service.IGlobalBaseService;
|
||||
import com.face.global.user.UserStore;
|
||||
import com.face.global.vo.GlobalUser;
|
||||
import com.face.global.vo.Operate;
|
||||
import com.face.util.JsonUtils;
|
||||
import com.face.util.SystemExceptionUtils;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.apache.ibatis.binding.MapperMethod;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.aop.framework.AopProxyUtils;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.cglib.beans.BeanMap;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.baomidou.mybatisplus.core.toolkit.StringPool.*;
|
||||
|
||||
public class GlobalBaseService<T, ID extends Serializable> implements IGlobalBaseService<T, ID> {
|
||||
|
||||
private GlobalBaseMapper<T, ID> globalBaseMapper;
|
||||
|
||||
private IdentifierGenerator identifierGenerator;
|
||||
|
||||
private volatile SqlSessionFactory sqlSessionFactory;
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private Class<GlobalBaseMapper<T, ID>> mapperClass;
|
||||
|
||||
public GlobalBaseService(GlobalBaseMapper<T, ID> globalBaseMapper, IdentifierGenerator identifierGenerator) {
|
||||
this.globalBaseMapper = globalBaseMapper;
|
||||
this.identifierGenerator = identifierGenerator;
|
||||
this.mapperClass = (Class<GlobalBaseMapper<T, ID>>) globalBaseMapper.getClass().getInterfaces()[0];
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int insert(T entity) {
|
||||
return this.globalBaseMapper.insert(entity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int deleteById(ID id) {
|
||||
return this.globalBaseMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int deleteById(T entity) {
|
||||
return this.globalBaseMapper.deleteById(entity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int deleteByMap(Map columnMap) {
|
||||
return this.globalBaseMapper.deleteByMap(columnMap);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int delete(Wrapper<T> queryWrapper) {
|
||||
return this.globalBaseMapper.delete(queryWrapper);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int updateByIdForInt(T entity) {
|
||||
return this.globalBaseMapper.updateById(entity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int updateForInt(T entity, Wrapper<T> updateWrapper) {
|
||||
return this.globalBaseMapper.update(entity, updateWrapper);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int updateForInt(Wrapper<T> updateWrapper) {
|
||||
return this.globalBaseMapper.update(updateWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T selectById(ID id) {
|
||||
return this.globalBaseMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T selectOne(Wrapper<T> queryWrapper) {
|
||||
return this.globalBaseMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T selectOne(Wrapper<T> queryWrapper, boolean throwEx) {
|
||||
return this.globalBaseMapper.selectOne(queryWrapper, throwEx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(Wrapper<T> queryWrapper) {
|
||||
return this.globalBaseMapper.exists(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseMapper<T> getBaseMapper() {
|
||||
return this.globalBaseMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> selectByMap(Map columnMap) {
|
||||
return this.globalBaseMapper.selectByMap(columnMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long selectCount(Wrapper<T> queryWrapper) {
|
||||
return this.globalBaseMapper.selectCount(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> selectList(Wrapper<T> queryWrapper) {
|
||||
return this.globalBaseMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> selectBatchIds(Collection<ID> idList) {
|
||||
return this.globalBaseMapper.selectBatchIds(idList);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int deleteBatchIds(Collection<ID> idList) {
|
||||
return this.globalBaseMapper.deleteBatchIds(idList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generatorStringId() {
|
||||
return String.valueOf(identifierGenerator.nextId(null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long generatorLongId() {
|
||||
return identifierGenerator.nextId(null).longValue();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int insertH(ID id, Function<ID, Map<String, Object>> content, Operate operate) {
|
||||
Map<Object, Object> data = new HashMap<>();
|
||||
data.putAll(BeanMap.create(operate));
|
||||
if (operate.getExtendsData() != null) {
|
||||
data.putAll(operate.getExtendsData());
|
||||
}
|
||||
data.put("createDate", operate.getModifyDate());
|
||||
data.put("isDelete", DeleteType.NO_DELETE.getCode());
|
||||
data.put("createUser", operate.getModifyUser());
|
||||
data.put("createUserType", operate.getModifyUserType());
|
||||
if (operate.isGenerateId()) {
|
||||
operate.setId(this.generatorStringId());
|
||||
}
|
||||
data.put("id", operate.getId());
|
||||
data.put("mainId", id);
|
||||
Object contentObject = content.apply(id);
|
||||
if (contentObject != null) {
|
||||
data.put("content", JsonUtils.toJsonString(contentObject));
|
||||
}
|
||||
return this.globalBaseMapper.insertH(data);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Operate getUpdateOperate(boolean generateSeq) {
|
||||
Operate operate = Operate.inst()
|
||||
.modifyUser(this.getOperateUser().getUserId())
|
||||
.modifyUserType(this.getOperateUser().getUserType()).update();
|
||||
if (generateSeq) {
|
||||
operate.setSeqno(this.generatorLongId());
|
||||
}
|
||||
return operate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Operate getInsertOperate(boolean generateSeq) {
|
||||
Operate operate = Operate.inst()
|
||||
.modifyUser(this.getOperateUser().getUserId())
|
||||
.modifyUserType(this.getOperateUser().getUserType()).insert();
|
||||
if (generateSeq) {
|
||||
operate.setSeqno(this.generatorLongId());
|
||||
}
|
||||
return operate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Operate getDeleteOperate(boolean generateSeq) {
|
||||
Operate operate = Operate.inst()
|
||||
.modifyUser(this.getOperateUser().getUserId())
|
||||
.modifyUserType(this.getOperateUser().getUserType())
|
||||
.delete();
|
||||
if (generateSeq) {
|
||||
operate.setSeqno(this.generatorLongId());
|
||||
}
|
||||
return operate;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public boolean updateSomeColumnById(List list) {
|
||||
Class modelClass = GenericTypeUtils.resolveTypeArguments(getClass(), GlobalBaseService.class)[0];
|
||||
TableName tableNameAnnotation = (TableName) modelClass.getAnnotation(TableName.class);
|
||||
String tableName = tableNameAnnotation.value();
|
||||
Field[] baseFields = FieldUtils.getAllFields(modelClass);
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (Field field : baseFields) {
|
||||
if (field.getAnnotation(TableId.class) != null) {
|
||||
keys.add(field.getName());
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isEmpty(keys)) {
|
||||
throw SystemExceptionUtils.buildBusinessException("noKeys");
|
||||
}
|
||||
String sqlStatement = GlobalBaseMapper.class.getName() + StringPool.DOT + "updateSomeColumnById";
|
||||
Field[] updateFields = FieldUtils.getAllFields(list.get(0).getClass());
|
||||
List<String> allUpdateFields = Arrays.stream(updateFields).filter(field -> {
|
||||
if (keys.contains(field.getName())) {
|
||||
return false;
|
||||
}
|
||||
TableField tableField = field.getAnnotation(TableField.class);
|
||||
if (tableField == null) {
|
||||
return true;
|
||||
}
|
||||
return tableField.updateStrategy() != FieldStrategy.NEVER;
|
||||
}).map(field -> field.getName()).toList();
|
||||
if (CollectionUtils.isEmpty(allUpdateFields)) {
|
||||
throw SystemExceptionUtils.buildBusinessException("noUpdateColumn");
|
||||
}
|
||||
StringBuffer updateSql = new StringBuffer();
|
||||
StringBuffer whereSql = new StringBuffer();
|
||||
List<String> wheres = new ArrayList<>();
|
||||
List<String> updates = new ArrayList<>();
|
||||
for (String key : keys) {
|
||||
wheres.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, key).concat(EQUALS)
|
||||
.concat(HASH_LEFT_BRACE).concat("entity.").concat(key).concat(RIGHT_BRACE));
|
||||
}
|
||||
whereSql.append(String.join(" and ", wheres));
|
||||
for (String key : allUpdateFields) {
|
||||
updates.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, key).concat(EQUALS)
|
||||
.concat(HASH_LEFT_BRACE).concat("entity.").concat(key).concat(RIGHT_BRACE));
|
||||
}
|
||||
updateSql.append(String.join(" and ", updates));
|
||||
return SqlHelper.executeBatch(getSqlSessionFactory(), this.log, list, DEFAULT_BATCH_SIZE,
|
||||
(sqlSession, data) -> {
|
||||
sqlSession.update(sqlStatement, Map.of("tableName", tableName, "updateSql", updateSql.toString(), "whereSql", whereSql.toString(), "entity", data));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalUser getOperateUser() {
|
||||
GlobalUser globalUser = new GlobalUser();
|
||||
if (UserStore.getCurrentUser() == null) {
|
||||
globalUser.setUserName(GlobalConstant.SYSTEM_OPERATE_USER_ID);
|
||||
globalUser.setUserType(UserTypeEnum.SYS_USER.getCode());
|
||||
globalUser.setUserId(GlobalConstant.SYSTEM_OPERATE_USER_ID);
|
||||
return globalUser;
|
||||
}
|
||||
return UserStore.getCurrentUser();
|
||||
}
|
||||
|
||||
protected GlobalUser getOperateUser(String userId, UserTypeEnum userTypeEnum) {
|
||||
GlobalUser globalUser = new GlobalUser();
|
||||
if (UserStore.getCurrentUser() == null) {
|
||||
globalUser.setUserType(userTypeEnum.getCode());
|
||||
globalUser.setUserId(userId);
|
||||
return globalUser;
|
||||
}
|
||||
return UserStore.getCurrentUser();
|
||||
}
|
||||
|
||||
protected final Class<?>[] typeArguments = GenericTypeUtils.resolveTypeArguments(getClass(), ServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public Class<T> getEntityClass() {
|
||||
return (Class<T>) this.typeArguments[1];
|
||||
}
|
||||
|
||||
protected SqlSessionFactory getSqlSessionFactory() {
|
||||
if (this.sqlSessionFactory == null) {
|
||||
synchronized (this) {
|
||||
if (this.sqlSessionFactory == null) {
|
||||
Object target = this.globalBaseMapper;
|
||||
// 这个检查目前看着来说基本上可以不用判断Aop是不是存在了.
|
||||
if (com.baomidou.mybatisplus.extension.toolkit.AopUtils.isLoadSpringAop()) {
|
||||
while (AopUtils.isAopProxy(target)) {
|
||||
target = AopProxyUtils.getSingletonTarget(target);
|
||||
}
|
||||
}
|
||||
if (target instanceof MybatisMapperProxy) {
|
||||
MybatisMapperProxy mybatisMapperProxy = (MybatisMapperProxy) Proxy.getInvocationHandler(target);
|
||||
SqlSessionTemplate sqlSessionTemplate = (SqlSessionTemplate) mybatisMapperProxy.getSqlSession();
|
||||
this.sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
|
||||
} else if (Proxy.getInvocationHandler(target) instanceof MybatisMapperProxy) {
|
||||
MybatisMapperProxy mybatisMapperProxy = (MybatisMapperProxy) Proxy.getInvocationHandler(target);
|
||||
SqlSessionTemplate sqlSessionTemplate = (SqlSessionTemplate) mybatisMapperProxy.getSqlSession();
|
||||
this.sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
|
||||
} else {
|
||||
this.sqlSessionFactory = GlobalConfigUtils.currentSessionFactory(this.getEntityClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.sqlSessionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入
|
||||
*
|
||||
* @param entityList ignore
|
||||
* @param batchSize ignore
|
||||
* @return ignore
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean saveBatch(Collection<T> entityList, int batchSize) {
|
||||
String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
|
||||
return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取mapperStatementId
|
||||
*
|
||||
* @param sqlMethod 方法名
|
||||
* @return 命名id
|
||||
* @since 3.4.0
|
||||
*/
|
||||
protected String getSqlStatement(SqlMethod sqlMethod) {
|
||||
return SqlHelper.getSqlStatement(mapperClass, sqlMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* TableId 注解存在更新记录,否插入一条记录
|
||||
*
|
||||
* @param entity 实体对象
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean saveOrUpdate(T entity) {
|
||||
if (null != entity) {
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.getEntityClass());
|
||||
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
|
||||
String keyProperty = tableInfo.getKeyProperty();
|
||||
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
|
||||
Object idVal = tableInfo.getPropertyValue(entity, tableInfo.getKeyProperty());
|
||||
return StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal)) ? save(entity) : updateById(entity);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.getEntityClass());
|
||||
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
|
||||
String keyProperty = tableInfo.getKeyProperty();
|
||||
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
|
||||
return SqlHelper.saveOrUpdateBatch(getSqlSessionFactory(), this.mapperClass, log, entityList, batchSize, (sqlSession, entity) -> {
|
||||
Object idVal = tableInfo.getPropertyValue(entity, keyProperty);
|
||||
return StringUtils.checkValNull(idVal)
|
||||
|| CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
|
||||
}, (sqlSession, entity) -> {
|
||||
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||
param.put(Constants.ENTITY, entity);
|
||||
sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean updateBatchById(Collection<T> entityList, int batchSize) {
|
||||
String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
|
||||
return executeBatch(entityList, batchSize, (sqlSession, entity) -> {
|
||||
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||
param.put(Constants.ENTITY, entity);
|
||||
sqlSession.update(sqlStatement, param);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
|
||||
return this.globalBaseMapper.selectOne(queryWrapper, throwEx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<T> getOneOpt(Wrapper<T> queryWrapper, boolean throwEx) {
|
||||
return Optional.ofNullable(this.globalBaseMapper.selectOne(queryWrapper, throwEx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
|
||||
return SqlHelper.getObject(log, this.globalBaseMapper.selectMaps(queryWrapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
|
||||
return SqlHelper.getObject(log, listObjs(queryWrapper, mapper));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行批量操作
|
||||
*
|
||||
* @param list 数据集合
|
||||
* @param batchSize 批量大小
|
||||
* @param consumer 执行方法
|
||||
* @param <E> 泛型
|
||||
* @return 操作结果
|
||||
* @since 3.3.1
|
||||
*/
|
||||
protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
|
||||
return SqlHelper.executeBatch(getSqlSessionFactory(), this.log, list, batchSize, consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeById(Serializable id) {
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(getEntityClass());
|
||||
if (tableInfo.isWithLogicDelete() && tableInfo.isWithUpdateFill()) {
|
||||
return removeById(id, true);
|
||||
}
|
||||
return SqlHelper.retBool(getBaseMapper().deleteById(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean removeByIds(Collection<?> list) {
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return false;
|
||||
}
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(getEntityClass());
|
||||
if (tableInfo.isWithLogicDelete() && tableInfo.isWithUpdateFill()) {
|
||||
return removeBatchByIds(list, true);
|
||||
}
|
||||
return SqlHelper.retBool(getBaseMapper().deleteBatchIds(list));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.face.global.user;
|
||||
|
||||
|
||||
import com.face.global.vo.GlobalOrgInfo;
|
||||
import com.face.global.vo.GlobalUser;
|
||||
|
||||
public class UserStore {
|
||||
private static final ThreadLocal<GlobalUser> USER_THREAD_LOCAL_STORE = new InheritableThreadLocal<>();
|
||||
|
||||
private static final ThreadLocal<String> USER_TOKEN = new InheritableThreadLocal<>();
|
||||
|
||||
private static final ThreadLocal<GlobalOrgInfo> ORG_INFO = new InheritableThreadLocal<>();
|
||||
|
||||
public static void setUser(GlobalUser globalUser) {
|
||||
USER_THREAD_LOCAL_STORE.set(globalUser);
|
||||
}
|
||||
public static void setUserToken(String token) {
|
||||
USER_TOKEN.set(token);
|
||||
}
|
||||
|
||||
public static GlobalUser getCurrentUser() {
|
||||
return USER_THREAD_LOCAL_STORE.get();
|
||||
}
|
||||
public static String getUserToken() {
|
||||
return USER_TOKEN.get();
|
||||
}
|
||||
|
||||
public static void setOrgInfo(GlobalOrgInfo orgInfo) {
|
||||
ORG_INFO.set(orgInfo);
|
||||
}
|
||||
|
||||
public static GlobalOrgInfo getOrgInfo() {
|
||||
return ORG_INFO.get();
|
||||
}
|
||||
|
||||
public static String getCurrentOrgId() {
|
||||
if (ORG_INFO.get() != null) {
|
||||
return ORG_INFO.get().getOrgId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void clearUserInfo () {
|
||||
USER_THREAD_LOCAL_STORE.remove();
|
||||
USER_TOKEN.remove();
|
||||
ORG_INFO.remove();
|
||||
}
|
||||
|
||||
public static String getCurrentUserId() {
|
||||
if (UserStore.getCurrentUser() != null) {
|
||||
return UserStore.getCurrentUser().getUserId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getToken() {
|
||||
return UserStore.getUserToken();
|
||||
}
|
||||
|
||||
public static String getCurrentUserType() {
|
||||
if (UserStore.getCurrentUser() != null) {
|
||||
return UserStore.getCurrentUser().getUserType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.face.global.validator;
|
||||
|
||||
/**
|
||||
* 枚举验证接口
|
||||
*
|
||||
*/
|
||||
public interface EnumValidator {
|
||||
Object getValue();
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.face.global.validator.enums;
|
||||
|
||||
|
||||
import com.face.global.validator.EnumValidator;
|
||||
import com.face.global.validator.impl.EnumConstraintValidator;
|
||||
import jakarta.validation.Constraint;
|
||||
import jakarta.validation.Payload;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* 枚举检查注解
|
||||
*
|
||||
*/
|
||||
@Documented
|
||||
@Constraint(validatedBy = EnumConstraintValidator.class)
|
||||
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
|
||||
@Retention(RUNTIME)
|
||||
@Repeatable(EnumCheck.List.class)
|
||||
public @interface EnumCheck {
|
||||
/**
|
||||
* 提示信息
|
||||
*
|
||||
*/
|
||||
String message() default "{javax.validation.constraints.EnumCheck.message}";
|
||||
|
||||
/**
|
||||
* 分组
|
||||
*
|
||||
*/
|
||||
Class<?>[] groups() default { };
|
||||
|
||||
/**
|
||||
* 扩展对象
|
||||
*
|
||||
*/
|
||||
Class<? extends Payload>[] payload() default { };
|
||||
|
||||
/**
|
||||
* 必须实现EnumValidator接口的枚举类
|
||||
*
|
||||
*/
|
||||
Class<? extends EnumValidator> clazz();
|
||||
|
||||
/**
|
||||
* 调用的方法名称
|
||||
*/
|
||||
String method() default "getValue";
|
||||
|
||||
/**
|
||||
* Defines several {@code @In} constraints on the same element.
|
||||
*
|
||||
* @see EnumCheck
|
||||
*/
|
||||
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
|
||||
@Retention(RUNTIME)
|
||||
@Documented
|
||||
@interface List {
|
||||
/**
|
||||
* In数组
|
||||
*/
|
||||
EnumCheck[] value();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.face.global.validator.enums;
|
||||
|
||||
|
||||
import com.face.global.validator.impl.MaxDoubleConstraintValidator;
|
||||
import jakarta.validation.Constraint;
|
||||
import jakarta.validation.Payload;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Documented
|
||||
@Constraint(validatedBy = MaxDoubleConstraintValidator.class)
|
||||
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
|
||||
@Retention(RUNTIME)
|
||||
public @interface MaxDouble {
|
||||
|
||||
String message() default "{jakarta.validation.constraints.Max.message}";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
double value();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.face.global.validator.enums;
|
||||
|
||||
import com.face.global.validator.impl.MinDoubleConstraintValidator;
|
||||
import jakarta.validation.Constraint;
|
||||
import jakarta.validation.Payload;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Documented
|
||||
@Constraint(validatedBy = MinDoubleConstraintValidator.class)
|
||||
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
|
||||
@Retention(RUNTIME)
|
||||
public @interface MinDouble {
|
||||
|
||||
String message() default "{jakarta.validation.constraints.Min.message}";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
double value();
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.face.global.validator.impl;
|
||||
|
||||
|
||||
import com.face.global.validator.enums.EnumCheck;
|
||||
import com.face.util.SystemExceptionUtils;
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 枚举验证器实现
|
||||
*/
|
||||
@Slf4j
|
||||
public class EnumConstraintValidator implements ConstraintValidator<EnumCheck, Object> {
|
||||
/**
|
||||
* 注解对象
|
||||
*/
|
||||
private EnumCheck annotation;
|
||||
|
||||
/**
|
||||
* 初始化方法
|
||||
*
|
||||
* @param constraintAnnotation 注解对象
|
||||
*/
|
||||
@Override
|
||||
public void initialize(EnumCheck constraintAnnotation) {
|
||||
this.annotation = constraintAnnotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Object value, ConstraintValidatorContext context) {
|
||||
if (Objects.isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
Object[] enumConstants = annotation.clazz().getEnumConstants();
|
||||
try {
|
||||
// 核心代码实现
|
||||
Method method = annotation.clazz().getMethod(annotation.method());
|
||||
for (Object enumConstant : enumConstants) {
|
||||
if (value.equals(method.invoke(enumConstant))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("validEnumFail", e);
|
||||
throw SystemExceptionUtils.buildBusinessException("validEnumFail");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.face.global.validator.impl;
|
||||
|
||||
import com.face.global.validator.enums.MaxDouble;
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
public class MaxDoubleConstraintValidator implements ConstraintValidator<MaxDouble, Object> {
|
||||
/**
|
||||
* 注解对象
|
||||
*/
|
||||
private MaxDouble annotation;
|
||||
|
||||
/**
|
||||
* 初始化方法
|
||||
*
|
||||
* @param constraintAnnotation 注解对象
|
||||
*/
|
||||
@Override
|
||||
public void initialize(MaxDouble constraintAnnotation) {
|
||||
this.annotation = constraintAnnotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Object value, ConstraintValidatorContext context) {
|
||||
if (Objects.isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
if (!(value instanceof Double)) {
|
||||
return true;
|
||||
}
|
||||
return ((Double) value).compareTo(annotation.value()) <= 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.face.global.validator.impl;
|
||||
|
||||
|
||||
import com.face.global.validator.enums.MinDouble;
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* double
|
||||
*/
|
||||
@Slf4j
|
||||
public class MinDoubleConstraintValidator implements ConstraintValidator<MinDouble, Object> {
|
||||
/**
|
||||
* 注解对象
|
||||
*/
|
||||
private MinDouble annotation;
|
||||
|
||||
/**
|
||||
* 初始化方法
|
||||
*
|
||||
* @param constraintAnnotation 注解对象
|
||||
*/
|
||||
@Override
|
||||
public void initialize(MinDouble constraintAnnotation) {
|
||||
this.annotation = constraintAnnotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Object value, ConstraintValidatorContext context) {
|
||||
if (Objects.isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
if (!(value instanceof Double)) {
|
||||
return true;
|
||||
}
|
||||
return ((Double) value).compareTo(annotation.value()) >= 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @author: admin
|
||||
* @date: 2018年09月30日 20:13
|
||||
*/
|
||||
@Data
|
||||
public class ApiResult<R> {
|
||||
private R data;
|
||||
|
||||
private String code;
|
||||
|
||||
private String message;
|
||||
|
||||
public ApiResult(String code, String message, R data) {
|
||||
this.data = data;
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public ApiResult(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DefaultAuthUser {
|
||||
private String phone;
|
||||
|
||||
private String password;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ExcelResponseVO {
|
||||
@Schema(title = "数据")
|
||||
List allData;
|
||||
|
||||
@Schema(title = "错误标识")
|
||||
Boolean errorFlag;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class GlobalOrgInfo {
|
||||
|
||||
private String orgId;
|
||||
|
||||
private String orgName;
|
||||
|
||||
private String orgFullName;
|
||||
|
||||
private long visitTime;
|
||||
/**
|
||||
* 是否是平台
|
||||
*/
|
||||
private boolean plat;
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class GlobalUser {
|
||||
private String userId;
|
||||
|
||||
private String userName;
|
||||
|
||||
private String userType;
|
||||
|
||||
private String minOpenId;
|
||||
|
||||
private String unionId;
|
||||
|
||||
private String wxType;
|
||||
|
||||
private Map<String, Object> otherProperties;
|
||||
|
||||
public String getString(String key, String defaultValue) {
|
||||
return Optional.ofNullable(otherProperties.get(key)).map(Objects::toString).orElse(defaultValue);
|
||||
}
|
||||
|
||||
public Boolean getBoolean(String key, Boolean defaultValue) {
|
||||
return Optional.ofNullable(otherProperties.get(key))
|
||||
.map(data -> Boolean.parseBoolean(data.toString()))
|
||||
.orElse(defaultValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
|
||||
import com.face.global.enums.OperateType;
|
||||
import com.face.global.enums.UserTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class Operate {
|
||||
|
||||
/**
|
||||
* 主表id
|
||||
*/
|
||||
private String mainId;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 历史序列
|
||||
*/
|
||||
private long seqno;
|
||||
|
||||
/**
|
||||
* 操作状态(1-新增,2-修改,3-删除)
|
||||
*/
|
||||
private String operateType;
|
||||
|
||||
/**
|
||||
* 最后操作人
|
||||
*/
|
||||
private String modifyUser;
|
||||
|
||||
/**
|
||||
* 最后操作时间
|
||||
*/
|
||||
private Date modifyDate;
|
||||
|
||||
|
||||
private String modifyUserType;
|
||||
|
||||
private boolean generateId;
|
||||
|
||||
private Map<String, Object> extendsData;
|
||||
|
||||
public Operate() {
|
||||
this.modifyDate = new Date();
|
||||
this.generateId = true;
|
||||
}
|
||||
|
||||
public Operate extendsData(Map<String, Object> extendsData) {
|
||||
this.extendsData = extendsData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Operate inst() {
|
||||
return new Operate();
|
||||
}
|
||||
|
||||
public Operate seqno(long seqno) {
|
||||
this.seqno = seqno;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate mainId(String mainId) {
|
||||
this.mainId = mainId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate generateId(boolean generateId) {
|
||||
this.generateId = generateId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate insert() {
|
||||
this.operateType = OperateType.ADD.getOperateType();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate update() {
|
||||
this.operateType = OperateType.UPDATE.getOperateType();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate customerType() {
|
||||
this.modifyUserType = UserTypeEnum.CUSTOMER.getCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Operate sysUserType() {
|
||||
this.modifyUserType = UserTypeEnum.SYS_USER.getCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate modifyUserType(String modifyUserType) {
|
||||
this.modifyUserType = modifyUserType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate delete() {
|
||||
this.operateType = OperateType.DELETE.getOperateType();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate modifyUser(String user) {
|
||||
this.modifyUser = user;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operate operateType(String operateType) {
|
||||
this.operateType = operateType;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class PageRequestVO {
|
||||
@Getter
|
||||
@Setter
|
||||
@Min(value = 1)
|
||||
private int pageIndex;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Min(value = 1)
|
||||
@Max(value = 200)
|
||||
private int pageSize;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date createStartDate;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@JsonFormat(pattern = "yyyy-MM-dd" , timezone = "GMT+8")
|
||||
private Date createEndDate;
|
||||
|
||||
private int start;
|
||||
|
||||
public int getStart() {
|
||||
return (pageIndex - 1) * pageSize;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String myUserId;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String myOrgId;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PageResponseFinanceVO<T> {
|
||||
private long totalSize;
|
||||
private List<T> data;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PageResponseVO<T> {
|
||||
private long totalSize;
|
||||
private List<T> data;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.face.global.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class TimeCostLog {
|
||||
private Long startTimeValue;
|
||||
private Date startTime;
|
||||
private Long endTimeValue;
|
||||
private Date endTime;
|
||||
private String userId;
|
||||
private String userName;
|
||||
private String orgId;
|
||||
private String orgName;
|
||||
private boolean start;
|
||||
private String traceId;
|
||||
private String authType;
|
||||
private String ip;
|
||||
private Map requestParams;
|
||||
private Map requestHeaders;
|
||||
private Map responseHeaders;
|
||||
private String uri;
|
||||
private String method;
|
||||
private long timeCost;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.face.jsonBean;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Base64;
|
||||
|
||||
public class ImgToBase64 {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Path imageFile = Paths.get("F:\\体验腾讯人脸融合-素材\\222.jpg");
|
||||
byte[] imageBytes = Files.readAllBytes(imageFile);
|
||||
|
||||
|
||||
/*
|
||||
InputStream imageInputStream = new FileInputStream("F:\\体验腾讯人脸融合-素材\\111.jpg");
|
||||
byte[] imageBytes = new byte[imageInputStream.available()];
|
||||
imageInputStream.read(imageBytes);
|
||||
imageInputStream.close();*/
|
||||
|
||||
String imgBase = Base64.getEncoder().encodeToString(imageBytes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.face.jsonBean;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class JsonFaceInfo {
|
||||
@JsonProperty("X")
|
||||
private int x;
|
||||
@JsonProperty("Y")
|
||||
int y;
|
||||
@JsonProperty("Width")
|
||||
int width;
|
||||
@JsonProperty("Height")
|
||||
int height;
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.face.jsonBean;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class JsonMaterialFace {
|
||||
//人脸ID
|
||||
@JsonProperty("FaceId")
|
||||
private String faceId;
|
||||
|
||||
//人脸坐标信息
|
||||
@JsonProperty("FaceInfo")
|
||||
private JsonFaceInfo faceInfo;
|
||||
|
||||
|
||||
public String getFaceId() {
|
||||
return faceId;
|
||||
}
|
||||
|
||||
public void setFaceId(String faceId) {
|
||||
this.faceId = faceId;
|
||||
}
|
||||
|
||||
public JsonFaceInfo getFaceInfo() {
|
||||
return faceInfo;
|
||||
}
|
||||
|
||||
public void setFaceInfo(JsonFaceInfo faceInfo) {
|
||||
this.faceInfo = faceInfo;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.face.jsonBean;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JsonMaterialInfo {
|
||||
//素材ID
|
||||
@JsonProperty("MaterialId")
|
||||
private String materialId;
|
||||
|
||||
//素材状态
|
||||
@JsonProperty("MaterialStatus")
|
||||
private int materialStatus;
|
||||
|
||||
@JsonProperty("CreateTime")
|
||||
private String createTime;
|
||||
|
||||
@JsonProperty("UpdateTime")
|
||||
private String updateTime;
|
||||
//素材人脸模版
|
||||
@JsonProperty("MaterialFaceList")
|
||||
List<JsonMaterialFace> materialFaceList;
|
||||
//素材名称
|
||||
@JsonProperty("MaterialName")
|
||||
private String materialName;
|
||||
//授权信息
|
||||
@JsonProperty("AuditResult")
|
||||
private String auditResult;
|
||||
|
||||
public String getMaterialId() {
|
||||
return materialId;
|
||||
}
|
||||
|
||||
public void setMaterialId(String materialId) {
|
||||
this.materialId = materialId;
|
||||
}
|
||||
|
||||
public int getMaterialStatus() {
|
||||
return materialStatus;
|
||||
}
|
||||
|
||||
public void setMaterialStatus(int materialStatus) {
|
||||
this.materialStatus = materialStatus;
|
||||
}
|
||||
|
||||
public String getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(String createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(String updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public List<JsonMaterialFace> getMaterialFaceList() {
|
||||
return materialFaceList;
|
||||
}
|
||||
|
||||
public void setMaterialFaceList(List<JsonMaterialFace> materialFaceList) {
|
||||
this.materialFaceList = materialFaceList;
|
||||
}
|
||||
|
||||
public String getMaterialName() {
|
||||
return materialName;
|
||||
}
|
||||
|
||||
public void setMaterialName(String materialName) {
|
||||
this.materialName = materialName;
|
||||
}
|
||||
|
||||
public String getAuditResult() {
|
||||
return auditResult;
|
||||
}
|
||||
|
||||
public void setAuditResult(String auditResult) {
|
||||
this.auditResult = auditResult;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.face.jsonBean;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class QiuTestRoot {
|
||||
|
||||
//素材数组
|
||||
@JsonProperty("MaterialInfos")
|
||||
List<JsonMaterialInfo> materialInfos;
|
||||
|
||||
//素材个数
|
||||
@JsonProperty("Count")
|
||||
int count;
|
||||
|
||||
//活动ID
|
||||
@JsonProperty("RequestId")
|
||||
private String requestId;
|
||||
|
||||
public List<JsonMaterialInfo> getMaterialInfos() {
|
||||
return materialInfos;
|
||||
}
|
||||
|
||||
public void setMaterialInfos(List<JsonMaterialInfo> materialInfos) {
|
||||
this.materialInfos = materialInfos;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public String getRequestId() {
|
||||
return requestId;
|
||||
}
|
||||
|
||||
public void setRequestId(String requestId) {
|
||||
this.requestId = requestId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.face.util;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class AesUtil {
|
||||
private static final String DEFAULT_CHARSET = "UTF-8";
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
*
|
||||
* @param data 要加密的数据
|
||||
* @param key 加密key
|
||||
* @param iv 加密iv
|
||||
* @return 加密的结果
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String data, String key, String iv) throws Exception {
|
||||
//"算法/模式/补码方式"PKCS5Padding"
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
byte[] plaintext = data.getBytes(DEFAULT_CHARSET);
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
|
||||
byte[] encrypted = cipher.doFinal(plaintext);
|
||||
return new Base64().encodeToString(encrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密方法
|
||||
*
|
||||
* @param data 要解密的数据
|
||||
* @param key 解密key
|
||||
* @param iv 解密iv
|
||||
* @return 解密的结果
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String decrypt(String data, String key, String iv) throws Exception {
|
||||
byte[] encrypted = new Base64().decode(data);
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
|
||||
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
|
||||
byte[] original = cipher.doFinal(encrypted);
|
||||
return new String(original, DEFAULT_CHARSET);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package com.face.util;
|
||||
|
||||
|
||||
import com.face.global.enums.CommonCode;
|
||||
import com.face.global.language.LanguageStore;
|
||||
import com.face.global.vo.ApiResult;
|
||||
import com.face.global.vo.PageResponseFinanceVO;
|
||||
import com.face.global.vo.PageResponseVO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @author: admin
|
||||
* @date: 2018年10月01日 12:57w
|
||||
*/
|
||||
public class ApiResultBuilder<T, R> {
|
||||
|
||||
private String code;
|
||||
|
||||
private String message;
|
||||
|
||||
private R data;
|
||||
|
||||
private Class<T> cls;
|
||||
|
||||
public static <T> ApiResultBuilder<T, List<T>> getListBuilder(Class<T> cls) {
|
||||
ApiResultBuilder<T, List<T>> builder = new ApiResultBuilder<>();
|
||||
builder.cls = cls;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static <T> ApiResultBuilder<T, T> getCommonBuilder(Class<T> cls) {
|
||||
ApiResultBuilder<T, T> builder = new ApiResultBuilder<>();
|
||||
builder.cls = cls;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static ApiResultBuilder<Object, Object> getRawBuilder() {
|
||||
return new ApiResultBuilder<>();
|
||||
}
|
||||
|
||||
|
||||
public ApiResultBuilder<T, R> success(R data) {
|
||||
this.code = CommonCode.SUCCESS.getCode();
|
||||
this.message = getMessage();
|
||||
this.data = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
private String getMessage() {
|
||||
if (StringUtils.isNotBlank(this.message)) {
|
||||
return message;
|
||||
}
|
||||
return MessageUtils.getMessage(this.code, null, LanguageStore.getLocale());
|
||||
}
|
||||
|
||||
public ApiResultBuilder<T, R> success() {
|
||||
this.code = CommonCode.SUCCESS.getCode();
|
||||
this.message = this.getMessage();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public ApiResultBuilder<T, R> error() {
|
||||
this.code = CommonCode.ERROR.getCode();
|
||||
this.message = this.getMessage();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ApiResultBuilder<T, R> error(String message) {
|
||||
this.code = CommonCode.ERROR.toString();
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ApiResultBuilder<T, R> baseInfo(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ApiResult<R> build() {
|
||||
return new ApiResult<>(this.code, this.message, this.data);
|
||||
}
|
||||
|
||||
|
||||
public static <T> ApiResultBuilder<T, PageResponseVO<T>> getPageCommonBuilder(Class<T> cls) {
|
||||
ApiResultBuilder<T, PageResponseVO<T>> builder = new ApiResultBuilder<>();
|
||||
builder.cls = cls;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static <T> ApiResultBuilder<T, PageResponseFinanceVO<T>> getPageFinanceCommonBuilder(Class<T> cls) {
|
||||
ApiResultBuilder<T, PageResponseFinanceVO<T>> builder = new ApiResultBuilder<>();
|
||||
builder.cls = cls;
|
||||
return builder;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.face.util;
|
||||
|
||||
import com.face.global.enums.CommonCode;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Slf4j
|
||||
public class BatchExecuteUtils {
|
||||
public static <T, ID> void pageAllById(int pageSize, ID startMaxId,
|
||||
PageMaxIdFunction<T, ID> pageFunction,
|
||||
Consumer<List<T>> pageConsumer,
|
||||
Function<T, ID> idFunction, Class<T> dataCls,
|
||||
Class<ID> idCls) {
|
||||
List<T> datas;
|
||||
ID startId = startMaxId;
|
||||
do {
|
||||
try {
|
||||
PageMaxParam pageMaxParam = PageMaxParam.builder().maxId(startId)
|
||||
.pageIndex(1).pageSize(pageSize).build();
|
||||
datas = pageFunction.pageByMax(pageMaxParam);
|
||||
pageConsumer.accept(datas);
|
||||
if (!CollectionUtils.isEmpty(datas)) {
|
||||
startId = idFunction.apply(datas.get(datas.size() - 1));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("pageAllByIdFail {}", startMaxId, e);
|
||||
throw SystemExceptionUtils.buildBusinessException(CommonCode.ERROR.getCode(), e);
|
||||
}
|
||||
} while (!CollectionUtils.isEmpty(datas) && datas.size() >= pageSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public interface PageMaxIdFunction<T, ID> {
|
||||
List<T> pageByMax(PageMaxParam<ID> pageMaxParam);
|
||||
}
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public static class PageMaxParam<ID> {
|
||||
private int pageIndex;
|
||||
private int pageSize;
|
||||
private ID maxId;
|
||||
}
|
||||
|
||||
public static <T> void pageAll(int pageSize,
|
||||
PageFunction<T, PageParam> pageFunction,
|
||||
Consumer<List<T>> pageConsumer,
|
||||
Class<T> dataCls) {
|
||||
List<T> datas;
|
||||
int pageIndex = 1;
|
||||
do {
|
||||
try {
|
||||
PageParam pageParam = PageParam.builder()
|
||||
.pageIndex(pageIndex).pageSize(pageSize).build();
|
||||
datas = pageFunction.page(pageParam);
|
||||
pageConsumer.accept(datas);
|
||||
if (CollectionUtils.isEmpty(datas) || datas.size() >= pageSize) {
|
||||
break;
|
||||
}
|
||||
pageIndex ++;
|
||||
} catch (Throwable e) {
|
||||
log.error("pageAllFail", e);
|
||||
throw SystemExceptionUtils.buildBusinessException(CommonCode.ERROR.getCode(), e);
|
||||
}
|
||||
} while (!CollectionUtils.isEmpty(datas) && datas.size() >= pageSize);
|
||||
}
|
||||
|
||||
|
||||
public interface PageFunction<T, PageParam> {
|
||||
List<T> page(PageParam pageMaxParam) throws Throwable;
|
||||
}
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public static class PageParam {
|
||||
private int pageIndex;
|
||||
private int pageSize;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/**
|
||||
* All rights Reserved, Designed By http://www.pete-cat.com/
|
||||
*
|
||||
* @Title: DataCopy.java
|
||||
* @Package com.petecat.formdesigner.util
|
||||
* @Description:复制数据工具类
|
||||
* @author: 成都皮特猫科技
|
||||
* @date:2017年11月27日 下午4:41:51
|
||||
* @version V1.0
|
||||
* @Copyright: 2017 www.pete-cat.com Inc. All rights reserved.
|
||||
* 注意:本内容仅限于成都皮特猫信息技术有限公司内部传阅,禁止外泄以及用于其他的商业目
|
||||
*/
|
||||
package com.face.util;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.springframework.cglib.beans.BeanCopier;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class DataCopy {
|
||||
private static final LoadingCache<CopyKey, BeanCopier> BEAN_COPIER = CacheBuilder.newBuilder()
|
||||
// 设置缓存个数
|
||||
.maximumSize(500)
|
||||
.build(new CacheLoader<>() {
|
||||
@Override
|
||||
public BeanCopier load(CopyKey copyKey) {
|
||||
return BeanCopier.create(copyKey.getSourseClass(), copyKey.getDestClass(), false);
|
||||
}
|
||||
});
|
||||
|
||||
public static <T> T shallowCopyData(Object source, Class<T> cls) {
|
||||
try {
|
||||
T obj = cls.newInstance();
|
||||
copyDataInner(source, obj);
|
||||
return obj;
|
||||
} catch (Exception e) {
|
||||
log.error("copyDataFail", e);
|
||||
throw SystemExceptionUtils.buildBusinessException("copyFail");
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyDataInner(Object source, Object obj) {
|
||||
try {
|
||||
String key = source.getClass().getName().concat("_").concat(obj.getClass().getName());
|
||||
BeanCopier beanCopier = BEAN_COPIER.get(CopyKey.builder().key(key)
|
||||
.sourseClass(source.getClass()).destClass(obj.getClass()).build());
|
||||
beanCopier.copy(source, obj, null);
|
||||
} catch (Exception e) {
|
||||
log.error("copyDataFail", e);
|
||||
throw SystemExceptionUtils.buildBusinessException("copyFail");
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> List<T> shallowCopyList(List<?> datas, Class<T> cls) {
|
||||
if (datas != null) {
|
||||
return datas.stream().map((t) -> {
|
||||
T obj = shallowCopyData(t, cls);
|
||||
return obj;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> List<T> deepCopyList(List<?> datas, TypeReference<List<T>> typeReference) {
|
||||
try {
|
||||
return JsonUtils.parseObject(JsonUtils.toJsonString(datas), typeReference);
|
||||
} catch (Exception e) {
|
||||
log.error("copyDataFail", e);
|
||||
throw SystemExceptionUtils.buildBusinessException("copyFail");
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T deepCopyData(Object source, Class<T> cls) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return JsonUtils.parseObject(JsonUtils.toJsonString(source), cls);
|
||||
} catch (Exception e) {
|
||||
log.error("copyDataFail", e);
|
||||
throw SystemExceptionUtils.buildBusinessException("copyFail");
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> List<T> deepCopyList(List<?> datas, Class<T> cls) {
|
||||
try {
|
||||
return datas.stream().map(data -> deepCopyData(data, cls)).collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
log.error("copyDataFail", e);
|
||||
throw SystemExceptionUtils.buildBusinessException("copyFail");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
static class CopyKey {
|
||||
|
||||
private String key;
|
||||
|
||||
private Class destClass;
|
||||
|
||||
private Class sourseClass;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
CopyKey copyKey = (CopyKey) o;
|
||||
return Objects.equals(key, copyKey.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyExistsField(Object source, Object target) {
|
||||
try {
|
||||
List<Field> sourceFields = FieldUtils.getAllFieldsList(source.getClass());
|
||||
List<Field> targetFields = FieldUtils.getAllFieldsList(target.getClass());
|
||||
Object value = null;
|
||||
for (Field targetField : targetFields) {
|
||||
List<Field> fields =
|
||||
sourceFields.stream().filter(field -> StringUtils.equals(field.getName(),
|
||||
targetField.getName())).toList();
|
||||
for (Field field : fields) {
|
||||
if (Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
value = FieldUtils.readField(field, source, true);
|
||||
FieldUtils.writeField(targetField, target, value, true);
|
||||
} catch (Exception e) {
|
||||
log.warn("copyExistsFieldFail {} {}", field, value, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("copyExistsField", e);
|
||||
throw SystemExceptionUtils.buildBusinessException("copyFail");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,695 @@
|
|||
package com.face.util;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Period;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 日期获取工具类
|
||||
*/
|
||||
|
||||
public class DateUtils {
|
||||
|
||||
public final static String DEFAULT_TIMEZONE = "GMT+8";
|
||||
|
||||
public final static String ISO_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
|
||||
|
||||
public final static String ISO_SHORT_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
|
||||
|
||||
public final static String DEFAULT_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public final static String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
|
||||
|
||||
public final static String DEFAULT_ONLY_TIME_FORMAT = "HH:mm:ss";
|
||||
|
||||
public final static String SHORT_TIME_FORMAT = "yyyy-MM-dd HH:mm";
|
||||
|
||||
public final static String FULL_SEQ_FORMAT = "yyyyMMddHHmmssSSS";
|
||||
|
||||
public final static String FULL_FORMAT = "yyyyMMddHHmmssSSS";
|
||||
|
||||
public final static String[] MULTI_FORMAT = {DEFAULT_DATE_FORMAT, DEFAULT_TIME_FORMAT, ISO_DATE_TIME_FORMAT, ISO_SHORT_DATE_TIME_FORMAT,
|
||||
SHORT_TIME_FORMAT, "yyyy-MM"};
|
||||
|
||||
public final static String FORMAT_YYYY = "yyyy";
|
||||
|
||||
public final static String FORMAT_YYYYMM = "yyyyMM";
|
||||
|
||||
public final static String FORMAT_YYYYMMDD = "yyyyMMdd";
|
||||
|
||||
public final static String FORMAT_YYYYMMDDHH = "yyyyMMddHH";
|
||||
|
||||
public final static String FORMAT_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
|
||||
|
||||
public final static String FORMAT_CORN = "ss mm HH dd MM ? yyyy";
|
||||
|
||||
public final static String ZONE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
|
||||
|
||||
public final static String[] MULTI_FORMAT_ALL = {DEFAULT_TIME_FORMAT, ZONE_TIME_FORMAT, FULL_FORMAT, DEFAULT_DATE_FORMAT, ISO_DATE_TIME_FORMAT, ISO_SHORT_DATE_TIME_FORMAT,
|
||||
SHORT_TIME_FORMAT};
|
||||
|
||||
/**
|
||||
* 日期转字符串
|
||||
* 默认格式: {@linkplain DateUtils#DEFAULT_DATE_FORMAT}
|
||||
*
|
||||
* @param date 日期对象
|
||||
* @return 返回格式化字符串
|
||||
*/
|
||||
public static String formatDate(Date date) {
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
return new SimpleDateFormat(DEFAULT_DATE_FORMAT).format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间对象转化为日期数字
|
||||
*
|
||||
* @param date 日期字符串 {@linkplain DateUtils#SHORT_TIME_FORMAT}
|
||||
* @param format 格式字符串
|
||||
* @return 返回日期数字
|
||||
*/
|
||||
public static String formatDate(Date date, String format) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return new SimpleDateFormat(format).format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间对象转化为corn表达式
|
||||
*
|
||||
* @param date 时间点
|
||||
* @return convert Date to cron ,eg. "0 06 10 15 10 ? 2018"
|
||||
*/
|
||||
public static String formatDateToCorn(Date date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return new SimpleDateFormat(FORMAT_CORN).format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间对象转化为日期数字
|
||||
*
|
||||
* @param date 日期字符串 {@linkplain DateUtils#SHORT_TIME_FORMAT}
|
||||
* @param format 格式字符串
|
||||
* @return 返回日期数字
|
||||
*/
|
||||
public static Integer formatDateToInt(Date date, String format) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return Integer.valueOf(new SimpleDateFormat(format).format(date));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间对象转化为日期数字
|
||||
*
|
||||
* @param date 日期字符串 {@linkplain DateUtils#SHORT_TIME_FORMAT}
|
||||
* @param format 格式字符串
|
||||
* @return 返回日期数字
|
||||
*/
|
||||
public static Long formatDateToLong(Date date, String format) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return Long.valueOf(new SimpleDateFormat(format).format(date));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间对象转化为日期字符串
|
||||
*
|
||||
* @param date 日期字符串 {@linkplain DateUtils#DEFAULT_TIME_FORMAT}
|
||||
* @return 返回日期字符串
|
||||
*/
|
||||
public static String formatTime(Date date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return new SimpleDateFormat(DEFAULT_TIME_FORMAT).format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间对象转化为日期字符串
|
||||
*
|
||||
* @param date 日期字符串 {@linkplain DateUtils#SHORT_TIME_FORMAT}
|
||||
* @return 返回日期字符串
|
||||
*/
|
||||
public static String formatShortTime(Date date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return new SimpleDateFormat(SHORT_TIME_FORMAT).format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间字符串转化为日期对象
|
||||
*
|
||||
* @param date 日期字符串
|
||||
* @param format 格式串
|
||||
* @return 返回日期对象
|
||||
*/
|
||||
public static Date parseDate(String date, String format) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new SimpleDateFormat(format).parse(date);
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间字符串转化为日期对象
|
||||
*
|
||||
* @param date 日期字符串
|
||||
* @param format 格式串
|
||||
* @return 返回日期对象
|
||||
*/
|
||||
public static Date parseTime(String date, String format) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new SimpleDateFormat(format).parse(date);
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间字符串转化为日期对象
|
||||
*
|
||||
* @param date 日期字符串 {@linkplain DateUtils#DEFAULT_TIME_FORMAT}
|
||||
* @return 返回日期对象
|
||||
*/
|
||||
public static Date parseDate(String date) {
|
||||
return parseDate(date, DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期时间字符串转化为日期对象
|
||||
*
|
||||
* @param date 日期字符串 {@linkplain DateUtils#DEFAULT_TIME_FORMAT}
|
||||
* @return 返回日期对象
|
||||
*/
|
||||
public static Date parseTime(String date) {
|
||||
return parseTime(date, DEFAULT_TIME_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对差异时间的格式化显示,方便人工查看
|
||||
*
|
||||
* @param diffMillis 差异时间(毫秒)
|
||||
* @return 人能看懂的字符串
|
||||
*/
|
||||
public static String getHumanDisplayForTimediff(Long diffMillis) {
|
||||
if (diffMillis == null) {
|
||||
return "";
|
||||
}
|
||||
long day = diffMillis / (24 * 60 * 60 * 1000);
|
||||
long hour = (diffMillis / (60 * 60 * 1000) - day * 24);
|
||||
long min = ((diffMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
|
||||
long se = (diffMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (day > 0) {
|
||||
sb.append(day).append("D");
|
||||
}
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
sb.append(df.format(hour)).append(":");
|
||||
sb.append(df.format(min)).append(":");
|
||||
sb.append(df.format(se));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日期相差天数
|
||||
*
|
||||
* @param beginDate 字符串类型开始日期
|
||||
* @param endDate 字符串类型结束日期
|
||||
* @return Long 日期相差天数
|
||||
*/
|
||||
public static Long getDiffDay(String beginDate, String endDate) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
|
||||
Long checkday = 0L;
|
||||
//开始结束相差天数
|
||||
try {
|
||||
checkday = (formatter.parse(endDate).getTime() - formatter.parse(beginDate).getTime()) / (1000 * 24 * 60 * 60);
|
||||
} catch (ParseException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
checkday = null;
|
||||
}
|
||||
return checkday;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日期相差天数
|
||||
*
|
||||
* @param beginDate Date类型开始日期
|
||||
* @param endDate Date类型结束日期
|
||||
* @return Long 相差天数
|
||||
*/
|
||||
public static Long getDiffDay(Date beginDate, Date endDate) {
|
||||
SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
|
||||
String strBeginDate = format.format(beginDate);
|
||||
|
||||
String strEndDate = format.format(endDate);
|
||||
return getDiffDay(strBeginDate, strEndDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* N天之后
|
||||
*
|
||||
* @param n 天数
|
||||
* @param date 日期
|
||||
* @return n天之后
|
||||
*/
|
||||
public static Date nDaysAfter(Integer n, Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) + n);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* N年之后
|
||||
*
|
||||
* @param n 年数
|
||||
* @param date 日期
|
||||
* @return n年之后
|
||||
*/
|
||||
public static Date nYearsAfter(Integer n, Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + n);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* N天之前
|
||||
*
|
||||
* @param n 天数
|
||||
* @param date 日期
|
||||
* @return N天之后
|
||||
*/
|
||||
public static Date nDaysAgo(Integer n, Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) - n);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* N年之前
|
||||
*
|
||||
* @param n 年数
|
||||
* @param date 日期
|
||||
* @return n年之前
|
||||
*/
|
||||
public static Date nYearsAgo(Integer n, Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - n);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期在全年中的第几周
|
||||
*
|
||||
* @param date 日期
|
||||
* @return 返回日期在这一年中的周数
|
||||
*/
|
||||
public static Integer getWeekOfYear(Date date) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(date);
|
||||
return Integer.valueOf(formatDate(date, FORMAT_YYYY) + c.get(Calendar.WEEK_OF_YEAR));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期时间
|
||||
*
|
||||
* @return 返回当前日期时间
|
||||
*/
|
||||
public static Date getCurrentDateTime() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期
|
||||
*
|
||||
* @return 返回当前日期
|
||||
*/
|
||||
public static Date getCurrentDate() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
//获取年份
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
//获取月份
|
||||
int month = calendar.get(Calendar.MONTH);
|
||||
//获取日
|
||||
int day = calendar.get(Calendar.DATE);
|
||||
calendar.set(year, month, day, 0, 0, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期格式化为年月日的日期
|
||||
*
|
||||
* @param date 日期
|
||||
* @return 年月日的日期
|
||||
*/
|
||||
public static Date formatDate2Date(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(date.getTime());
|
||||
//获取年份
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
//获取月份
|
||||
int month = calendar.get(Calendar.MONTH);
|
||||
//获取日
|
||||
int day = calendar.get(Calendar.DATE);
|
||||
calendar.set(year, month, day, 0, 0, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
//根据传入日期查询该日期前五天内全部日期,不考虑跨月情况
|
||||
public static List<String> getDatesList(String pdate) {
|
||||
List<String> datesList = new ArrayList<>();
|
||||
List<LocalDate> previousFiveDays = new ArrayList<>();
|
||||
LocalDate date2 = LocalDate.parse(pdate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
|
||||
// 逐一计算前五天的日期
|
||||
for (int i = 0; i < 5; i++) {
|
||||
//判断是不是在一个月份,如果不是,则不添加,反正则添加
|
||||
// if (date2.minusDays(i).getMonthValue() == date2.getMonthValue()) {
|
||||
// previousFiveDays.add(date2.minusDays(i));
|
||||
// }
|
||||
previousFiveDays.add(date2.minusDays(i));
|
||||
}
|
||||
// 格式化日期为字符串
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
for (LocalDate date : previousFiveDays) {
|
||||
String day = date.format(formatter);
|
||||
datesList.add(day);
|
||||
}
|
||||
return datesList;
|
||||
}
|
||||
|
||||
//根据传入的开始时间、结束时间查询该范围内的全部时间
|
||||
public static List<String> getRangeDateList(String sdate, String edate) {
|
||||
LocalDate startDate = LocalDate.parse(sdate);
|
||||
LocalDate endDate = LocalDate.parse(edate);
|
||||
|
||||
List<LocalDate> dateList = new ArrayList<>();
|
||||
List<String> rangeList = new ArrayList<>();
|
||||
LocalDate currentDate = startDate;
|
||||
|
||||
while (!currentDate.isAfter(endDate)) {
|
||||
dateList.add(currentDate);
|
||||
currentDate = currentDate.plus(Period.ofDays(1));
|
||||
}
|
||||
//格式转换
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
for (LocalDate date : dateList) {
|
||||
String day = date.format(formatter);
|
||||
rangeList.add(day);
|
||||
}
|
||||
|
||||
return rangeList;
|
||||
}
|
||||
|
||||
//根据月份获取该月的全部日期信息
|
||||
public static List<String> getMonthDates(String pdate) {
|
||||
List<String> dateList = new ArrayList<>();
|
||||
List<Date> dates = new ArrayList<>();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf.parse(pdate);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||
int month = calendar.get(Calendar.MONTH);
|
||||
while (calendar.get(Calendar.MONTH) == month) {
|
||||
dates.add(calendar.getTime());
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
for (Date date1 : dates) {
|
||||
dateList.add(sdf.format(date1));
|
||||
}
|
||||
return dateList;
|
||||
}
|
||||
|
||||
//获取传入月份的开始时间和结束时间
|
||||
public static List<String> getBEDateOfMonth(String month) {
|
||||
List<String> dateList = new ArrayList<>();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf.parse(month);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
// 获取给定日期所在月份的开始时间
|
||||
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||
Date monthStartDate = calendar.getTime();
|
||||
// 获取给定日期所在月份的结束时间
|
||||
calendar.add(Calendar.MONTH, 1);
|
||||
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||
Date monthEndDate = calendar.getTime();
|
||||
String startDate = sdf.format(monthStartDate);
|
||||
String endDate = sdf.format(monthEndDate);
|
||||
dateList.add(startDate);
|
||||
dateList.add(endDate);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return dateList;
|
||||
}
|
||||
|
||||
//获取上一个月
|
||||
public static String getLastMonth(String month) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date date = null;
|
||||
try {
|
||||
date = format.parse(month);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
// 设置为当前时间
|
||||
calendar.setTime(date);
|
||||
calendar.add(Calendar.MONTH, -1);
|
||||
// 设置为上一个月
|
||||
//calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
|
||||
date = calendar.getTime();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
//获取起止时间
|
||||
public static List<String> getStartStopTime(String startMonth, String endMonth) {
|
||||
List<String> list = new ArrayList<>();
|
||||
//开始时间
|
||||
startMonth = startMonth.substring(0, 7) + "-01";
|
||||
//结束时间
|
||||
// 将字符串转换为 LocalDate 对象
|
||||
LocalDate date = LocalDate.parse(endMonth, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
|
||||
// 获取该月的最后一天
|
||||
endMonth = date.withDayOfMonth(date.lengthOfMonth()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
list.add(startMonth);
|
||||
list.add(endMonth);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
//获取传入月份范围的全部月份的起止时间
|
||||
public static Map<String, List<String>> getMonthStartEnd(String start, String end) {
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
List<String> startMonthList = new ArrayList<>();
|
||||
List<String> endMonthList = new ArrayList<>();
|
||||
|
||||
// 将字符串转换为 LocalDate 对象
|
||||
LocalDate startMonth = LocalDate.parse(start, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
LocalDate endMonth = LocalDate.parse(end, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
|
||||
// 遍历月份范围并输出每个月的开始和结束时间
|
||||
LocalDate currentMonth = startMonth;
|
||||
while (!currentMonth.isAfter(endMonth)) {
|
||||
String firstDayOfMonth = currentMonth.withDayOfMonth(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
String lastDayOfMonth = currentMonth.withDayOfMonth(currentMonth.lengthOfMonth()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
startMonthList.add(firstDayOfMonth);
|
||||
endMonthList.add(lastDayOfMonth);
|
||||
// 下一个月
|
||||
currentMonth = currentMonth.plusMonths(1);
|
||||
}
|
||||
map.put("start", startMonthList);
|
||||
map.put("end", endMonthList);
|
||||
return map;
|
||||
}
|
||||
|
||||
//获取月份的天数
|
||||
public static int getDaysNumByYearMonth(String date) {
|
||||
int year = Integer.parseInt(date.substring(0, 4));
|
||||
int month = Integer.parseInt(date.substring(5, 7));
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.YEAR, year);
|
||||
calendar.set(Calendar.MONTH, month - 1);
|
||||
calendar.set(Calendar.DATE, 1);
|
||||
calendar.roll(Calendar.DATE, -1);
|
||||
return calendar.get(Calendar.DATE);
|
||||
}
|
||||
|
||||
|
||||
public static String getWeekByDate(String date) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
try {
|
||||
Date givenDate = sdf.parse(date); // 替换为你要检查的日期
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(givenDate);
|
||||
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
|
||||
|
||||
String weekday;
|
||||
switch (dayOfWeek) {
|
||||
case Calendar.SUNDAY:
|
||||
weekday = "0";
|
||||
break;
|
||||
case Calendar.MONDAY:
|
||||
weekday = "1";
|
||||
break;
|
||||
case Calendar.TUESDAY:
|
||||
weekday = "2";
|
||||
break;
|
||||
case Calendar.WEDNESDAY:
|
||||
weekday = "3";
|
||||
break;
|
||||
case Calendar.THURSDAY:
|
||||
weekday = "4";
|
||||
break;
|
||||
case Calendar.FRIDAY:
|
||||
weekday = "5";
|
||||
break;
|
||||
case Calendar.SATURDAY:
|
||||
weekday = "6";
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + dayOfWeek);
|
||||
}
|
||||
System.out.println("给定日期是:" + weekday);
|
||||
return weekday;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Date stringToDate(String dateString, String format) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(format);
|
||||
try {
|
||||
return formatter.parse(dateString);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getWeekByDateName(String date) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
try {
|
||||
Date givenDate = sdf.parse(date); // 替换为你要检查的日期
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(givenDate);
|
||||
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
|
||||
|
||||
String weekday;
|
||||
switch (dayOfWeek) {
|
||||
case Calendar.SUNDAY:
|
||||
weekday = "星期天";
|
||||
break;
|
||||
case Calendar.MONDAY:
|
||||
weekday = "星期一";
|
||||
break;
|
||||
case Calendar.TUESDAY:
|
||||
weekday = "星期二";
|
||||
break;
|
||||
case Calendar.WEDNESDAY:
|
||||
weekday = "星期三";
|
||||
break;
|
||||
case Calendar.THURSDAY:
|
||||
weekday = "星期四";
|
||||
break;
|
||||
case Calendar.FRIDAY:
|
||||
weekday = "星期五";
|
||||
break;
|
||||
case Calendar.SATURDAY:
|
||||
weekday = "星期六";
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + dayOfWeek);
|
||||
}
|
||||
System.out.println("给定日期是:" + weekday);
|
||||
return weekday;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据年月获取月初第一天日期
|
||||
* @param year
|
||||
* @param month
|
||||
* @return
|
||||
*/
|
||||
public static String getFirstDay(int year,int month,String format) {
|
||||
Calendar cale = Calendar.getInstance();
|
||||
|
||||
|
||||
|
||||
cale.set(Calendar.YEAR,year); //赋值年份
|
||||
cale.set(Calendar.MONTH, month-1);//赋值月份
|
||||
int lastDay = cale.getActualMinimum(Calendar.DAY_OF_MONTH);//获取月最大天数
|
||||
cale.set(Calendar.DAY_OF_MONTH, lastDay);//设置日历中月份的最大天数
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);//格式化日期yyyy-MM-dd
|
||||
String lastDayOfMonth = sdf.format(cale.getTime());
|
||||
return lastDayOfMonth;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据年月获取月末最后一天日期
|
||||
* @param year
|
||||
* @param month
|
||||
* @return
|
||||
*/
|
||||
public static String getLastDay(int year,int month,String format) {
|
||||
Calendar cale = Calendar.getInstance();
|
||||
|
||||
cale.set(Calendar.YEAR,year);//赋值年份
|
||||
cale.set(Calendar.MONTH, month-1);//赋值月份
|
||||
int lastDay = cale.getActualMaximum(Calendar.DAY_OF_MONTH);//获取月最大天数
|
||||
cale.set(Calendar.DAY_OF_MONTH, lastDay);//设置日历中月份的最大天数
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format); //格式化日期yyyy-MM-dd
|
||||
String lastDayOfMonth = sdf.format(cale.getTime());
|
||||
return lastDayOfMonth;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<String> cdf=DateUtils.getBEDateOfMonth("02");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package com.face.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.face.global.consts.GlobalConstant;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public class HttpUtils {
|
||||
public static Map getHeadersInfo(HttpServletRequest request, HttpHeaders headers) {
|
||||
Map datas = new HashMap();
|
||||
if (headers != null) {
|
||||
headers.entrySet().forEach(stringListEntry ->
|
||||
datas.put(stringListEntry.getKey(), stringListEntry.getValue()));
|
||||
} else {
|
||||
Enumeration<String> keys = request.getHeaderNames();
|
||||
while (keys.hasMoreElements()) {
|
||||
String key = keys.nextElement();
|
||||
datas.put(key, Lists.newArrayList(request.getHeaders(key).asIterator()));
|
||||
}
|
||||
}
|
||||
datas.remove(GlobalConstant.TOKEN_KEY);
|
||||
datas.remove(GlobalConstant.TOKEN_KEY.toLowerCase(Locale.ROOT));
|
||||
return datas;
|
||||
}
|
||||
|
||||
public static String getUri(ServletRequest servletRequest) {
|
||||
if (servletRequest instanceof HttpServletRequest) {
|
||||
return ((HttpServletRequest) servletRequest).getRequestURI();
|
||||
}
|
||||
return servletRequest.getRequestId();
|
||||
}
|
||||
|
||||
public static Map<String, String[]> getParams(ServletRequest servletRequest) {
|
||||
return servletRequest.getParameterMap();
|
||||
}
|
||||
|
||||
public static Map getHeaders(ServletRequest servletRequest) {
|
||||
if (servletRequest instanceof HttpServletRequest) {
|
||||
return getHeadersInfo((HttpServletRequest) servletRequest, null);
|
||||
}
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
public static Map getHeaders(ServletResponse servletResponse) {
|
||||
if (servletResponse instanceof HttpServletResponse) {
|
||||
return getHeadersInfo((HttpServletResponse) servletResponse);
|
||||
}
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
public static Map getHeadersInfo(HttpServletResponse response) {
|
||||
Map datas = new HashMap();
|
||||
Collection<String> keys = response.getHeaderNames();
|
||||
for (String key : keys) {
|
||||
datas.put(key, response.getHeaders(key));
|
||||
}
|
||||
datas.remove(GlobalConstant.TOKEN_KEY);
|
||||
return datas;
|
||||
}
|
||||
|
||||
public static void addHeader(ServletResponse servletResponse, String key, String id) {
|
||||
try {
|
||||
if (StringUtils.isBlank(id)) {
|
||||
return;
|
||||
}
|
||||
if (servletResponse instanceof HttpServletResponse) {
|
||||
((HttpServletResponse) servletResponse).addHeader(key, id);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static String getReqIp(HttpServletRequest request) {
|
||||
String ip = request.getHeader("X-Forwarded-For");
|
||||
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Real-IP");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
if (StringUtils.isNotBlank(ip) && !"unknown".equalsIgnoreCase(ip)
|
||||
&& StringUtils.contains(ip, ",")) {
|
||||
// 多次反向代理后会有多个IP值,第一个为真实IP。
|
||||
ip = StringUtils.substringBefore(ip, ",");
|
||||
}
|
||||
// 处理localhost访问
|
||||
if (StringUtils.isBlank(ip) || "unkown".equalsIgnoreCase(ip) || StringUtils.split(ip, ".").length != 4) {
|
||||
try {
|
||||
InetAddress inetAddress = InetAddress.getLocalHost();
|
||||
ip = inetAddress.getHostAddress();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.face.util;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class JsonUtil {
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public static <T> T fromJson(String jsonString, Class<T> clazz) throws IOException {
|
||||
return objectMapper.readValue(jsonString, clazz);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package com.face.util;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.face.global.enums.CommonCode;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
@Slf4j
|
||||
public class JsonUtils {
|
||||
@Getter
|
||||
private static ObjectMapper OBJECT_MAPPER;
|
||||
|
||||
private static final Set<String> FORMAT_DATES = Sets.newHashSet("yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");
|
||||
|
||||
|
||||
public static class DateJsonDeserializer extends JsonDeserializer<Date> {
|
||||
@Override
|
||||
public Date deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
|
||||
String valueStr = p.getValueAsString();
|
||||
if (StringUtils.isBlank(valueStr)) {
|
||||
return null;
|
||||
}
|
||||
if (NumberUtils.isCreatable(valueStr)) {
|
||||
return new Date(Long.parseLong(valueStr));
|
||||
}
|
||||
for (String format : FORMAT_DATES) {
|
||||
try {
|
||||
return new SimpleDateFormat(format).parse(valueStr);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(valueStr.concat(" convert date fail"));
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
OBJECT_MAPPER = JsonMapper.builder()
|
||||
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true)
|
||||
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
|
||||
.build();
|
||||
SimpleModule simpleModule = new SimpleModule();
|
||||
simpleModule.addDeserializer(Date.class, new DateJsonDeserializer());
|
||||
OBJECT_MAPPER.registerModule(simpleModule);
|
||||
}
|
||||
|
||||
|
||||
public static String toJsonString(Object value) {
|
||||
return toJsonString(value, false);
|
||||
}
|
||||
|
||||
public static String toJsonString(Object value, boolean throwException) {
|
||||
try {
|
||||
return OBJECT_MAPPER.writeValueAsString(value);
|
||||
} catch (Exception e) {
|
||||
log.error("toJsonStringFail", e);
|
||||
throwBusinessException(throwException, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String value, TypeReference<T> typeReference) {
|
||||
return parseObject(value, typeReference, false);
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String value, JavaType javaType) {
|
||||
return parseObject(value, javaType, false);
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String value, JavaType javaType, boolean throwException) {
|
||||
try {
|
||||
return OBJECT_MAPPER.readValue(value, javaType);
|
||||
} catch (Exception e) {
|
||||
log.error("parseObjectFail", e);
|
||||
throwBusinessException(throwException, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String value, TypeReference<T> typeReference, boolean throwException) {
|
||||
try {
|
||||
return OBJECT_MAPPER.readValue(value, typeReference);
|
||||
} catch (Exception e) {
|
||||
log.error("parseObjectFail", e);
|
||||
throwBusinessException(throwException, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String value, Class<T> cls) {
|
||||
return parseObject(value, cls, false);
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String value, Class<T> cls, boolean throwException) {
|
||||
try {
|
||||
return OBJECT_MAPPER.readValue(value, cls);
|
||||
} catch (Exception e) {
|
||||
log.error("parseObjectFail", e);
|
||||
throwBusinessException(throwException, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static void throwBusinessException(boolean throwException, Exception exception) {
|
||||
if (throwException) {
|
||||
throw SystemExceptionUtils.buildBusinessException(CommonCode.ERROR.getCode(), new Object[]{}, exception);
|
||||
}
|
||||
}
|
||||
|
||||
public static TypeFactory getTypeFactory() {
|
||||
return OBJECT_MAPPER.getTypeFactory();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.face.util;
|
||||
|
||||
|
||||
import com.face.util.spring.SpringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@Slf4j
|
||||
public class MessageUtils {
|
||||
public static String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
|
||||
try {
|
||||
return SpringUtils.getMessageSource().getMessage(code, args, defaultMessage, locale);
|
||||
} catch (Exception e) {
|
||||
log.warn("getMessageFail {} {}", code, args, e);
|
||||
}
|
||||
return defaultMessage;
|
||||
}
|
||||
|
||||
public static String getMessage(String code, @Nullable Object[] args, Locale locale) {
|
||||
try {
|
||||
return SpringUtils.getMessageSource().getMessage(code, args, locale);
|
||||
} catch (Exception e) {
|
||||
log.warn("getMessageFail {} {}", code, args, e);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
public static String getMessageReturnNull(String code, @Nullable Object[] args, Locale locale) {
|
||||
try {
|
||||
return SpringUtils.getMessageSource().getMessage(code, args, locale);
|
||||
} catch (Exception e) {
|
||||
log.warn("getMessageFail {} {}", code, args, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.face.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class NumberUtils {
|
||||
public static String formatYuanAmt(Integer amountFen) {
|
||||
if (amountFen == null) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
DecimalFormat df = new DecimalFormat("0.00");
|
||||
return df.format(BigDecimal.valueOf(amountFen).divide(BigDecimal.valueOf(100)));
|
||||
}
|
||||
|
||||
public static String formatYuanAmt(BigDecimal amountYuan) {
|
||||
if (amountYuan == null) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
DecimalFormat df = new DecimalFormat("0.00");
|
||||
return df.format(amountYuan);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.face.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ObjectUtils {
|
||||
public static boolean equalsNullBlank(Object left, Object right) {
|
||||
if (left == null && right == null) {
|
||||
return true;
|
||||
}
|
||||
if (left == null && right instanceof String) {
|
||||
if (StringUtils.isBlank(right.toString())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (left instanceof String && right == null) {
|
||||
if (StringUtils.isBlank(left.toString())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Objects.equals(left, right);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.face.util;
|
||||
|
||||
|
||||
import com.face.global.language.LanguageStore;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ResponseUtils {
|
||||
public static void writeError(String code, String message, HttpServletResponse response) throws IOException {
|
||||
String errorMessage;
|
||||
if (StringUtils.isNotBlank(message)) {
|
||||
errorMessage = message;
|
||||
} else {
|
||||
errorMessage = MessageUtils.getMessage(code,
|
||||
null, LanguageStore.getLocale());
|
||||
}
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write(JsonUtils.toJsonString(
|
||||
ApiResultBuilder.getRawBuilder().baseInfo(code, errorMessage).build()));
|
||||
response.getWriter().flush();
|
||||
}
|
||||
|
||||
public static void writeString(String message, HttpServletResponse response) throws IOException {
|
||||
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
|
||||
response.getWriter().write(message);
|
||||
response.getWriter().flush();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue