parent
faaeb24007
commit
c4f34073c4
|
@ -0,0 +1,111 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="Spring" name="Spring">
|
||||||
|
<configuration />
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="common-core" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok-maven-plugin:1.18.6.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.sonatype.plexus:plexus-build-api:0.0.7" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.codehaus.plexus:plexus-utils:1.5.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>m2pool-api</artifactId>
|
||||||
|
<groupId>com.m2pool</groupId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>api-system</artifactId>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
api-system系统接口模块
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- m2pool Common Core-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.m2pool</groupId>
|
||||||
|
<artifactId>common-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok-maven-plugin</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.m2pool.system.api;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.common.core.constant.ServiceNameConstants;
|
||||||
|
import com.m2pool.system.api.entity.SysFile;
|
||||||
|
import com.m2pool.system.api.factory.RemoteFileFallbackFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件服务
|
||||||
|
*
|
||||||
|
* @author m2pool
|
||||||
|
*/
|
||||||
|
@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.FILE_SERVICE, fallbackFactory = RemoteFileFallbackFactory.class)
|
||||||
|
public interface RemoteFileService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
*
|
||||||
|
* @param file 文件信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* windMiner上传文件
|
||||||
|
*
|
||||||
|
* @param file 文件信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/windMinerUploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
public R<SysFile> windMinerUploadFile(@RequestPart(value = "file") MultipartFile file);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.m2pool.system.api;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.common.core.constant.SecurityConstants;
|
||||||
|
import com.m2pool.common.core.constant.ServiceNameConstants;
|
||||||
|
import com.m2pool.system.api.entity.SysLogininfor;
|
||||||
|
import com.m2pool.system.api.entity.SysOperLog;
|
||||||
|
import com.m2pool.system.api.factory.RemoteLogFallbackFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 日志服务
|
||||||
|
* @Date 2024/6/11 11:46
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@FeignClient(contextId = "remoteLogService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class)
|
||||||
|
public interface RemoteLogService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存系统日志
|
||||||
|
*
|
||||||
|
* @param sysOperLog 日志实体
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/operlog")
|
||||||
|
public R<Boolean> saveLog(@RequestBody SysOperLog sysOperLog, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存访问记录
|
||||||
|
*
|
||||||
|
* @param sysLogininfor 访问实体
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/logininfor")
|
||||||
|
public R<Boolean> saveLogininfor(@RequestBody SysLogininfor sysLogininfor, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.m2pool.system.api;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.common.core.constant.ServiceNameConstants;
|
||||||
|
import com.m2pool.system.api.entity.EmailEntity;
|
||||||
|
import com.m2pool.system.api.entity.GetEmailCodeEntity;
|
||||||
|
import com.m2pool.system.api.factory.RemoteMailFallbackFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邮件服务
|
||||||
|
*
|
||||||
|
* @author m2pool
|
||||||
|
*/
|
||||||
|
@FeignClient(contextId = "remoteMailService", value = ServiceNameConstants.AUTH_SERVICE, fallbackFactory = RemoteMailFallbackFactory.class)
|
||||||
|
public interface RemoteMailService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 发送提现的邮箱验证码
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/addCreditEmailCode")
|
||||||
|
public R<?> sendAddCreditEmailCode(@RequestBody GetEmailCodeEntity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送文本邮件
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/sendTextMail")
|
||||||
|
public R<?> sendTextMail(@RequestBody EmailEntity entity);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
package com.m2pool.system.api;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.common.core.constant.SecurityConstants;
|
||||||
|
import com.m2pool.common.core.constant.ServiceNameConstants;
|
||||||
|
import com.m2pool.system.api.entity.SysUser;
|
||||||
|
import com.m2pool.system.api.entity.SysUserLeveDate;
|
||||||
|
import com.m2pool.system.api.factory.RemoteUserFallbackFactory;
|
||||||
|
import com.m2pool.system.api.model.LoginUser;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户服务
|
||||||
|
* @Date 2024/6/12 15:46
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@FeignClient(contextId = "remoteUserService",value = ServiceNameConstants.SYSTEM_SERVICE,fallbackFactory = RemoteUserFallbackFactory.class)
|
||||||
|
public interface RemoteUserService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过用户名/邮箱查询用户信息
|
||||||
|
*
|
||||||
|
* @param account 用户名/邮箱
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@GetMapping("/user/info/{account}")
|
||||||
|
public R<LoginUser> getUserInfo(@PathVariable("account") String account, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改用户最后一次登录的ip和登录次数
|
||||||
|
*
|
||||||
|
* @param sysUser 用户信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/user/update")
|
||||||
|
public R<Boolean> updateUserInfo(@RequestBody SysUser sysUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册用户信息
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param sysUser 用户信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/user/register")
|
||||||
|
public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置用户密码
|
||||||
|
*
|
||||||
|
* @param sysUser 用户信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/user/profile/resetPwd")
|
||||||
|
public R<Boolean> resetPwdByEmail(@RequestBody SysUser sysUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看会员有效期情况
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/user/profile/userLevel")
|
||||||
|
public R<SysUserLeveDate> userLevel(@RequestBody Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 升级用户并记录用户会员有效期
|
||||||
|
*
|
||||||
|
* @param user 用户信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/user/profile/Levelup")
|
||||||
|
public R<Boolean> userLevelup(@RequestBody SysUserLeveDate user, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户谷歌验证器验证
|
||||||
|
*
|
||||||
|
* @param code 用户信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/user/profile/checkGoogleCode")
|
||||||
|
public R<Boolean> checkGoogleCode(@RequestBody Long code, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客服列表
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/user/getCSList")
|
||||||
|
public List<SysUser> getCSList();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户登录对象
|
||||||
|
* @Date 2024/6/11 14:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EmailCodeEntity implements Serializable {
|
||||||
|
|
||||||
|
/** 用户名或邮箱 */
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String emailCode;
|
||||||
|
|
||||||
|
private int times;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户登录对象
|
||||||
|
* @Date 2024/6/12 16:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EmailEntity implements Serializable {
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String subject;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户登录对象
|
||||||
|
* @Date 2024/6/12 16:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class GetEmailCodeEntity {
|
||||||
|
|
||||||
|
/** 用户名或邮箱 */
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
@NotNull(message = "用户邮箱不能为空")
|
||||||
|
@Email(message = "邮箱格式错误")
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
//@NotNull(message = "用户密码不能为空")
|
||||||
|
//@Size(min=6, max=15,message="密码长度必须在 5 ~ 15 字符之间!")
|
||||||
|
////@Pattern(regexp="^[a-zA-Z0-9|_]+$",message="密码必须由字母、数字、下划线组成!")
|
||||||
|
//private String password;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.web.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 部门表实体
|
||||||
|
* @Date 2024/6/12 11:19
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysDept extends BaseEntity {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 部门ID */
|
||||||
|
private Long deptId;
|
||||||
|
|
||||||
|
/** 父部门ID */
|
||||||
|
private Long parentId;
|
||||||
|
|
||||||
|
/** 祖级列表 */
|
||||||
|
private String ancestors;
|
||||||
|
|
||||||
|
/** 部门名称 */
|
||||||
|
private String deptName;
|
||||||
|
|
||||||
|
/** 显示顺序 */
|
||||||
|
private Integer orderNum;
|
||||||
|
|
||||||
|
/** 负责人 */
|
||||||
|
private String leader;
|
||||||
|
|
||||||
|
/** 联系电话 */
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/** 部门状态:0正常,1停用 */
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/** 删除标志(0代表存在 2代表删除) */
|
||||||
|
private String delFlag;
|
||||||
|
|
||||||
|
/** 父部门名称 */
|
||||||
|
private String parentName;
|
||||||
|
|
||||||
|
/** 子部门 */
|
||||||
|
private List<SysDept> children = new ArrayList<SysDept>();
|
||||||
|
|
||||||
|
@NotBlank(message = "部门名称不能为空")
|
||||||
|
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
|
||||||
|
public String getDeptName()
|
||||||
|
{
|
||||||
|
return deptName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull(message = "显示顺序不能为空")
|
||||||
|
public Integer getOrderNum()
|
||||||
|
{
|
||||||
|
return orderNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
|
||||||
|
public String getPhone()
|
||||||
|
{
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Email(message = "邮箱格式不正确")
|
||||||
|
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||||
|
public String getEmail()
|
||||||
|
{
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.web.entity.BaseEntity;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件信息
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
public class SysFile extends BaseEntity
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 文件表主键
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件地址
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl()
|
||||||
|
{
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url)
|
||||||
|
{
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("name", getName())
|
||||||
|
.append("id", getId())
|
||||||
|
.append("url", getUrl())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.m2pool.common.core.web.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 系统访问记录表实体类
|
||||||
|
* @Date 2024/6/11 10:40
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysLogininfor extends BaseEntity {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 3217638467115846123L;
|
||||||
|
|
||||||
|
/** ID */
|
||||||
|
private Long infoId;
|
||||||
|
|
||||||
|
/** 用户账号 */
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/** 状态 0成功 1失败 */
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/** 地址 */
|
||||||
|
private String ipaddr;
|
||||||
|
|
||||||
|
/** 描述 */
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
/** 访问时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date accessTime;
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.m2pool.common.core.web.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 操作日志记录表实体类
|
||||||
|
* @Date 2024/6/11 10:43
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysOperLog extends BaseEntity {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 7117642119125846123L;
|
||||||
|
|
||||||
|
/** 日志主键 */
|
||||||
|
private Long operId;
|
||||||
|
|
||||||
|
/** 操作模块 */
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/** 业务类型(0其它 1新增 2修改 3删除) */
|
||||||
|
private Integer businessType;
|
||||||
|
|
||||||
|
/** 业务类型数组 */
|
||||||
|
private Integer[] businessTypes;
|
||||||
|
|
||||||
|
/** 请求方法 */
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
/** 请求方式 */
|
||||||
|
private String requestMethod;
|
||||||
|
|
||||||
|
/** 操作类别(0其它 1后台用户 2手机端用户) */
|
||||||
|
private Integer operatorType;
|
||||||
|
|
||||||
|
/** 操作人员 */
|
||||||
|
private String operName;
|
||||||
|
|
||||||
|
/** 部门名称 */
|
||||||
|
private String deptName;
|
||||||
|
|
||||||
|
/** 请求url */
|
||||||
|
private String operUrl;
|
||||||
|
|
||||||
|
/** 操作地址 */
|
||||||
|
private String operIp;
|
||||||
|
|
||||||
|
/** 请求参数 */
|
||||||
|
private String operParam;
|
||||||
|
|
||||||
|
/** 返回参数 */
|
||||||
|
private String jsonResult;
|
||||||
|
|
||||||
|
/** 操作状态(0正常 1异常) */
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 错误消息 */
|
||||||
|
private String errorMsg;
|
||||||
|
|
||||||
|
/** 操作时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date operTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.web.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 角色表实体
|
||||||
|
* @Date 2024/6/12 11:18
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysRole extends BaseEntity {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 角色ID */
|
||||||
|
private Long roleId;
|
||||||
|
|
||||||
|
/** 角色名称 */
|
||||||
|
private String roleName;
|
||||||
|
|
||||||
|
/** 角色权限 */
|
||||||
|
private String roleKey;
|
||||||
|
|
||||||
|
/** 角色排序 */
|
||||||
|
private String roleSort;
|
||||||
|
|
||||||
|
|
||||||
|
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
|
||||||
|
private String dataScope;
|
||||||
|
|
||||||
|
/** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
|
||||||
|
private boolean menuCheckStrictly;
|
||||||
|
|
||||||
|
/** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */
|
||||||
|
private boolean deptCheckStrictly;
|
||||||
|
|
||||||
|
/** 角色状态(0正常 1停用) */
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/** 删除标志(0代表存在 2代表删除) */
|
||||||
|
private String delFlag;
|
||||||
|
|
||||||
|
/** 用户是否存在此角色标识 默认不存在 */
|
||||||
|
private boolean flag = false;
|
||||||
|
|
||||||
|
/** 菜单组 */
|
||||||
|
private Long[] menuIds;
|
||||||
|
|
||||||
|
/** 部门组(数据权限) */
|
||||||
|
//private Long[] deptIds;
|
||||||
|
|
||||||
|
public boolean isAdmin()
|
||||||
|
{
|
||||||
|
return isAdmin(this.roleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAdmin(Long roleId)
|
||||||
|
{
|
||||||
|
return roleId != null && 1L == roleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotBlank(message = "角色名称不能为空")
|
||||||
|
@Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
|
||||||
|
public String getRoleName()
|
||||||
|
{
|
||||||
|
return roleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotBlank(message = "权限字符不能为空")
|
||||||
|
@Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
|
||||||
|
public String getRoleKey()
|
||||||
|
{
|
||||||
|
return roleKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotBlank(message = "显示顺序不能为空")
|
||||||
|
public String getRoleSort()
|
||||||
|
{
|
||||||
|
return roleSort;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.web.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户实体类
|
||||||
|
* @Date 2024/6/12 10:59
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysUser extends BaseEntity {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 2417642483325474318L;
|
||||||
|
|
||||||
|
/** 用户ID */
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/** 部门ID */
|
||||||
|
private Long deptId;
|
||||||
|
|
||||||
|
/** 用户账号 */
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/** 用户昵称 */
|
||||||
|
private String nickName;
|
||||||
|
|
||||||
|
/** 用户邮箱 */
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/** 手机号码 */
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/** 用户性别 */
|
||||||
|
private String sex;
|
||||||
|
|
||||||
|
/** 用户头像 */
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
/** 密码 */
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/** 帐号状态(0正常 1停用) */
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/** 删除标志(0代表存在 2代表删除) */
|
||||||
|
private String delFlag;
|
||||||
|
|
||||||
|
/** 最后登录IP */
|
||||||
|
private String loginIp;
|
||||||
|
|
||||||
|
/** 登录次数 */
|
||||||
|
private Long loginCount;
|
||||||
|
|
||||||
|
/** 最后登录时间 */
|
||||||
|
private Date loginDate;
|
||||||
|
|
||||||
|
/** 部门对象 */
|
||||||
|
private SysDept dept;
|
||||||
|
|
||||||
|
/** 角色对象 */
|
||||||
|
private List<SysRole> roles;
|
||||||
|
|
||||||
|
/** 角色组 用户角色更新操作使用*/
|
||||||
|
private Long[] roleIds;
|
||||||
|
|
||||||
|
/** 岗位组 */
|
||||||
|
private Long[] postIds;
|
||||||
|
|
||||||
|
/** 角色ID */
|
||||||
|
private Long roleId;
|
||||||
|
|
||||||
|
public boolean isAdmin()
|
||||||
|
{
|
||||||
|
return isAdmin(this.userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAdmin(Long userId)
|
||||||
|
{
|
||||||
|
return userId != null && 1L == userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: xss
|
||||||
|
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
|
||||||
|
public String getNickName()
|
||||||
|
{
|
||||||
|
return nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: xss
|
||||||
|
@NotBlank(message = "用户账号不能为空")
|
||||||
|
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
|
||||||
|
public String getUserName()
|
||||||
|
{
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Email(message = "邮箱格式不正确")
|
||||||
|
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||||
|
public String getEmail()
|
||||||
|
{
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
|
||||||
|
public String getPhone()
|
||||||
|
{
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.m2pool.system.api.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description TODO
|
||||||
|
* @Date 2024/6/11 15:41
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysUserLeveDate {
|
||||||
|
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 用户ID */
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/** 用户账号 */
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/** 会员开始时间 */
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
/** 会员过期时间 */
|
||||||
|
private Date expireTime;
|
||||||
|
|
||||||
|
private int levelType;
|
||||||
|
|
||||||
|
//选择操作 默认0新增 1续费
|
||||||
|
private int oper = 0;
|
||||||
|
|
||||||
|
/** 角色对象 */
|
||||||
|
private Long roleId;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.m2pool.system.api.factory;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.system.api.RemoteFileService;
|
||||||
|
import com.m2pool.system.api.entity.SysFile;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件服务降级处理
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileService>
|
||||||
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(RemoteFileFallbackFactory.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteFileService create(Throwable throwable)
|
||||||
|
{
|
||||||
|
log.error("文件服务调用失败:{}", throwable.getMessage());
|
||||||
|
return new RemoteFileService()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public R<SysFile> upload(MultipartFile file)
|
||||||
|
{
|
||||||
|
return R.fail("远程调用上传文件失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<SysFile> windMinerUploadFile(MultipartFile file) {
|
||||||
|
return R.fail("windMiner远程调用上传文件失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.m2pool.system.api.factory;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.system.api.RemoteLogService;
|
||||||
|
import com.m2pool.system.api.entity.SysLogininfor;
|
||||||
|
import com.m2pool.system.api.entity.SysOperLog;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 日志服务降级处理
|
||||||
|
* @Date 2024/6/11 11:58
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class RemoteLogFallbackFactory implements FallbackFactory<RemoteLogService> {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(RemoteLogFallbackFactory.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteLogService create(Throwable cause) {
|
||||||
|
log.error("日志服务调用失败:{}", cause.getMessage());
|
||||||
|
return new RemoteLogService()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public R<Boolean> saveLog(SysOperLog sysOperLog, String source)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<Boolean> saveLogininfor(SysLogininfor sysLogininfor, String source)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.m2pool.system.api.factory;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.system.api.RemoteMailService;
|
||||||
|
import com.m2pool.system.api.entity.EmailEntity;
|
||||||
|
import com.m2pool.system.api.entity.GetEmailCodeEntity;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件服务降级处理
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class RemoteMailFallbackFactory implements FallbackFactory<RemoteMailService>
|
||||||
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(RemoteMailFallbackFactory.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteMailService create(Throwable cause)
|
||||||
|
{
|
||||||
|
return new RemoteMailService() {
|
||||||
|
@Override
|
||||||
|
public R<?>
|
||||||
|
sendAddCreditEmailCode(GetEmailCodeEntity entity) {
|
||||||
|
return R.fail("提现邮箱验证发送失败:" + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> sendTextMail(@RequestBody EmailEntity entity){
|
||||||
|
return R.fail("邮箱发送失败:" + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.m2pool.system.api.factory;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.system.api.RemoteUserService;
|
||||||
|
import com.m2pool.system.api.entity.SysUser;
|
||||||
|
import com.m2pool.system.api.entity.SysUserLeveDate;
|
||||||
|
import com.m2pool.system.api.model.LoginUser;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户服务降级处理
|
||||||
|
* @Date 2024/6/11 15:48
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserService> {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class);
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteUserService create(Throwable cause) {
|
||||||
|
log.error("用户服务调用失败:{}",cause.getMessage());
|
||||||
|
|
||||||
|
return new RemoteUserService(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<LoginUser> getUserInfo(String username, String source) {
|
||||||
|
return R.fail("获取用户失败:" + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<Boolean> updateUserInfo(SysUser sysUser) {
|
||||||
|
return R.fail("修改用户失败:" + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<Boolean> registerUserInfo(SysUser sysUser) {
|
||||||
|
return R.fail("注册用户失败:" + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<Boolean> resetPwdByEmail(SysUser sysUser) {
|
||||||
|
return R.fail("重置用户密码失败:" + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<SysUserLeveDate> userLevel(Long userId) {
|
||||||
|
return R.fail("获取用户会员信息失败:" + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<Boolean> userLevelup(SysUserLeveDate user, String source) {
|
||||||
|
return R.fail("用户升级失败:" + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<Boolean> checkGoogleCode(Long code, String source) {
|
||||||
|
return R.fail("谷歌验证器校验失败:" + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.m2pool.system.api.model;
|
||||||
|
|
||||||
|
import com.m2pool.system.api.entity.SysUser;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 登陆的用户信息
|
||||||
|
* @Date 2024/6/12 15:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class LoginUser implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 用户唯一标识 */
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
/** 用户名id */
|
||||||
|
private Long userid;
|
||||||
|
|
||||||
|
/** 用户名 */
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
/** 登录时间 */
|
||||||
|
private Long loginTime;
|
||||||
|
|
||||||
|
/** 过期时间 */
|
||||||
|
private Long expireTime;
|
||||||
|
|
||||||
|
/** 登录IP地址 */
|
||||||
|
private String ipaddr;
|
||||||
|
|
||||||
|
/** 权限列表 */
|
||||||
|
private Set<String> permissions;
|
||||||
|
|
||||||
|
/** 角色列表 */
|
||||||
|
private Set<String> roles;
|
||||||
|
|
||||||
|
/** 用户信息 */
|
||||||
|
private SysUser sysUser;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.m2pool.system.api.model;
|
||||||
|
|
||||||
|
import com.m2pool.system.api.entity.SysUser;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 登陆的用户信息
|
||||||
|
* @Date 2024/6/12 15:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OpenApiKeyInfo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 用户唯一标识 */
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
/** 用户邮箱 */
|
||||||
|
private String user;
|
||||||
|
|
||||||
|
/** 登录时间 */
|
||||||
|
private Long loginTime;
|
||||||
|
|
||||||
|
/** 过期时间 */
|
||||||
|
private Long expireTime;
|
||||||
|
|
||||||
|
/** apiKey绑定的ip */
|
||||||
|
private String apiIp;
|
||||||
|
|
||||||
|
/** 登录IP地址 */
|
||||||
|
private String ipaddr;
|
||||||
|
|
||||||
|
private Set<String> permissions;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||||
|
com.m2pool.system.api.factory.RemoteUserFallbackFactory,\
|
||||||
|
com.m2pool.system.api.factory.RemoteFileFallbackFactory,\
|
||||||
|
com.m2pool.system.api.factory.RemoteMailFallbackFactory,\
|
||||||
|
com.m2pool.system.api.factory.RemoteLogFallbackFactory
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>m2pool</artifactId>
|
||||||
|
<groupId>com.m2pool</groupId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>m2pool-api</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<modules>
|
||||||
|
<module>api-system</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
m2pool-api系统接口
|
||||||
|
</description>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,178 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="Spring" name="Spring">
|
||||||
|
<configuration />
|
||||||
|
</facet>
|
||||||
|
<facet type="web" name="Web">
|
||||||
|
<configuration>
|
||||||
|
<webroots />
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2021.0.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-commons:2021.0.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-client:2.0.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpasyncclient:4.1.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.15" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore-nio:4.4.15" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.guava:guava:20.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.prometheus:simpleclient:0.12.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.prometheus:simpleclient_tracer_otel:0.12.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.prometheus:simpleclient_tracer_common:0.12.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.prometheus:simpleclient_tracer_otel_agent:0.12.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.spring:spring-context-support:1.0.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2021.0.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.62" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.62" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel:2021.0.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-transport-simple-http:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-transport-common:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-datasource-extension:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-annotation-aspectj:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-core:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-circuitbreaker-sentinel:2021.0.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-reactor-adapter:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-spring-webflux-adapter:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-spring-webmvc-adapter:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-parameter-flow-control:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-server-default:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-common-default:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.76.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.76.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.76.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.76.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.76.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.76.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-client-default:1.8.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-sentinel-datasource:2021.0.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-actuator:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator-autoconfigure:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.micrometer:micrometer-core:1.8.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.hdrhistogram:HdrHistogram:2.1.12" level="project" />
|
||||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: org.latencyutils:LatencyUtils:2.0.3" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok-maven-plugin:1.18.6.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.sonatype.plexus:plexus-build-api:0.0.7" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.codehaus.plexus:plexus-utils:1.5.8" level="project" />
|
||||||
|
<orderEntry type="module" module-name="common-security" />
|
||||||
|
<orderEntry type="module" module-name="api-system" />
|
||||||
|
<orderEntry type="module" module-name="common-core" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
|
||||||
|
<orderEntry type="module" module-name="common-redis" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.6.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.6.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.6.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.1.8.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>m2pool</artifactId>
|
||||||
|
<groupId>com.m2pool</groupId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>m2pool-auth</artifactId>
|
||||||
|
|
||||||
|
<description>认证模块:登录认证、权限鉴定等</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Nacos -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Nacos Config -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringBoot Web -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Sentinel -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- SpringBoot Actuator -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok-maven-plugin</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JXY Common Security-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.m2pool</groupId>
|
||||||
|
<artifactId>common-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.m2pool.auth;
|
||||||
|
|
||||||
|
import com.m2pool.common.security.annotation.EnableM2PoolFeignClients;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
|
||||||
|
@EnableM2PoolFeignClients
|
||||||
|
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||||
|
public class M2PoolAuthApplication{
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
SpringApplication.run(M2PoolAuthApplication.class,args);
|
||||||
|
|
||||||
|
System.out.println("认证授权中心启动成功");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
package com.m2pool.auth.controller;
|
||||||
|
|
||||||
|
import com.m2pool.auth.entity.*;
|
||||||
|
import com.m2pool.auth.service.SysLoginService;
|
||||||
|
import com.m2pool.auth.service.impl.MaliServiceImpl;
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.common.core.utils.JwtUtils;
|
||||||
|
import com.m2pool.common.core.utils.StringUtils;
|
||||||
|
import com.m2pool.common.core.web.Result.AjaxResult;
|
||||||
|
import com.m2pool.common.security.annotation.RequiresLogin;
|
||||||
|
import com.m2pool.common.security.auth.AuthUtil;
|
||||||
|
import com.m2pool.common.security.service.TokenService;
|
||||||
|
import com.m2pool.common.security.utils.SecurityUtils;
|
||||||
|
import com.m2pool.system.api.entity.SysUser;
|
||||||
|
import com.m2pool.system.api.model.LoginUser;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description token 控制
|
||||||
|
* @Date 2024/6/12 14:59
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@Api(tags = "token令牌")
|
||||||
|
public class TokenController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysLoginService sysLoginService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MaliServiceImpl maliService;
|
||||||
|
|
||||||
|
@PostMapping("login")
|
||||||
|
public R<?> login(@RequestBody @Valid LoginBody loginBody,@RequestHeader("User-Agent") String userAgent)
|
||||||
|
{
|
||||||
|
return sysLoginService.login(loginBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("registerCode")
|
||||||
|
public R<?> emailCode(@Validated @RequestBody GetEmailCodeEntity entity)
|
||||||
|
{
|
||||||
|
return maliService.emailCode(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("loginCode")
|
||||||
|
public R<?> loginCode(@Valid @RequestBody GetLoginEmailCodeEntity entity)
|
||||||
|
{
|
||||||
|
return maliService.loginCode(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("addCreditEmailCode")
|
||||||
|
public R<?> addCreditEmailCode(@RequestBody GetEmailCodeEntity entity)
|
||||||
|
{
|
||||||
|
return maliService.AddCreditCode(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("resetPwdCode")
|
||||||
|
public R<?> resetPwdCode(@Valid @RequestBody GetEmailCodeEntity entity)
|
||||||
|
{
|
||||||
|
return maliService.resetPwdCode(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("updatePwdCode")
|
||||||
|
public R<?> updatePwdCode()
|
||||||
|
{
|
||||||
|
return maliService.updatePwdCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("hello")
|
||||||
|
public R<?> hello()
|
||||||
|
{
|
||||||
|
return R.success("浏览器安全认证已确认,请重新返回原页面进行登陆");
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("logout")
|
||||||
|
public R<?> logout(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
String token = SecurityUtils.getToken(request);
|
||||||
|
if (StringUtils.isNotEmpty(token))
|
||||||
|
{
|
||||||
|
String username = JwtUtils.getUserName(token);
|
||||||
|
//删除用户缓存记录
|
||||||
|
AuthUtil.logoutByToken(token);
|
||||||
|
// 记录用户退出日志
|
||||||
|
sysLoginService.logout(username);
|
||||||
|
}
|
||||||
|
return R.success("用户登出");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("refresh")
|
||||||
|
public R<?> refresh(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
LoginUser loginUser = tokenService.getLoginUser(request);
|
||||||
|
if (StringUtils.isNotNull(loginUser)){
|
||||||
|
//刷新令牌有效期
|
||||||
|
tokenService.refreshToken(loginUser);
|
||||||
|
return R.success();
|
||||||
|
}
|
||||||
|
return R.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("register")
|
||||||
|
public R<?> register(@Valid() @RequestBody RegisterBody registerBody)
|
||||||
|
{
|
||||||
|
// 用户注册
|
||||||
|
sysLoginService.register(registerBody);
|
||||||
|
return R.success("用户"+registerBody.getEmail()+"注册成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("resetPwd")
|
||||||
|
public R<?> resetPwd(@Valid @RequestBody ResetPwdBody resetPwdBody)
|
||||||
|
{
|
||||||
|
// 重置密码
|
||||||
|
sysLoginService.resetPwd(resetPwdBody);
|
||||||
|
return R.success("账号"+ resetPwdBody.getEmail()+"密码重置成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("updatePwd")
|
||||||
|
@RequiresLogin
|
||||||
|
public R<?> updatePwd(@Valid @RequestBody ResetPwdBody resetPwdBody)
|
||||||
|
{
|
||||||
|
String email = SecurityUtils.getUsername();
|
||||||
|
resetPwdBody.setEmail(email);
|
||||||
|
|
||||||
|
// 修改密码
|
||||||
|
sysLoginService.resetPwd(resetPwdBody);
|
||||||
|
return R.success("账号"+ resetPwdBody.getEmail()+"密码修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("sendTextMail")
|
||||||
|
public R<?> sendTextMail(@Valid @RequestBody EmailEntity entity)
|
||||||
|
{
|
||||||
|
maliService.sendTextMailMessage(entity.getEmail(), entity.getSubject(),entity.getText());
|
||||||
|
return R.success("邮件已发送");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.m2pool.auth.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户登录对象
|
||||||
|
* @Date 2024/6/12 16:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EmailCodeEntity implements Serializable {
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String emailCode;
|
||||||
|
|
||||||
|
private int times;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.m2pool.auth.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户登录对象
|
||||||
|
* @Date 2022/5/12 16:13
|
||||||
|
* @Author 杜懿
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EmailEntity implements Serializable {
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
@Email
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String subject;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.m2pool.auth.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户登录对象
|
||||||
|
* @Date 2024/6/12 16:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class GetEmailCodeEntity {
|
||||||
|
|
||||||
|
/** 用户名或邮箱 */
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
@NotNull(message = "用户邮箱不能为空")
|
||||||
|
@Email(message = "邮箱格式错误")
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
//@NotNull(message = "用户密码不能为空")
|
||||||
|
//@Size(min=6, max=15,message="密码长度必须在 5 ~ 15 字符之间!")
|
||||||
|
////@Pattern(regexp="^[a-zA-Z0-9|_]+$",message="密码必须由字母、数字、下划线组成!")
|
||||||
|
//private String password;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.m2pool.auth.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户登录对象
|
||||||
|
* @Date 2024/6/12 16:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class GetLoginEmailCodeEntity {
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
@NotNull(message = "用户邮箱不能为空")
|
||||||
|
@Email(message = "邮箱格式错误")
|
||||||
|
private String account;
|
||||||
|
|
||||||
|
//@NotNull(message = "用户密码不能为空")
|
||||||
|
//@Size(min=6, max=15,message="密码长度必须在 5 ~ 15 字符之间!")
|
||||||
|
////@Pattern(regexp="^[a-zA-Z0-9|_]+$",message="密码必须由字母、数字、下划线组成!")
|
||||||
|
//private String password;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.m2pool.auth.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户登录对象
|
||||||
|
* @Date 2024/6/12 16:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class LoginBody {
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
@Email
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/** 密码 */
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
private String uuid;
|
||||||
|
|
||||||
|
//private boolean flag = false;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.m2pool.auth.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.Pattern;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户注册对象
|
||||||
|
* @Date 2024/6/12 16:16
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RegisterBody{
|
||||||
|
|
||||||
|
//todo 添加注册详细信息
|
||||||
|
/** 手机号码 */
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
@Email(message = "邮箱格式错误")
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String emailCode;
|
||||||
|
|
||||||
|
/** 密码 */
|
||||||
|
@NotNull(message = "密码不能为空")
|
||||||
|
//@Size(min=8, max=32,message="密码长度必须在 8 ~ 32 字符之间!")
|
||||||
|
//@Pattern(regexp="^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_]+$)(?![a-z0-9]+$)(?![a-z\\W_]+$)(?![0-9\\W_]+$)[a-zA-Z0-9\\W_]{8,32}$",message="密码格式错误,密码应包含大写字母、小写字母、数字以及特殊字符,8到32位")
|
||||||
|
private String password;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.m2pool.auth.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户重置密码对象
|
||||||
|
* @Date 2024/6/12 16:16
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ResetPwdBody {
|
||||||
|
|
||||||
|
//todo 添加详细信息
|
||||||
|
|
||||||
|
@Email
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String resetPwdCode;
|
||||||
|
|
||||||
|
/** 新密码 */
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 谷歌验证器验证码
|
||||||
|
*/
|
||||||
|
public long gCode;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.m2pool.auth.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户修改密码对象
|
||||||
|
* @Date 2024/6/12 16:16
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class UpdatePwdBody {
|
||||||
|
|
||||||
|
private String updatePwdCode;
|
||||||
|
|
||||||
|
/** 新密码 */
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.m2pool.auth.service;
|
||||||
|
|
||||||
|
import com.m2pool.auth.entity.GetEmailCodeEntity;
|
||||||
|
import com.m2pool.auth.entity.GetLoginEmailCodeEntity;
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description TODO
|
||||||
|
* @Date 2024/6/11 14:56
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public interface MailService {
|
||||||
|
/**
|
||||||
|
* 发送纯文本邮件
|
||||||
|
* @param to
|
||||||
|
* @param subject
|
||||||
|
* @param text
|
||||||
|
*/
|
||||||
|
public void sendTextMailMessage(String to,String subject,String text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送html邮件
|
||||||
|
* @param to
|
||||||
|
* @param subject
|
||||||
|
* @param content
|
||||||
|
*/
|
||||||
|
public void sendHtmlMailMessage(String to,String subject,String content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送带附件的邮件
|
||||||
|
* @param to 邮件收信人
|
||||||
|
* @param subject 邮件主题
|
||||||
|
* @param content 邮件内容
|
||||||
|
* @param filePath 附件路径
|
||||||
|
*/
|
||||||
|
public void sendAttachmentMailMessage(String to,String subject,String content,String filePath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送注册邮箱验证码
|
||||||
|
* @param to
|
||||||
|
* @param code
|
||||||
|
*/
|
||||||
|
public void sendCodeMailMessage(String to, String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送登录邮箱验证码
|
||||||
|
* @param to
|
||||||
|
* @param code
|
||||||
|
*/
|
||||||
|
public void sendLoginCodeMailMessage(String to, String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送重置密码邮箱验证码
|
||||||
|
* @param to
|
||||||
|
* @param code
|
||||||
|
*/
|
||||||
|
public void sendResetPwdMailMessage(String to, String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送修改密码邮箱验证码
|
||||||
|
* @param to
|
||||||
|
* @param code
|
||||||
|
*/
|
||||||
|
public void sendUpdatePwdMailMessage(String to, String code);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public R<?> emailCode(GetEmailCodeEntity entity);
|
||||||
|
|
||||||
|
public R<?> loginCode(GetLoginEmailCodeEntity entity);
|
||||||
|
|
||||||
|
public R<?> AddCreditCode(GetEmailCodeEntity entity);
|
||||||
|
|
||||||
|
public R<?> resetPwdCode(GetEmailCodeEntity entity);
|
||||||
|
|
||||||
|
public R<?> updatePwdCode();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,453 @@
|
||||||
|
package com.m2pool.auth.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
|
||||||
|
import com.m2pool.auth.entity.*;
|
||||||
|
import com.m2pool.common.core.RedisTransKey;
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.common.core.constant.Constants;
|
||||||
|
import com.m2pool.common.core.constant.SecurityConstants;
|
||||||
|
import com.m2pool.common.core.constant.UserConstants;
|
||||||
|
import com.m2pool.common.core.enums.UserStatus;
|
||||||
|
import com.m2pool.common.core.exception.ServiceException;
|
||||||
|
import com.m2pool.common.core.text.Convert;
|
||||||
|
import com.m2pool.common.core.utils.DateUtils;
|
||||||
|
import com.m2pool.common.core.utils.ServletUtils;
|
||||||
|
import com.m2pool.common.core.utils.StringUtils;
|
||||||
|
import com.m2pool.common.core.utils.ip.IpUtils;
|
||||||
|
import com.m2pool.common.core.utils.sign.RsaUtils;
|
||||||
|
import com.m2pool.common.core.web.Result.AjaxResult;
|
||||||
|
import com.m2pool.common.redis.service.RedisService;
|
||||||
|
import com.m2pool.common.security.service.TokenService;
|
||||||
|
import com.m2pool.common.security.utils.SecurityUtils;
|
||||||
|
import com.m2pool.system.api.RemoteLogService;
|
||||||
|
import com.m2pool.system.api.RemoteUserService;
|
||||||
|
import com.m2pool.system.api.entity.SysLogininfor;
|
||||||
|
import com.m2pool.system.api.entity.SysUser;
|
||||||
|
import com.m2pool.system.api.model.LoginUser;
|
||||||
|
import org.apache.ibatis.annotations.Update;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 登录校验方法
|
||||||
|
* @Date 2024/6/12 16:19
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SysLoginService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RemoteLogService remoteLogService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RemoteUserService remoteUserService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
|
//public static String PWD_REGEX="^(?![A-Za-z0-9]+$)(?![a-z0-9\\W]+$)(?![A-Za-z\\W]+$)(?![A-Z0-9\\W]+$)[a-zA-Z0-9\\W]{8,32}$";
|
||||||
|
public static String PWD_REGEX="^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[!@#$%^&*()./_])[A-Za-z\\d!@#$%^&*()./_]{8,32}$";
|
||||||
|
|
||||||
|
public static String EMAIL_REGEX="^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
*/
|
||||||
|
public R<?> login(LoginBody loginBody)
|
||||||
|
{
|
||||||
|
//邮箱
|
||||||
|
String email = loginBody.getUserName();
|
||||||
|
|
||||||
|
//String password= loginBody.getPassword();
|
||||||
|
String password="";
|
||||||
|
|
||||||
|
try {
|
||||||
|
password = RsaUtils.decryptByPrivateKey(loginBody.getPassword());
|
||||||
|
password = StringUtils.clean(password);
|
||||||
|
}catch (Exception e){
|
||||||
|
return R.fail(401,"加密密码传参有误");
|
||||||
|
}
|
||||||
|
|
||||||
|
String emailCode = loginBody.getCode();
|
||||||
|
// 用户名或密码为空 错误
|
||||||
|
if (StringUtils.isAnyBlank(email, password))
|
||||||
|
{
|
||||||
|
recordLogininfor(email, Constants.LOGIN_FAIL, "邮箱/密码必须填写");
|
||||||
|
throw new ServiceException("邮箱/密码必须填写");
|
||||||
|
}
|
||||||
|
if(!StringUtils.isBlank(email)){
|
||||||
|
if(!email.matches(EMAIL_REGEX)){
|
||||||
|
throw new ServiceException("邮箱格式错误");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("邮箱为必填项");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 密码如果不在指定范围内 错误
|
||||||
|
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|
||||||
|
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
recordLogininfor(email, Constants.LOGIN_FAIL, "用户密码不在指定范围");
|
||||||
|
throw new ServiceException("用户密码不在指定范围");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//if(!"admin".equals(username)){
|
||||||
|
// if(!password.matches(PWD_REGEX)){
|
||||||
|
// recordLogininfor(username, Constants.LOGIN_FAIL, "密码格式错误");
|
||||||
|
// throw new ServiceException("密码格式错误,密码应包含大写字母、小写字母、数字以及特殊字符,8到32位");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//todo 可以添加校验验证码的功能
|
||||||
|
if("1328642438@qq.com".equals(email)){
|
||||||
|
//不做处理 进入后续登录流程
|
||||||
|
}else if(redisService.hasKey(RedisTransKey.getLoginKey(email))){
|
||||||
|
|
||||||
|
Object o = redisService.getCacheObject(RedisTransKey.getLoginKey(email));//user:emailCode:email
|
||||||
|
|
||||||
|
|
||||||
|
EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
|
||||||
|
//验证验证码
|
||||||
|
if(emailCode.equals(emailCodeEntity.getEmailCode())){
|
||||||
|
//不做处理 进入后续登录流程
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("验证码错误");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("验证码未获取或已过期,请重新获取验证码");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户信息
|
||||||
|
R<LoginUser> userResult = remoteUserService.getUserInfo(email, SecurityConstants.INNER);
|
||||||
|
|
||||||
|
if (R.FAIL == userResult.getCode())
|
||||||
|
{
|
||||||
|
throw new ServiceException(userResult.getMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
|
||||||
|
{
|
||||||
|
recordLogininfor(email, Constants.LOGIN_FAIL, "登录用户不存在");
|
||||||
|
throw new ServiceException("登录用户:" + email + " 不存在");
|
||||||
|
}
|
||||||
|
LoginUser userInfo = userResult.getData();
|
||||||
|
//Long userid = userInfo.getUserid();
|
||||||
|
SysUser user = userResult.getData().getSysUser();
|
||||||
|
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
||||||
|
{
|
||||||
|
recordLogininfor(email, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
|
||||||
|
throw new ServiceException("对不起,您的账号:" + email + " 已被删除");
|
||||||
|
}
|
||||||
|
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
||||||
|
{
|
||||||
|
recordLogininfor(email, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
|
||||||
|
throw new ServiceException("对不起,您的账号:" + email + " 已停用");
|
||||||
|
}
|
||||||
|
//根据user:userId:lock
|
||||||
|
if(redisService.hasKey("user:"+email+":lock")){
|
||||||
|
//账户输入密码错误
|
||||||
|
throw new ServiceException("该账户因密码错误多次被暂时限制登陆24h!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SecurityUtils.matchesPassword(password, user.getPassword()))
|
||||||
|
{
|
||||||
|
recordLogininfor(email, Constants.LOGIN_FAIL, "用户密码错误");
|
||||||
|
//redis 记录用户密码错误次数 大于5时锁定账户24小时
|
||||||
|
int count = 0;
|
||||||
|
if(redisService.hasKey("user:"+email+":pwdError")){
|
||||||
|
//判断key是否过期
|
||||||
|
long expire = redisService.getExpire("user:" + email + ":pwdError", TimeUnit.SECONDS);
|
||||||
|
if(expire > 0){
|
||||||
|
count = Convert.toInt(redisService.getCacheObject("user:"+email+":pwdError"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
if(count == 1){
|
||||||
|
redisService.setCacheObject("user:"+email+":pwdError",count,1L,TimeUnit.HOURS);
|
||||||
|
}else if(count < 6){
|
||||||
|
long expire = redisService.getExpire("user:" + email + ":pwdError", TimeUnit.SECONDS);
|
||||||
|
System.out.println(expire);
|
||||||
|
redisService.setCacheObject("user:"+email+":pwdError",count,redisService.getExpire("user:"+email+":pwdError",TimeUnit.SECONDS),TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
if(count >= 5){
|
||||||
|
//锁定用户账号 并清除输入错误次数的记录
|
||||||
|
redisService.setCacheObject("user:"+email+":lock", email, 24L, TimeUnit.HOURS);
|
||||||
|
//清除输入错误次数的记录
|
||||||
|
redisService.deleteObject("user:"+email+":pwdError");
|
||||||
|
}
|
||||||
|
throw new ServiceException("密码错误,一小时内错误五次之后锁定账户24h,当前已失败"+count+"次");
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo 判断当前ip和用户上一次登陆ip是否一致
|
||||||
|
//if(StringUtils.isNotNull(userResult.getData().getSysUser().getLoginIp()) && StringUtils.isNotBlank(userResult.getData().getSysUser().getLoginIp())){
|
||||||
|
// //上一次ip不为空 判断
|
||||||
|
// if(StringUtils.isBlank(loginBody.getUuid()) || StringUtils.isNull(loginBody.getUuid())){
|
||||||
|
//
|
||||||
|
// //没传uuid说明是刚发起的登录请求 需要判断ip是否发生变化
|
||||||
|
// String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest());
|
||||||
|
// if(!ipAddr.equals(userResult.getData().getSysUser().getLoginIp())){
|
||||||
|
// return R.fail(201,"登录ip发生变化,请通过验证再登录");
|
||||||
|
// }
|
||||||
|
// }else {
|
||||||
|
// //传了uuid说明是验证登录 验证
|
||||||
|
// if (StringUtils.isBlank(loginBody.getCode()))
|
||||||
|
// {
|
||||||
|
// return R.fail("验证码不能为空");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// String verifyKey = Constants.CAPTCHA_CODE_KEY + loginBody.getUuid();
|
||||||
|
// String captcha = redisService.getCacheObject(verifyKey);
|
||||||
|
//
|
||||||
|
// if(StringUtils.isNull(captcha)){
|
||||||
|
// return R.fail("验证码已失效");
|
||||||
|
// }
|
||||||
|
// //redisService.deleteObject(verifyKey);
|
||||||
|
//
|
||||||
|
// if (!loginBody.getCode().equalsIgnoreCase(captcha))
|
||||||
|
// {
|
||||||
|
// return R.fail("验证码错误");
|
||||||
|
// }
|
||||||
|
// redisService.deleteObject(verifyKey);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
recordLogininfor(email, Constants.LOGIN_SUCCESS, "登录成功");
|
||||||
|
|
||||||
|
//修改数据库中的用户登录次数和最后一次登录的ip
|
||||||
|
user.setLoginCount(user.getLoginCount()+1);
|
||||||
|
user.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
|
||||||
|
user.setLoginDate(DateUtils.getNowDate());
|
||||||
|
|
||||||
|
//todo 单独存储用户的登录时间和ip
|
||||||
|
remoteUserService.updateUserInfo(user);
|
||||||
|
|
||||||
|
return R.success(tokenService.createToken(userInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logout(String loginName)
|
||||||
|
{
|
||||||
|
recordLogininfor(loginName, Constants.LOGOUT, "退出成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册
|
||||||
|
*/
|
||||||
|
public void register(RegisterBody registerBody)
|
||||||
|
{
|
||||||
|
String password = registerBody.getPassword();
|
||||||
|
try {
|
||||||
|
password = RsaUtils.decryptByPrivateKey(registerBody.getPassword());
|
||||||
|
password = StringUtils.clean(password);
|
||||||
|
}catch (Exception e){
|
||||||
|
throw new ServiceException("加密密码传参有误",401);
|
||||||
|
}
|
||||||
|
|
||||||
|
String email = registerBody.getEmail();
|
||||||
|
|
||||||
|
|
||||||
|
String phone = registerBody.getPhone();
|
||||||
|
String emailCode = registerBody.getEmailCode();
|
||||||
|
//String key = username+"+"+email;
|
||||||
|
// 用户名或密码为空 错误
|
||||||
|
if (StringUtils.isAnyBlank(email, password))
|
||||||
|
{
|
||||||
|
throw new ServiceException("邮箱/密码必须填写");
|
||||||
|
}
|
||||||
|
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|
||||||
|
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
throw new ServiceException("密码长度必须在8到32个字符之间");
|
||||||
|
}
|
||||||
|
if(!password.matches(PWD_REGEX)){
|
||||||
|
throw new ServiceException("密码格式错误,密码应包含大写字母、小写字母、数字以及特殊字符,8到32位");
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo 手机号验证
|
||||||
|
if(!StringUtils.isEmpty(phone)){
|
||||||
|
String phoneRex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$";
|
||||||
|
|
||||||
|
if (!phone.matches(phoneRex))
|
||||||
|
{
|
||||||
|
throw new ServiceException("手机号格式不正确");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!StringUtils.isBlank(email)){
|
||||||
|
if(!email.matches(EMAIL_REGEX)){
|
||||||
|
throw new ServiceException("邮箱格式错误");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("邮箱为必填项");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(redisService.hasKey(RedisTransKey.getEmailKey(email))){
|
||||||
|
|
||||||
|
Object o = redisService.getCacheObject(RedisTransKey.getEmailKey(email));//user:emailCode:email
|
||||||
|
|
||||||
|
EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
|
||||||
|
|
||||||
|
//验证验证码
|
||||||
|
if(emailCode.equals(emailCodeEntity.getEmailCode())){
|
||||||
|
// 注册用户信息
|
||||||
|
SysUser sysUser = new SysUser();
|
||||||
|
sysUser.setUserName(email);
|
||||||
|
sysUser.setNickName(email);
|
||||||
|
sysUser.setPhone(phone);
|
||||||
|
sysUser.setEmail(email);
|
||||||
|
sysUser.setPassword(SecurityUtils.encryptPassword(password));
|
||||||
|
R<?> registerResult = remoteUserService.registerUserInfo(sysUser);
|
||||||
|
|
||||||
|
if (R.FAIL == registerResult.getCode())
|
||||||
|
{
|
||||||
|
throw new ServiceException(registerResult.getMsg());
|
||||||
|
}
|
||||||
|
recordLogininfor(email, Constants.REGISTER, "注册成功");
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("验证码错误");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("验证码未获取或已过期,请重新获取验证码");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置密码
|
||||||
|
*/
|
||||||
|
public void resetPwd(ResetPwdBody resetPwdBody)
|
||||||
|
{
|
||||||
|
|
||||||
|
String password = resetPwdBody.getPassword();
|
||||||
|
try {
|
||||||
|
password = RsaUtils.decryptByPrivateKey(resetPwdBody.getPassword());
|
||||||
|
}catch (Exception e){
|
||||||
|
throw new ServiceException("加密密码传参有误",401);
|
||||||
|
//password = resetPwdBody.getPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
String email = resetPwdBody.getEmail();
|
||||||
|
String resetPwdCode = resetPwdBody.getResetPwdCode();
|
||||||
|
// 邮箱或密码为空 错误
|
||||||
|
if (StringUtils.isAnyBlank(email, password))
|
||||||
|
{
|
||||||
|
throw new ServiceException("邮箱/新密码不能为空");
|
||||||
|
}
|
||||||
|
if(!StringUtils.isBlank(email)){
|
||||||
|
if(!email.matches(EMAIL_REGEX)){
|
||||||
|
throw new ServiceException("邮箱格式错误");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("邮箱为必填项");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|
||||||
|
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
throw new ServiceException("密码长度必须在8到32个字符之间");
|
||||||
|
}
|
||||||
|
//password格式校验
|
||||||
|
if(!password.matches(PWD_REGEX)){
|
||||||
|
throw new ServiceException("密码格式错误,密码应包含大写字母、小写字母、数字以及特殊字符,8到32位");
|
||||||
|
}
|
||||||
|
R<LoginUser> userResult = remoteUserService.getUserInfo(email, SecurityConstants.INNER);
|
||||||
|
|
||||||
|
if (R.FAIL == userResult.getCode())
|
||||||
|
{
|
||||||
|
throw new ServiceException("服务器请求失败请稍后再试");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SecurityUtils.matchesPassword(password,userResult.getData().getSysUser().getPassword())){
|
||||||
|
throw new ServiceException("新密码不能与原密码一致");
|
||||||
|
}
|
||||||
|
|
||||||
|
//if(resetPwdBody.getGCode() == 0){
|
||||||
|
// throw new ServiceException("验证码不能为空");
|
||||||
|
//}
|
||||||
|
//谷歌验证码校验
|
||||||
|
//R<?> checkCodeResult = remoteUserService.checkGoogleCode(resetPwdBody.getGCode(),SecurityConstants.INNER);
|
||||||
|
//
|
||||||
|
//if (R.FAIL == checkCodeResult.getCode())
|
||||||
|
//{
|
||||||
|
// System.out.println(checkCodeResult);
|
||||||
|
// throw new ServiceException(checkCodeResult.getMsg());
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//System.out.println(checkCodeResult);
|
||||||
|
|
||||||
|
if(redisService.hasKey(RedisTransKey.getResetPwdKey(email))){
|
||||||
|
|
||||||
|
Object o = redisService.getCacheObject(RedisTransKey.getResetPwdKey(email));//user:emailCode:username
|
||||||
|
|
||||||
|
EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
|
||||||
|
if (email.equals(emailCodeEntity.getEmail())) {
|
||||||
|
//邮箱必须和刚刚传的一致
|
||||||
|
//验证验证码
|
||||||
|
if(resetPwdCode.equals(emailCodeEntity.getEmailCode())){
|
||||||
|
// 重置用户密码
|
||||||
|
SysUser sysUser = new SysUser();
|
||||||
|
sysUser.setEmail(email);
|
||||||
|
sysUser.setPassword(SecurityUtils.encryptPassword(password));
|
||||||
|
|
||||||
|
R<?> resetPwdResult = remoteUserService.resetPwdByEmail(sysUser);
|
||||||
|
|
||||||
|
if (R.FAIL == resetPwdResult.getCode())
|
||||||
|
{
|
||||||
|
throw new ServiceException(resetPwdResult.getMsg());
|
||||||
|
}
|
||||||
|
//recordLogininfor(username, Constants.REGISTER, "注册成功");
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("邮箱验证码错误");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
throw new ServiceException("请勿修改已输入的邮箱");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
////判断是邮箱不存在还是操作超时
|
||||||
|
////通过邮箱获取用户
|
||||||
|
//R<LoginUser> userByEmail = remoteUserService.getUserInfo(email, SecurityConstants.INNER);
|
||||||
|
//
|
||||||
|
//if(StringUtils.isNull(userByEmail.getData())){
|
||||||
|
// throw new ServiceException("邮箱"+email+"未被注册,请检查邮箱是否正确");
|
||||||
|
//}
|
||||||
|
throw new ServiceException("验证码校验失败:操作超时,请重新操作");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录登录信息
|
||||||
|
*
|
||||||
|
* @param username 用户名
|
||||||
|
* @param status 状态
|
||||||
|
* @param message 消息内容
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void recordLogininfor(String username, String status, String message)
|
||||||
|
{
|
||||||
|
SysLogininfor logininfor = new SysLogininfor();
|
||||||
|
logininfor.setUserName(username);
|
||||||
|
logininfor.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
|
||||||
|
logininfor.setMsg(message);
|
||||||
|
// 日志状态
|
||||||
|
if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
|
||||||
|
{
|
||||||
|
logininfor.setStatus(Constants.LOGIN_SUCCESS_STATUS);
|
||||||
|
}
|
||||||
|
else if (Constants.LOGIN_FAIL.equals(status))
|
||||||
|
{
|
||||||
|
logininfor.setStatus(Constants.LOGIN_FAIL_STATUS);
|
||||||
|
}
|
||||||
|
remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,518 @@
|
||||||
|
package com.m2pool.auth.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.m2pool.auth.entity.EmailCodeEntity;
|
||||||
|
import com.m2pool.auth.entity.GetEmailCodeEntity;
|
||||||
|
import com.m2pool.auth.entity.GetLoginEmailCodeEntity;
|
||||||
|
import com.m2pool.auth.service.MailService;
|
||||||
|
import com.m2pool.common.core.RedisTransKey;
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.common.core.constant.SecurityConstants;
|
||||||
|
import com.m2pool.common.core.exception.ServiceException;
|
||||||
|
import com.m2pool.common.core.utils.CodeUtils;
|
||||||
|
import com.m2pool.common.core.utils.StringUtils;
|
||||||
|
import com.m2pool.common.redis.service.RedisService;
|
||||||
|
import com.m2pool.common.security.utils.SecurityUtils;
|
||||||
|
import com.m2pool.system.api.RemoteUserService;
|
||||||
|
import com.m2pool.system.api.model.LoginUser;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||||
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description TODO
|
||||||
|
* @Date 2024/6/12 15:08
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class MaliServiceImpl implements MailService {
|
||||||
|
/**
|
||||||
|
* 注入邮件工具类
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private JavaMailSenderImpl javaMailSender;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RemoteUserService remoteUserService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
|
@Value("${spring.mail.username}")
|
||||||
|
private String sendMailer;
|
||||||
|
|
||||||
|
public static String EMAIL_REGEX="^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测邮件信息类
|
||||||
|
* @param to
|
||||||
|
* @param subject
|
||||||
|
* @param text
|
||||||
|
*/
|
||||||
|
private void checkMail(String to,String subject,String text){
|
||||||
|
if(StringUtils.isEmpty(to)){
|
||||||
|
throw new RuntimeException("邮件收信人不能为空");
|
||||||
|
}
|
||||||
|
if(StringUtils.isEmpty(subject)){
|
||||||
|
throw new RuntimeException("邮件主题不能为空");
|
||||||
|
}
|
||||||
|
if(StringUtils.isEmpty(text)){
|
||||||
|
throw new RuntimeException("邮件内容不能为空");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送纯文本邮件
|
||||||
|
* @param to
|
||||||
|
* @param subject
|
||||||
|
* @param text
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sendTextMailMessage(String to,String subject,String text){
|
||||||
|
|
||||||
|
try {
|
||||||
|
//true 代表支持复杂的类型
|
||||||
|
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(),true);
|
||||||
|
//邮件发信人
|
||||||
|
mimeMessageHelper.setFrom(sendMailer);
|
||||||
|
//邮件收信人 1或多个
|
||||||
|
mimeMessageHelper.setTo(to.split(","));
|
||||||
|
//邮件主题
|
||||||
|
mimeMessageHelper.setSubject(subject);
|
||||||
|
//邮件内容
|
||||||
|
mimeMessageHelper.setText(text);
|
||||||
|
//邮件发送时间
|
||||||
|
mimeMessageHelper.setSentDate(new Date());
|
||||||
|
|
||||||
|
//发送邮件
|
||||||
|
javaMailSender.send(mimeMessageHelper.getMimeMessage());
|
||||||
|
//System.out.println("发送邮件成功:"+sendMailer+"->"+to);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
//System.out.println("发送邮件失败:"+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送html邮件
|
||||||
|
* @param to
|
||||||
|
* @param subject
|
||||||
|
* @param content
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sendHtmlMailMessage(String to,String subject,String content){
|
||||||
|
|
||||||
|
content="<!DOCTYPE html>\n" +
|
||||||
|
"<html>\n" +
|
||||||
|
"<head>\n" +
|
||||||
|
"<meta charset=\"utf-8\">\n" +
|
||||||
|
"<title>邮件</title>\n" +
|
||||||
|
"</head>\n" +
|
||||||
|
"<body>\n" +
|
||||||
|
"\t<h3>这是一封HTML邮件!</h3>\n" +
|
||||||
|
"</body>\n" +
|
||||||
|
"</html>";
|
||||||
|
try {
|
||||||
|
//true 代表支持复杂的类型
|
||||||
|
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(),true);
|
||||||
|
//邮件发信人
|
||||||
|
mimeMessageHelper.setFrom(sendMailer);
|
||||||
|
//邮件收信人 1或多个
|
||||||
|
mimeMessageHelper.setTo(to.split(","));
|
||||||
|
//邮件主题
|
||||||
|
mimeMessageHelper.setSubject(subject);
|
||||||
|
//邮件内容 true 代表支持html
|
||||||
|
mimeMessageHelper.setText(content,true);
|
||||||
|
//邮件发送时间
|
||||||
|
mimeMessageHelper.setSentDate(new Date());
|
||||||
|
|
||||||
|
//发送邮件
|
||||||
|
javaMailSender.send(mimeMessageHelper.getMimeMessage());
|
||||||
|
System.out.println("发送邮件成功:"+sendMailer+"->"+to);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.println("发送邮件失败:"+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送带附件的邮件
|
||||||
|
* @param to 邮件收信人
|
||||||
|
* @param subject 邮件主题
|
||||||
|
* @param content 邮件内容
|
||||||
|
* @param filePath 附件路径
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sendAttachmentMailMessage(String to,String subject,String content,String filePath){
|
||||||
|
try {
|
||||||
|
//true 代表支持复杂的类型
|
||||||
|
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(),true);
|
||||||
|
//邮件发信人
|
||||||
|
mimeMessageHelper.setFrom(sendMailer);
|
||||||
|
//邮件收信人 1或多个
|
||||||
|
mimeMessageHelper.setTo(to.split(","));
|
||||||
|
//邮件主题
|
||||||
|
mimeMessageHelper.setSubject(subject);
|
||||||
|
//邮件内容 true 代表支持html
|
||||||
|
mimeMessageHelper.setText(content,true);
|
||||||
|
//邮件发送时间
|
||||||
|
mimeMessageHelper.setSentDate(new Date());
|
||||||
|
//添加邮件附件
|
||||||
|
FileSystemResource file = new FileSystemResource(new File(filePath));
|
||||||
|
String fileName = file.getFilename();
|
||||||
|
mimeMessageHelper.addAttachment(fileName, file);
|
||||||
|
|
||||||
|
//发送邮件
|
||||||
|
javaMailSender.send(mimeMessageHelper.getMimeMessage());
|
||||||
|
//System.out.println("发送邮件成功:"+sendMailer+"->"+to);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
//System.out.println("发送邮件失败:"+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送账号注册邮箱验证码
|
||||||
|
* @param to
|
||||||
|
* @param code
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sendCodeMailMessage(String to, String code) {
|
||||||
|
String subject = "账号注册,邮箱验证码";
|
||||||
|
String text = "注册验证码10分钟内有效:\n\t"+code;
|
||||||
|
sendTextMailMessage(to,subject,text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送账号登录邮箱验证码
|
||||||
|
* @param to
|
||||||
|
* @param code
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sendLoginCodeMailMessage(String to, String code) {
|
||||||
|
String subject = "用户登录,邮箱验证码";
|
||||||
|
String text = "登录验证码10分钟内有效:\n\t"+code;
|
||||||
|
sendTextMailMessage(to,subject,text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendResetPwdMailMessage(String to, String code) {
|
||||||
|
String subject = "账号重置密码,邮箱验证码";
|
||||||
|
String text = "您正在重置密码,如果不是您本人操作,请忽略。验证码10分钟内有效:\n\t"+code;
|
||||||
|
sendTextMailMessage(to,subject,text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendUpdatePwdMailMessage(String to, String code) {
|
||||||
|
String subject = "修改密码,邮箱验证码";
|
||||||
|
String text = "您正在修改密码,如果不是您本人操作,请忽略。验证码10分钟内有效:\n\t"+code;
|
||||||
|
sendTextMailMessage(to,subject,text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> emailCode(GetEmailCodeEntity entity) {
|
||||||
|
String email = entity.getEmail();
|
||||||
|
if(!StringUtils.isBlank(email)){
|
||||||
|
if(!email.matches(EMAIL_REGEX)){
|
||||||
|
return R.fail("邮箱格式错误");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
return R.fail("601,\"邮箱不能为空\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
//手动格式验证
|
||||||
|
|
||||||
|
//判断用户是不是恶意刷邮箱,在规定时间内进行的
|
||||||
|
if (redisService.hasKey(RedisTransKey.getEmailKey(email))) {
|
||||||
|
Object o = redisService.getCacheObject(RedisTransKey.getEmailKey(email));//user:emailCode:email
|
||||||
|
|
||||||
|
EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
|
||||||
|
if (emailCodeEntity.getTimes() > 4) {
|
||||||
|
return R.fail("请求次数过多,请10分钟后再试,(同一用户10分钟内只能请求4次)");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
emailCodeEntity.setEmailCode(emailCode);
|
||||||
|
|
||||||
|
|
||||||
|
//if(!email.equals(emailCodeEntity.getEmail())){
|
||||||
|
// //email与缓存中所存邮箱不同 则请求次数重置为1
|
||||||
|
// emailCodeEntity.setTimes(1);
|
||||||
|
//}else {
|
||||||
|
// emailCodeEntity.setTimes(emailCodeEntity.getTimes() + 1);
|
||||||
|
//}
|
||||||
|
|
||||||
|
emailCodeEntity.setTimes(emailCodeEntity.getTimes() + 1);
|
||||||
|
long overTime = redisService.getExpire(RedisTransKey.setEmailKey(email));
|
||||||
|
redisService.setCacheObject(RedisTransKey.setEmailKey(email), emailCodeEntity, overTime, TimeUnit.SECONDS
|
||||||
|
);
|
||||||
|
sendCodeMailMessage(email, emailCodeEntity.getEmailCode());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
R<LoginUser> userByEmail = remoteUserService.getUserInfo(email, SecurityConstants.INNER);
|
||||||
|
|
||||||
|
//if (userByName.getData() != null) {
|
||||||
|
// return R.fail(603,"用户名"+username+"已被注册");
|
||||||
|
//} else
|
||||||
|
if(userByEmail.getData() !=null){
|
||||||
|
|
||||||
|
return R.fail(604,"邮箱"+email+"已被注册");
|
||||||
|
} else {
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
// 最多允许用户在10分钟内发送2次的邮箱验证
|
||||||
|
// 0s倒计时后用户可以再发送验证码,但是间隔在10分钟内只能再发送1次
|
||||||
|
EmailCodeEntity emailCodeEntity = new EmailCodeEntity(
|
||||||
|
email, emailCode,1
|
||||||
|
);
|
||||||
|
//设置失效时间10分钟
|
||||||
|
redisService.setCacheObject(RedisTransKey.getEmailKey(email), emailCodeEntity,
|
||||||
|
10L, TimeUnit.MINUTES
|
||||||
|
);
|
||||||
|
sendCodeMailMessage(email, emailCodeEntity.getEmailCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return R.success("请求成功,验证码已经发送至用户邮箱");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> loginCode(GetLoginEmailCodeEntity entity) {
|
||||||
|
String email = entity.getAccount();
|
||||||
|
if(!StringUtils.isBlank(email)){
|
||||||
|
if(!email.matches(EMAIL_REGEX)){
|
||||||
|
return R.fail("邮箱格式错误");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
return R.fail(601,"邮箱不能为空");
|
||||||
|
}
|
||||||
|
//String username = entity.getUserName();
|
||||||
|
|
||||||
|
//if(StringUtils.isNull(username)){
|
||||||
|
// return R.fail(602,"用户名不能为空");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//判断用户是不是恶意刷邮箱,在规定时间内进行的
|
||||||
|
if (redisService.hasKey(RedisTransKey.getLoginKey(email))) {
|
||||||
|
Object o = redisService.getCacheObject(RedisTransKey.getLoginKey(email));//user:login:email
|
||||||
|
|
||||||
|
EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
|
||||||
|
if (emailCodeEntity.getTimes() > 4) {
|
||||||
|
return R.fail("请求次数过多,请10分钟后再试,(同一用户10分钟内只能请求4次)");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
emailCodeEntity.setEmailCode(emailCode);
|
||||||
|
|
||||||
|
//if(!email.equals(emailCodeEntity.getEmail())){
|
||||||
|
// //email与缓存中所存邮箱不同 则请求次数重置为1
|
||||||
|
// emailCodeEntity.setTimes(1);
|
||||||
|
//}else {
|
||||||
|
// emailCodeEntity.setTimes(emailCodeEntity.getTimes() + 1);
|
||||||
|
//}
|
||||||
|
|
||||||
|
emailCodeEntity.setTimes(emailCodeEntity.getTimes() + 1);
|
||||||
|
long overTime = redisService.getExpire(RedisTransKey.setLoginKey(email));
|
||||||
|
redisService.setCacheObject(RedisTransKey.setLoginKey(email), emailCodeEntity, overTime, TimeUnit.SECONDS
|
||||||
|
);
|
||||||
|
sendLoginCodeMailMessage(email, emailCodeEntity.getEmailCode());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
R<LoginUser> userByEmail = remoteUserService.getUserInfo(email, SecurityConstants.INNER);
|
||||||
|
|
||||||
|
//if (userByName.getData() != null) {
|
||||||
|
// return R.fail(603,"用户名"+username+"已被注册");
|
||||||
|
//} else
|
||||||
|
if(StringUtils.isNull(userByEmail.getData())){
|
||||||
|
|
||||||
|
return R.fail(606,"邮箱"+email+"未注册");
|
||||||
|
} else {
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
// 最多允许用户在10分钟内发送2次的邮箱验证
|
||||||
|
// 0s倒计时后用户可以再发送验证码,但是间隔在10分钟内只能再发送1次
|
||||||
|
EmailCodeEntity emailCodeEntity = new EmailCodeEntity(
|
||||||
|
email, emailCode,1
|
||||||
|
);
|
||||||
|
//设置失效时间10分钟
|
||||||
|
redisService.setCacheObject(RedisTransKey.getLoginKey(email), emailCodeEntity,
|
||||||
|
10L, TimeUnit.MINUTES
|
||||||
|
);
|
||||||
|
sendLoginCodeMailMessage(email, emailCodeEntity.getEmailCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return R.success("请求成功,验证码已经发送至用户邮箱");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> AddCreditCode(GetEmailCodeEntity entity) {
|
||||||
|
String email = entity.getEmail();
|
||||||
|
String username = entity.getUserName();
|
||||||
|
|
||||||
|
if(StringUtils.isNull(email)){
|
||||||
|
return R.fail(601,"邮箱不能为空");
|
||||||
|
}
|
||||||
|
if(StringUtils.isNull(username)){
|
||||||
|
return R.fail(602,"用户名不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断用户是不是恶意刷邮箱,在规定时间内进行的
|
||||||
|
if (redisService.hasKey(RedisTransKey.getAddCreditEmailKey(email))) {
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
Object o = redisService.getCacheObject(RedisTransKey.getAddCreditEmailKey(email));//user:addCreditEmailCode:email
|
||||||
|
|
||||||
|
com.m2pool.system.api.entity.EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), com.m2pool.system.api.entity.EmailCodeEntity.class);
|
||||||
|
if (emailCodeEntity.getTimes() > 4) {
|
||||||
|
return R.fail("请求次数过多,请10分钟后再试,(同一用户10分钟内只能请求4次)");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
emailCodeEntity.setEmailCode(emailCode);
|
||||||
|
emailCodeEntity.setUserName(username);
|
||||||
|
|
||||||
|
|
||||||
|
emailCodeEntity.setTimes(emailCodeEntity.getTimes() + 1);
|
||||||
|
long overTime = redisService.getExpire(RedisTransKey.getAddCreditEmailKey(email));
|
||||||
|
redisService.setCacheObject(RedisTransKey.setAddCreditEmailKey(email), emailCodeEntity, overTime, TimeUnit.SECONDS
|
||||||
|
);
|
||||||
|
sendCodeMailMessage(email, emailCodeEntity.getEmailCode());
|
||||||
|
}
|
||||||
|
long t2 = System.currentTimeMillis();
|
||||||
|
System.out.println("处理业务1耗时"+(t2-t1));
|
||||||
|
} else {
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
// 最多允许用户在10分钟内发送2次的邮箱验证
|
||||||
|
// 0s倒计时后用户可以再发送验证码,但是间隔在10分钟内只能再发送1次
|
||||||
|
com.m2pool.system.api.entity.EmailCodeEntity emailCodeEntity = new com.m2pool.system.api.entity.EmailCodeEntity (
|
||||||
|
username , email, emailCode,1
|
||||||
|
);
|
||||||
|
//设置失效时间10分钟
|
||||||
|
redisService.setCacheObject(RedisTransKey.getAddCreditEmailKey(email), emailCodeEntity,
|
||||||
|
10L, TimeUnit.MINUTES
|
||||||
|
);
|
||||||
|
String subject = "用户提现邮箱验证码";
|
||||||
|
String text = "提现验证码,10分钟内有效:\n\t"+emailCodeEntity.getEmailCode();
|
||||||
|
long t2 = System.currentTimeMillis();
|
||||||
|
System.out.println("处理业务2耗时"+(t2-t1));
|
||||||
|
sendTextMailMessage(email,subject,text);
|
||||||
|
long t3 = System.currentTimeMillis();
|
||||||
|
System.out.println("发送邮箱耗时"+(t3-t2));
|
||||||
|
}
|
||||||
|
return R.success("请求成功,验证码已经发送至用户邮箱");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> resetPwdCode(GetEmailCodeEntity entity) {
|
||||||
|
String email = entity.getEmail();
|
||||||
|
if(!StringUtils.isBlank(email)){
|
||||||
|
if(!email.matches(EMAIL_REGEX)){
|
||||||
|
return R.fail("邮箱格式错误");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
return R.fail(601,"邮箱为不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
//通过邮箱获取用户
|
||||||
|
R<LoginUser> userByEmail = remoteUserService.getUserInfo(email, SecurityConstants.INNER);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(userByEmail.getData())){
|
||||||
|
return R.fail("邮箱"+email+"未被注册,请检查邮箱是否正确");
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断用户是不是恶意刷邮箱,在规定时间内进行的
|
||||||
|
if (redisService.hasKey(RedisTransKey.getResetPwdKey(email))) {
|
||||||
|
|
||||||
|
Object o = redisService.getCacheObject(RedisTransKey.getResetPwdKey(email));//user:restPwdCode:email
|
||||||
|
|
||||||
|
EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
|
||||||
|
if (emailCodeEntity.getTimes() >= 5) {
|
||||||
|
return R.fail("请求次数过多,请10分钟后再试");
|
||||||
|
} else {
|
||||||
|
//这里就不去判断两次绑定的邮箱是不是一样的了,不排除第一次输入错了邮箱的情况
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
emailCodeEntity.setEmailCode(emailCode);
|
||||||
|
emailCodeEntity.setTimes(emailCodeEntity.getTimes() + 1);
|
||||||
|
long overTime = redisService.getExpire(RedisTransKey.getResetPwdKey(email));
|
||||||
|
redisService.setCacheObject(RedisTransKey.getResetPwdKey(email), emailCodeEntity, overTime, TimeUnit.SECONDS
|
||||||
|
);
|
||||||
|
sendResetPwdMailMessage(email, emailCodeEntity.getEmailCode());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
// 最多允许用户在10分钟内发送2次的邮箱验证
|
||||||
|
// 0s倒计时后用户可以再发送验证码,但是间隔在10分钟内只能再发送1次
|
||||||
|
EmailCodeEntity emailCodeEntity = new EmailCodeEntity(
|
||||||
|
email, emailCode,1
|
||||||
|
);
|
||||||
|
//设置失效时间10分钟
|
||||||
|
redisService.setCacheObject(RedisTransKey.getResetPwdKey(email), emailCodeEntity,
|
||||||
|
10L, TimeUnit.MINUTES
|
||||||
|
);
|
||||||
|
sendResetPwdMailMessage(email, emailCodeEntity.getEmailCode());
|
||||||
|
}
|
||||||
|
return R.success("请求成功,重置密码验证码已经发送至用户邮箱");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> updatePwdCode() {
|
||||||
|
String email = SecurityUtils.getUsername();
|
||||||
|
if(StringUtils.isBlank(email)){
|
||||||
|
return R.fail("token解析失败");
|
||||||
|
}
|
||||||
|
//通过邮箱获取用户
|
||||||
|
R<LoginUser> userByEmail = remoteUserService.getUserInfo(email, SecurityConstants.INNER);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(userByEmail.getData())){
|
||||||
|
return R.fail("token解析异常");
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断用户是不是恶意刷邮箱,在规定时间内进行的
|
||||||
|
if (redisService.hasKey(RedisTransKey.getUpdatePwdKey(email))) {
|
||||||
|
|
||||||
|
Object o = redisService.getCacheObject(RedisTransKey.getUpdatePwdKey(email));//user:updatePwdCode:email
|
||||||
|
|
||||||
|
EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
|
||||||
|
if (emailCodeEntity.getTimes() >= 5) {
|
||||||
|
return R.fail("请求次数过多,请10分钟后再试");
|
||||||
|
} else {
|
||||||
|
//这里就不去判断两次绑定的邮箱是不是一样的了,不排除第一次输入错了邮箱的情况
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
emailCodeEntity.setEmailCode(emailCode);
|
||||||
|
emailCodeEntity.setTimes(emailCodeEntity.getTimes() + 1);
|
||||||
|
long overTime = redisService.getExpire(RedisTransKey.getUpdatePwdKey(email));
|
||||||
|
redisService.setCacheObject(RedisTransKey.getUpdatePwdKey(email), emailCodeEntity, overTime, TimeUnit.SECONDS
|
||||||
|
);
|
||||||
|
sendUpdatePwdMailMessage(email, emailCodeEntity.getEmailCode());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String emailCode = CodeUtils.creatCode(6);
|
||||||
|
// 最多允许用户在10分钟内发送2次的邮箱验证
|
||||||
|
// 0s倒计时后用户可以再发送验证码,但是间隔在10分钟内只能再发送1次
|
||||||
|
EmailCodeEntity emailCodeEntity = new EmailCodeEntity(
|
||||||
|
email, emailCode,1
|
||||||
|
);
|
||||||
|
//设置失效时间10分钟
|
||||||
|
redisService.setCacheObject(RedisTransKey.getUpdatePwdKey(email), emailCodeEntity,
|
||||||
|
10L, TimeUnit.MINUTES
|
||||||
|
);
|
||||||
|
sendUpdatePwdMailMessage(email, emailCodeEntity.getEmailCode());
|
||||||
|
}
|
||||||
|
return R.success("请求成功,修改密码验证码已经发送至用户邮箱");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
#Tomcat
|
||||||
|
server:
|
||||||
|
port: 9200
|
||||||
|
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
#邮箱基本配置
|
||||||
|
mail:
|
||||||
|
# 配置在limit_time内,用户可以发送limit次验证码
|
||||||
|
limit: 2 这个是我额外的配置,结合邮箱服务用的
|
||||||
|
limitTime: 10 这个是我额外的配置
|
||||||
|
#配置smtp服务主机地址
|
||||||
|
# sina smtp.sina.cn
|
||||||
|
# aliyun smtp.aliyun.com
|
||||||
|
# 163 smtp.163.com 端口号465或994
|
||||||
|
host: mail.privateemail.com
|
||||||
|
#发送者邮箱
|
||||||
|
username: do.not.reply@m2pool.com
|
||||||
|
#配置密码,注意不是真正的密码,而是刚刚申请到的授权码
|
||||||
|
# password:
|
||||||
|
# password: M2pool2024@!
|
||||||
|
# password: axvm-zfgx-cgcg-qhhu
|
||||||
|
password: M2202401!
|
||||||
|
|
||||||
|
|
||||||
|
#端口号
|
||||||
|
port: 587
|
||||||
|
#默认的邮件编码为UTF-8
|
||||||
|
default-encoding: UTF-8
|
||||||
|
#其他参数
|
||||||
|
properties:
|
||||||
|
mail:
|
||||||
|
#配置SSL 加密工厂
|
||||||
|
smtp:
|
||||||
|
ssl:
|
||||||
|
#本地测试,先放开ssl
|
||||||
|
enable: false
|
||||||
|
required: false
|
||||||
|
#开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误
|
||||||
|
debug: false
|
||||||
|
socketFactory:
|
||||||
|
class: javax.net.ssl.SSLSocketFactory
|
||||||
|
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: m2pool-auth
|
||||||
|
profiles:
|
||||||
|
# 环境配置
|
||||||
|
active: prod
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 127.0.0.1:8808
|
||||||
|
namespace: m2_prod
|
||||||
|
group: m2_prod_group
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 127.0.0.1:8808
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yml
|
||||||
|
# 共享配置
|
||||||
|
shared-configs:
|
||||||
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
namespace: m2_prod
|
||||||
|
group: m2_prod_group
|
||||||
|
|
||||||
|
#server:
|
||||||
|
# port: 9500
|
||||||
|
#
|
||||||
|
## Spring
|
||||||
|
#spring:
|
||||||
|
# #邮箱基本配置
|
||||||
|
# mail:
|
||||||
|
# # 配置在limit_time内,用户可以发送limit次验证码
|
||||||
|
# limit: 2 这个是我额外的配置,结合邮箱服务用的
|
||||||
|
# limitTime: 10 这个是我额外的配置
|
||||||
|
# #配置smtp服务主机地址
|
||||||
|
# # sina smtp.sina.cn
|
||||||
|
# # aliyun smtp.aliyun.com
|
||||||
|
# # 163 smtp.163.com 端口号465或994
|
||||||
|
# host: mail.privateemail.com
|
||||||
|
# #发送者邮箱
|
||||||
|
# username: do.not.reply@m2pool.com
|
||||||
|
# #配置密码,注意不是真正的密码,而是刚刚申请到的授权码
|
||||||
|
# # password:
|
||||||
|
# # password: M2202401!
|
||||||
|
# # password: axvm-zfgx-cgcg-qhhu
|
||||||
|
# password: M2202401!
|
||||||
|
#
|
||||||
|
# #端口号
|
||||||
|
# port: 587
|
||||||
|
## port: 465
|
||||||
|
# #默认的邮件编码为UTF-8
|
||||||
|
# default-encoding: UTF-8
|
||||||
|
# #其他参数
|
||||||
|
# properties:
|
||||||
|
# mail:
|
||||||
|
# #配置SSL 加密工厂
|
||||||
|
# smtp:
|
||||||
|
# ssl:
|
||||||
|
# #本地测试,先放开ssl
|
||||||
|
# enable: false
|
||||||
|
# required: false
|
||||||
|
# #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误
|
||||||
|
# debug: false
|
||||||
|
# socketFactory:
|
||||||
|
# class: javax.net.ssl.SSLSocketFactory
|
||||||
|
##
|
||||||
|
## host: smtp.qq.com
|
||||||
|
## #发送者邮箱
|
||||||
|
## username: 1328642438@qq.com
|
||||||
|
## #配置密码,注意不是真正的密码,而是刚刚申请到的授权码
|
||||||
|
## # password:
|
||||||
|
## # password: M2pool2024@!
|
||||||
|
## # password: axvm-zfgx-cgcg-qhhu
|
||||||
|
## password: eqrzqxeqzlshhedh
|
||||||
|
##
|
||||||
|
## #端口号
|
||||||
|
## port: 465
|
||||||
|
## #默认的邮件编码为UTF-8
|
||||||
|
## default-encoding: UTF-8
|
||||||
|
## #其他参数
|
||||||
|
## properties:
|
||||||
|
## mail:
|
||||||
|
## #配置SSL 加密工厂
|
||||||
|
## smtp:
|
||||||
|
## ssl:
|
||||||
|
## #本地测试,先放开ssl
|
||||||
|
## enable: true
|
||||||
|
## required: true
|
||||||
|
## #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误
|
||||||
|
## debug: false
|
||||||
|
## socketFactory:
|
||||||
|
## class: javax.net.ssl.SSLSocketFactory
|
||||||
|
#
|
||||||
|
# application:
|
||||||
|
# # 应用名称
|
||||||
|
# name: m2pool-auth
|
||||||
|
# profiles:
|
||||||
|
# # 环境配置
|
||||||
|
# active: test
|
||||||
|
# cloud:
|
||||||
|
# nacos:
|
||||||
|
# discovery:
|
||||||
|
# # 服务注册地址
|
||||||
|
# server-addr: 127.0.0.1:8808
|
||||||
|
# namespace: m2_test
|
||||||
|
# group: m2_test_group
|
||||||
|
# config:
|
||||||
|
# # 配置中心地址
|
||||||
|
# server-addr: 127.0.0.1:8808
|
||||||
|
# # 配置文件格式
|
||||||
|
# file-extension: yml
|
||||||
|
# # 共享配置
|
||||||
|
# shared-configs:
|
||||||
|
# - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
# namespace: m2_test
|
||||||
|
# group: m2_test_group
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||||
|
<!-- 日志存放路径 -->
|
||||||
|
<property name="log.path" value="logs/m2pool-auth" />
|
||||||
|
<!-- 日志输出格式 -->
|
||||||
|
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统日志输出 -->
|
||||||
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/info.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>INFO</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/error.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>ERROR</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统模块日志级别控制 -->
|
||||||
|
<logger name="com.m2pool" level="info" />
|
||||||
|
<!-- Spring日志级别控制 -->
|
||||||
|
<logger name="org.springframework" level="warn" />
|
||||||
|
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="console" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<!--系统操作日志-->
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="file_info" />
|
||||||
|
<appender-ref ref="file_error" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,110 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="Spring" name="Spring">
|
||||||
|
<configuration />
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok-maven-plugin:1.18.6.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.sonatype.plexus:plexus-build-api:0.0.7" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.codehaus.plexus:plexus-utils:1.5.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,133 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>m2pool-common</artifactId>
|
||||||
|
<groupId>com.m2pool</groupId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>common-core</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- SpringCloud Openfeign -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Loadbalancer -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Context Support -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context-support</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok-maven-plugin</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Web -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Transmittable ThreadLocal -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>transmittable-thread-local</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Pagehelper -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.pagehelper</groupId>
|
||||||
|
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Hibernate Validator -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Jackson -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Alibaba Fastjson -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Jwt -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Jaxb -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.xml.bind</groupId>
|
||||||
|
<artifactId>jaxb-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Apache Lang3 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Commons Io -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Commons Fileupload -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-fileupload</groupId>
|
||||||
|
<artifactId>commons-fileupload</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- excel工具 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-ooxml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Java Servlet -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Swagger -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger</groupId>
|
||||||
|
<artifactId>swagger-annotations</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.m2pool.common.core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description TODO
|
||||||
|
* @Date 2024/6/12 15:35
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class RedisTransKey {
|
||||||
|
|
||||||
|
|
||||||
|
public static final String RedisNameSpace="user";
|
||||||
|
public static final String RedisTokenName="token";
|
||||||
|
public static final String RedisLoginName="login";
|
||||||
|
public static final String RedisEmailCodeName="emailCode";
|
||||||
|
public static final String RedisAddCreditEmailCodeName="addCreditEmailCode";
|
||||||
|
public static final String RedisResetPwdCodeName="restPwdCode";
|
||||||
|
public static final String RedisUpdatePwdCodeName="updatePwdCode";
|
||||||
|
|
||||||
|
public static String setEmailKey(String key){
|
||||||
|
return RedisNameSpace+":"+RedisEmailCodeName+":"+key;
|
||||||
|
}
|
||||||
|
public static String setRootKey(String key){
|
||||||
|
return RedisNameSpace+":"+key+":";
|
||||||
|
}
|
||||||
|
public static String setTokenKey(String key){
|
||||||
|
return RedisNameSpace+':'+RedisTokenName+":"+key;
|
||||||
|
}
|
||||||
|
public static String setLoginKey(String key){
|
||||||
|
return RedisNameSpace+':'+RedisLoginName+":"+key;
|
||||||
|
}
|
||||||
|
public static String setResetPwdKey(String key){
|
||||||
|
return RedisNameSpace+":"+RedisResetPwdCodeName+":"+key;
|
||||||
|
}
|
||||||
|
public static String setUpdatePwdKey(String key){
|
||||||
|
return RedisNameSpace+":"+RedisUpdatePwdCodeName+":"+key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String setAddCreditEmailKey(String key){
|
||||||
|
return RedisNameSpace+":"+RedisAddCreditEmailCodeName+":"+key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEmailKey(String key){return setEmailKey(key);}
|
||||||
|
public static String getRootKey(String key){return setRootKey(key);}
|
||||||
|
public static String getTokenKey(String key){return setTokenKey(key);}
|
||||||
|
public static String getLoginKey(String key){return setLoginKey(key);}
|
||||||
|
public static String getResetPwdKey(String key){return setResetPwdKey(key);}
|
||||||
|
public static String getUpdatePwdKey(String key){return setUpdatePwdKey(key);}
|
||||||
|
public static String getAddCreditEmailKey(String key){return setAddCreditEmailKey(key);}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.m2pool.common.core.Result;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.constant.Constants;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 响应信息主体
|
||||||
|
* @Date 2024/6/11 9:18
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class R<T> implements Serializable
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 3276842119125241681L;
|
||||||
|
|
||||||
|
/** 成功 */
|
||||||
|
public static final int SUCCESS = Constants.SUCCESS;
|
||||||
|
|
||||||
|
/** 失败 */
|
||||||
|
public static final int FAIL = Constants.FAIL;
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public static <T> R<T> success()
|
||||||
|
{
|
||||||
|
return restResult(null, SUCCESS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> success(T data)
|
||||||
|
{
|
||||||
|
return restResult(data, SUCCESS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> success(T data, String msg)
|
||||||
|
{
|
||||||
|
return restResult(data, SUCCESS, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail()
|
||||||
|
{
|
||||||
|
return restResult(null, FAIL, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(String msg)
|
||||||
|
{
|
||||||
|
return restResult(null, FAIL, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(T data)
|
||||||
|
{
|
||||||
|
return restResult(data, FAIL, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(T data, String msg)
|
||||||
|
{
|
||||||
|
return restResult(data, FAIL, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(int code, String msg)
|
||||||
|
{
|
||||||
|
return restResult(null, code, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> R<T> restResult(T data, int code, String msg)
|
||||||
|
{
|
||||||
|
R<T> apiResult = new R<>();
|
||||||
|
apiResult.setCode(code);
|
||||||
|
apiResult.setData(data);
|
||||||
|
apiResult.setMsg(msg);
|
||||||
|
return apiResult;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
package com.m2pool.common.core.annotation;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.utils.poi.ExcelHandlerAdapter;
|
||||||
|
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||||
|
import org.apache.poi.ss.usermodel.IndexedColors;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义导出Excel数据注解
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface Excel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 导出时在excel中排序
|
||||||
|
*/
|
||||||
|
public int sort() default Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出到Excel中的名字.
|
||||||
|
*/
|
||||||
|
public String name() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期格式, 如: yyyy-MM-dd
|
||||||
|
*/
|
||||||
|
public String dateFormat() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
|
||||||
|
*/
|
||||||
|
public String readConverterExp() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分隔符,读取字符串组内容
|
||||||
|
*/
|
||||||
|
public String separator() default ",";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
|
||||||
|
*/
|
||||||
|
public int scale() default -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
|
||||||
|
*/
|
||||||
|
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出时在excel中每个列的高度 单位为字符
|
||||||
|
*/
|
||||||
|
public double height() default 14;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出时在excel中每个列的宽 单位为字符
|
||||||
|
*/
|
||||||
|
public double width() default 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文字后缀,如% 90 变成90%
|
||||||
|
*/
|
||||||
|
public String suffix() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当值为空时,字段的默认值
|
||||||
|
*/
|
||||||
|
public String defaultValue() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提示信息
|
||||||
|
*/
|
||||||
|
public String prompt() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置只能选择不能输入的列内容.
|
||||||
|
*/
|
||||||
|
public String[] combo() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
|
||||||
|
*/
|
||||||
|
public boolean isExport() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 另一个类中的属性名称,支持多级获取,以小数点隔开
|
||||||
|
*/
|
||||||
|
public String targetAttr() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否自动统计数据,在最后追加一行统计数据总和
|
||||||
|
*/
|
||||||
|
public boolean isStatistics() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出类型(0数字 1字符串)
|
||||||
|
*/
|
||||||
|
public ColumnType cellType() default ColumnType.STRING;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出字体颜色
|
||||||
|
*/
|
||||||
|
public IndexedColors color() default IndexedColors.BLACK;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出字段对齐方式
|
||||||
|
*/
|
||||||
|
public HorizontalAlignment align() default HorizontalAlignment.CENTER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义数据处理器
|
||||||
|
*/
|
||||||
|
public Class<?> handler() default ExcelHandlerAdapter.class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义数据处理器参数
|
||||||
|
*/
|
||||||
|
public String[] args() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
|
||||||
|
*/
|
||||||
|
Type type() default Type.ALL;
|
||||||
|
|
||||||
|
public enum Type
|
||||||
|
{
|
||||||
|
ALL(0), EXPORT(1), IMPORT(2);
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
Type(int value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int value()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ColumnType
|
||||||
|
{
|
||||||
|
NUMERIC(0), STRING(1), IMAGE(2);
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
ColumnType(int value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int value()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.m2pool.common.core.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel注解集
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Excels
|
||||||
|
{
|
||||||
|
Excel[] value();
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.m2pool.common.core.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description TODO
|
||||||
|
* @Date 2024/6/12 17:24
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value={ElementType.FIELD})
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface ParamName {
|
||||||
|
/**
|
||||||
|
* 参数名称
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String value();
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.m2pool.common.core.annotation;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.constant.CacheConstants;
|
||||||
|
import com.m2pool.common.core.constant.Constants;
|
||||||
|
import com.m2pool.common.core.enums.LimitType;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description TODO
|
||||||
|
* @Date 2024/6/12 17:28
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface RateLimiter
|
||||||
|
{
|
||||||
|
// 限流key
|
||||||
|
public String key() default CacheConstants.RATE_LIMIT_KEY;
|
||||||
|
|
||||||
|
// 限流时间,单位秒
|
||||||
|
public int time() default 30;
|
||||||
|
|
||||||
|
// 限流次数
|
||||||
|
public int count() default 30;
|
||||||
|
|
||||||
|
// 限流类型
|
||||||
|
public LimitType limitType() default LimitType.DEFAULT;
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.m2pool.common.core.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 缓存的key
|
||||||
|
* @Date 2024/6/12 17:22
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class CacheConstants
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 缓存有效期,默认6个月 60*24*30*3=129600(分钟)
|
||||||
|
*/
|
||||||
|
public final static long EXPIRATION = 129600;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存刷新时间,默认120(分钟)
|
||||||
|
*/
|
||||||
|
public final static long REFRESH_TIME = 120;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限缓存前缀
|
||||||
|
*/
|
||||||
|
public final static String LOGIN_TOKEN_KEY = "login_tokens:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 防重提交 redis key
|
||||||
|
*/
|
||||||
|
public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限流 redis key
|
||||||
|
*/
|
||||||
|
public static final String RATE_LIMIT_KEY = "rate_limit:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api-key缓存前缀
|
||||||
|
*/
|
||||||
|
public final static String OPEN_API_KEY = "api_key:";
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
package com.m2pool.common.core.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 常量信息
|
||||||
|
* @Date 2024/6/11 18:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class Constants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UTF-8 字符集
|
||||||
|
*/
|
||||||
|
public static final String UTF8 = "UTF-8";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GBK 字符集
|
||||||
|
*/
|
||||||
|
public static final String GBK = "GBK";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RMI 远程方法调用
|
||||||
|
*/
|
||||||
|
public static final String LOOKUP_RMI = "rmi:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LDAP 远程方法调用
|
||||||
|
*/
|
||||||
|
public static final String LOOKUP_LDAP = "ldap:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LDAPS 远程方法调用
|
||||||
|
*/
|
||||||
|
public static final String LOOKUP_LDAPS = "ldaps:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http请求
|
||||||
|
*/
|
||||||
|
public static final String HTTP = "http://";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https请求
|
||||||
|
*/
|
||||||
|
public static final String HTTPS = "https://";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功标记
|
||||||
|
*/
|
||||||
|
public static final Integer SUCCESS = 200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败标记
|
||||||
|
*/
|
||||||
|
public static final Integer FAIL = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录成功状态
|
||||||
|
*/
|
||||||
|
public static final String LOGIN_SUCCESS_STATUS = "0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录失败状态
|
||||||
|
*/
|
||||||
|
public static final String LOGIN_FAIL_STATUS = "1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录成功
|
||||||
|
*/
|
||||||
|
public static final String LOGIN_SUCCESS = "Success";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注销
|
||||||
|
*/
|
||||||
|
public static final String LOGOUT = "Logout";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册
|
||||||
|
*/
|
||||||
|
public static final String REGISTER = "Register";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录失败
|
||||||
|
*/
|
||||||
|
public static final String LOGIN_FAIL = "Error";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前记录起始索引
|
||||||
|
*/
|
||||||
|
public static final String PAGE_NUM = "pageNum";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每页显示记录数
|
||||||
|
*/
|
||||||
|
public static final String PAGE_SIZE = "pageSize";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序列
|
||||||
|
*/
|
||||||
|
public static final String ORDER_BY_COLUMN = "orderByColumn";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序的方向 "desc" 或者 "asc".
|
||||||
|
*/
|
||||||
|
public static final String IS_ASC = "isAsc";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码 redis key
|
||||||
|
*/
|
||||||
|
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码有效期(分钟)
|
||||||
|
*/
|
||||||
|
public static final long CAPTCHA_EXPIRATION = 2;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数管理 cache key
|
||||||
|
*/
|
||||||
|
public static final String SYS_CONFIG_KEY = "sys_config:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源映射路径 前缀
|
||||||
|
*/
|
||||||
|
public static final String RESOURCE_PREFIX = "/profile";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.m2pool.common.core.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 返回状态码
|
||||||
|
* @Date 2024/6/12 11:35
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class HttpStatus
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 操作成功
|
||||||
|
*/
|
||||||
|
public static final int SUCCESS = 200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象创建成功
|
||||||
|
*/
|
||||||
|
public static final int CREATED = 201;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求已经被接受
|
||||||
|
*/
|
||||||
|
public static final int ACCEPTED = 202;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作已经执行成功,但是没有返回数据
|
||||||
|
*/
|
||||||
|
public static final int NO_CONTENT = 204;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源已被移除
|
||||||
|
*/
|
||||||
|
public static final int MOVED_PERM = 301;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重定向
|
||||||
|
*/
|
||||||
|
public static final int SEE_OTHER = 303;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源没有被修改
|
||||||
|
*/
|
||||||
|
public static final int NOT_MODIFIED = 304;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数列表错误(缺少,格式不匹配)
|
||||||
|
*/
|
||||||
|
public static final int BAD_REQUEST = 400;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未授权
|
||||||
|
*/
|
||||||
|
public static final int UNAUTHORIZED = 401;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登陆过期
|
||||||
|
*/
|
||||||
|
public static final int LOGINEXPIRES = 421;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登陆过期
|
||||||
|
*/
|
||||||
|
public static final int TOKENEXPIRES = 422;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问受限,授权过期
|
||||||
|
*/
|
||||||
|
public static final int FORBIDDEN = 403;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源,服务未找到
|
||||||
|
*/
|
||||||
|
public static final int NOT_FOUND = 404;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不允许的http方法
|
||||||
|
*/
|
||||||
|
public static final int BAD_METHOD = 405;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源冲突,或者资源被锁
|
||||||
|
*/
|
||||||
|
public static final int CONFLICT = 409;
|
||||||
|
|
||||||
|
public static final int TOO_MANY_REQUESTS = 429;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不支持的数据,媒体类型
|
||||||
|
*/
|
||||||
|
public static final int UNSUPPORTED_TYPE = 415;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统内部错误
|
||||||
|
*/
|
||||||
|
public static final int ERROR = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口未实现
|
||||||
|
*/
|
||||||
|
public static final int NOT_IMPLEMENTED = 501;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.m2pool.common.core.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 权限相关通用常量
|
||||||
|
* @Date 2024/6/11 16:19
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class OpenApiKeyConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权信息字段
|
||||||
|
*/
|
||||||
|
public static final String API_KEY_HEADER = "API-KEY";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api标识
|
||||||
|
*/
|
||||||
|
public static final String API_KEY = "api_key";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api对应用户
|
||||||
|
*/
|
||||||
|
public static final String API_USER = "api_user";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api 绑定ip
|
||||||
|
*/
|
||||||
|
public static final String API_IP = "api_ip";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api 相关信息
|
||||||
|
*/
|
||||||
|
public static final String API_KEY_INFO = "api_key_info";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求来源
|
||||||
|
*/
|
||||||
|
public static final String FROM_SOURCE = "from-source";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.m2pool.common.core.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 权限相关通用常量
|
||||||
|
* @Date 2024/6/11 16:19
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class SecurityConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID字段
|
||||||
|
*/
|
||||||
|
public static final String DETAILS_USER_ID = "user_id";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户名字段
|
||||||
|
*/
|
||||||
|
public static final String DETAILS_USERNAME = "username";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权信息字段
|
||||||
|
*/
|
||||||
|
public static final String AUTHORIZATION_HEADER = "authorization";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求来源
|
||||||
|
*/
|
||||||
|
public static final String FROM_SOURCE = "from-source";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内部请求
|
||||||
|
*/
|
||||||
|
public static final String INNER = "inner";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户标识
|
||||||
|
*/
|
||||||
|
public static final String USER_KEY = "user_key";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录用户
|
||||||
|
*/
|
||||||
|
public static final String LOGIN_USER = "login_user";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.m2pool.common.core.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 服务名常量
|
||||||
|
* @Date 2024/6/12 17:14
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class ServiceNameConstants
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 认证服务的serviceid
|
||||||
|
*/
|
||||||
|
public static final String AUTH_SERVICE = "m2pool-auth";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统模块的serviceid
|
||||||
|
*/
|
||||||
|
public static final String SYSTEM_SERVICE = "m2pool-system";
|
||||||
|
|
||||||
|
///**
|
||||||
|
// * 邮件模块的serviceid
|
||||||
|
// */
|
||||||
|
//public static final String Mail_SERVICE = "m2pool-mail";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件服务的serviceid
|
||||||
|
*/
|
||||||
|
public static final String FILE_SERVICE = "m2pool-file";
|
||||||
|
|
||||||
|
public static final String POOL_SERVICE = "m2pool-pool";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.m2pool.common.core.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description Token的Key常量
|
||||||
|
* @Date 2024/6/11 16:12
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class TokenConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌自定义标识
|
||||||
|
*/
|
||||||
|
public static final String AUTHENTICATION = "Authorization";
|
||||||
|
|
||||||
|
public static final String API_KEY = "API-KEY";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌前缀
|
||||||
|
*/
|
||||||
|
public static final String PREFIX = "Bearer ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌秘钥
|
||||||
|
*/
|
||||||
|
//TODO 根据情况更改密钥
|
||||||
|
public final static String SECRET = "mabsadba2basdsanwepsdaowwwxxsodddl";
|
||||||
|
|
||||||
|
public final static String API_SECRET = "mabsadba2bttxdnwcabpiowwwxxsodddl";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.m2pool.common.core.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户相关常量
|
||||||
|
* @Date 2024/6/12 17:39
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class UserConstants
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 平台内系统用户的唯一标志
|
||||||
|
*/
|
||||||
|
public static final String SYS_USER = "SYS_USER";
|
||||||
|
|
||||||
|
/** 正常状态 */
|
||||||
|
public static final String NORMAL = "0";
|
||||||
|
|
||||||
|
/** 异常状态 */
|
||||||
|
public static final String EXCEPTION = "1";
|
||||||
|
|
||||||
|
/** 用户封禁状态 */
|
||||||
|
public static final String USER_DISABLE = "1";
|
||||||
|
|
||||||
|
/** 角色封禁状态 */
|
||||||
|
public static final String ROLE_DISABLE = "1";
|
||||||
|
|
||||||
|
/** 部门正常状态 */
|
||||||
|
public static final String DEPT_NORMAL = "0";
|
||||||
|
|
||||||
|
/** 部门停用状态 */
|
||||||
|
public static final String DEPT_DISABLE = "1";
|
||||||
|
|
||||||
|
/** 字典正常状态 */
|
||||||
|
public static final String DICT_NORMAL = "0";
|
||||||
|
|
||||||
|
/** 是否为系统默认(是) */
|
||||||
|
public static final String YES = "Y";
|
||||||
|
|
||||||
|
/** 是否菜单外链(是) */
|
||||||
|
public static final String YES_FRAME = "0";
|
||||||
|
|
||||||
|
/** 是否菜单外链(否) */
|
||||||
|
public static final String NO_FRAME = "1";
|
||||||
|
|
||||||
|
/** 菜单类型(目录) */
|
||||||
|
public static final String TYPE_DIR = "M";
|
||||||
|
|
||||||
|
/** 菜单类型(菜单) */
|
||||||
|
public static final String TYPE_MENU = "C";
|
||||||
|
|
||||||
|
/** 菜单类型(按钮) */
|
||||||
|
public static final String TYPE_BUTTON = "F";
|
||||||
|
|
||||||
|
/** Layout组件标识 */
|
||||||
|
public final static String LAYOUT = "Layout";
|
||||||
|
|
||||||
|
/** ParentView组件标识 */
|
||||||
|
public final static String PARENT_VIEW = "ParentView";
|
||||||
|
|
||||||
|
/** InnerLink组件标识 */
|
||||||
|
public final static String INNER_LINK = "InnerLink";
|
||||||
|
|
||||||
|
/** 校验返回结果码 */
|
||||||
|
public final static String UNIQUE = "0";
|
||||||
|
|
||||||
|
public final static String NOT_UNIQUE = "1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户名长度限制
|
||||||
|
*/
|
||||||
|
public static final int USERNAME_MIN_LENGTH = 3;
|
||||||
|
|
||||||
|
public static final int USERNAME_MAX_LENGTH = 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码长度限制
|
||||||
|
*/
|
||||||
|
public static final int PASSWORD_MIN_LENGTH = 6;
|
||||||
|
|
||||||
|
public static final int PASSWORD_MAX_LENGTH = 32;
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.m2pool.common.core.context;
|
||||||
|
|
||||||
|
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||||
|
import com.m2pool.common.core.constant.OpenApiKeyConstants;
|
||||||
|
import com.m2pool.common.core.text.Convert;
|
||||||
|
import com.m2pool.common.core.utils.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 获取当前线程变量中的 用户id、用户名称、Token等信息
|
||||||
|
* @Date 2024/6/12 11:32
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class OpenApiContextHolder
|
||||||
|
{
|
||||||
|
private static final TransmittableThreadLocal<Map<String,Object>> THREAD_LOCAL = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
|
public static void set(String key, Object value)
|
||||||
|
{
|
||||||
|
Map<String, Object> map = getLocalMap();
|
||||||
|
map.put(key, value == null ? StringUtils.EMPTY : value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String get(String key)
|
||||||
|
{
|
||||||
|
Map<String, Object> map = getLocalMap();
|
||||||
|
return Convert.toStr(map.getOrDefault(key, StringUtils.EMPTY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T get(String key, Class<T> clazz)
|
||||||
|
{
|
||||||
|
Map<String, Object> map = getLocalMap();
|
||||||
|
return StringUtils.cast(map.getOrDefault(key, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> getLocalMap()
|
||||||
|
{
|
||||||
|
Map<String, Object> map = THREAD_LOCAL.get();
|
||||||
|
if (map == null)
|
||||||
|
{
|
||||||
|
map = new ConcurrentHashMap<String, Object>();
|
||||||
|
THREAD_LOCAL.set(map);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLocalMap(Map<String, Object> threadLocalMap)
|
||||||
|
{
|
||||||
|
THREAD_LOCAL.set(threadLocalMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getApiUser()
|
||||||
|
{
|
||||||
|
return get(OpenApiKeyConstants.API_USER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setApiUser(String user)
|
||||||
|
{
|
||||||
|
set(OpenApiKeyConstants.API_USER, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getApiIp()
|
||||||
|
{
|
||||||
|
return get(OpenApiKeyConstants.API_IP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setApiIp(String ip)
|
||||||
|
{
|
||||||
|
set(OpenApiKeyConstants.API_IP, ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getApiKey()
|
||||||
|
{
|
||||||
|
return get(OpenApiKeyConstants.API_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setApiKey(String apiKey)
|
||||||
|
{
|
||||||
|
set(OpenApiKeyConstants.API_KEY, apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void remove()
|
||||||
|
{
|
||||||
|
THREAD_LOCAL.remove();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package com.m2pool.common.core.context;
|
||||||
|
|
||||||
|
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||||
|
import com.m2pool.common.core.constant.SecurityConstants;
|
||||||
|
import com.m2pool.common.core.text.Convert;
|
||||||
|
import com.m2pool.common.core.utils.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 获取当前线程变量中的 用户id、用户名称、Token等信息
|
||||||
|
* @Date 2024/6/12 11:32
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class SecurityContextHolder
|
||||||
|
{
|
||||||
|
private static final TransmittableThreadLocal<Map<String, Object>> THREAD_LOCAL = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
|
public static void set(String key, Object value)
|
||||||
|
{
|
||||||
|
Map<String, Object> map = getLocalMap();
|
||||||
|
map.put(key, value == null ? StringUtils.EMPTY : value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String get(String key)
|
||||||
|
{
|
||||||
|
Map<String, Object> map = getLocalMap();
|
||||||
|
return Convert.toStr(map.getOrDefault(key, StringUtils.EMPTY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T get(String key, Class<T> clazz)
|
||||||
|
{
|
||||||
|
Map<String, Object> map = getLocalMap();
|
||||||
|
return StringUtils.cast(map.getOrDefault(key, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> getLocalMap()
|
||||||
|
{
|
||||||
|
Map<String, Object> map = THREAD_LOCAL.get();
|
||||||
|
if (map == null)
|
||||||
|
{
|
||||||
|
map = new ConcurrentHashMap<String, Object>();
|
||||||
|
THREAD_LOCAL.set(map);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLocalMap(Map<String, Object> threadLocalMap)
|
||||||
|
{
|
||||||
|
THREAD_LOCAL.set(threadLocalMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long getUserId()
|
||||||
|
{
|
||||||
|
return Convert.toLong(get(SecurityConstants.DETAILS_USER_ID), 0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setUserId(String account)
|
||||||
|
{
|
||||||
|
set(SecurityConstants.DETAILS_USER_ID, account);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUserName()
|
||||||
|
{
|
||||||
|
return get(SecurityConstants.DETAILS_USERNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setUserName(String username)
|
||||||
|
{
|
||||||
|
set(SecurityConstants.DETAILS_USERNAME, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUserKey()
|
||||||
|
{
|
||||||
|
return get(SecurityConstants.USER_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setUserKey(String userKey)
|
||||||
|
{
|
||||||
|
set(SecurityConstants.USER_KEY, userKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void remove()
|
||||||
|
{
|
||||||
|
THREAD_LOCAL.remove();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.m2pool.common.core.enums;
|
||||||
|
|
||||||
|
public enum LimitType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认策略全局限流
|
||||||
|
*/
|
||||||
|
DEFAULT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据请求者IP进行限流
|
||||||
|
*/
|
||||||
|
IP
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.m2pool.common.core.enums;
|
||||||
|
|
||||||
|
public enum UserRole {
|
||||||
|
ADMIN(1, "admin", "管理员"),
|
||||||
|
REGISTERED(2, "registered", "注册用户"),
|
||||||
|
ADVANCE(3, "advance", "付费用户"),
|
||||||
|
VIP(4, "vip", "vip"),
|
||||||
|
SUPPORT(5, "support", "支持人员"),
|
||||||
|
VERIFIER(6, "verifier", "审核人员"),
|
||||||
|
ACCOUNTTING(7, "accounting", "财务");
|
||||||
|
|
||||||
|
private final int roleId;
|
||||||
|
private final String role;
|
||||||
|
private final String des;
|
||||||
|
|
||||||
|
UserRole(int roleId, String role, String des)
|
||||||
|
{
|
||||||
|
this.roleId = roleId;
|
||||||
|
this.role = role;
|
||||||
|
this.des = des;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRoleId()
|
||||||
|
{
|
||||||
|
return roleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRole()
|
||||||
|
{
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDes(){return des;}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.m2pool.common.core.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户状态
|
||||||
|
* @Date 2024/6/12 14:52
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public enum UserStatus {
|
||||||
|
|
||||||
|
OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String info;
|
||||||
|
|
||||||
|
UserStatus(String code, String info)
|
||||||
|
{
|
||||||
|
this.code = code;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInfo()
|
||||||
|
{
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.m2pool.common.core.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 验证码错误异常类
|
||||||
|
* @Date 2024/6/13 10:51
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class CaptchaException extends RuntimeException{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public CaptchaException(String msg)
|
||||||
|
{
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.m2pool.common.core.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 全局异常
|
||||||
|
* @Date 2024/6/12 14:39
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class GlobalException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误提示
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误明细,内部调试错误
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private String detailMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空构造方法,避免反序列化问题
|
||||||
|
*/
|
||||||
|
public GlobalException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalException(String message)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailMessage()
|
||||||
|
{
|
||||||
|
return detailMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalException setDetailMessage(String detailMessage)
|
||||||
|
{
|
||||||
|
this.detailMessage = detailMessage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage()
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalException setMessage(String message)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.m2pool.common.core.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 内部认证异常
|
||||||
|
* @Date 2024/6/11 18:23
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class InnerAuthException extends RuntimeException{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InnerAuthException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.m2pool.common.core.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 权限异常
|
||||||
|
* @Date 2024/6/11 11:31
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class PreAuthorizeException extends RuntimeException{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public PreAuthorizeException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.m2pool.common.core.exception;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 业务异常
|
||||||
|
* @Date 2024/6/11 16:32
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public final class ServiceException extends RuntimeException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误码
|
||||||
|
*/
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误提示
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误明细,内部调试错误
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private String detailMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空构造方法,避免反序列化问题
|
||||||
|
*/
|
||||||
|
public ServiceException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException(String message)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException(String message, Integer code)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailMessage()
|
||||||
|
{
|
||||||
|
return detailMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage()
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCode()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException setMessage(String message)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException setDetailMessage(String detailMessage)
|
||||||
|
{
|
||||||
|
this.detailMessage = detailMessage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.m2pool.common.core.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 工具类异常
|
||||||
|
* @Date 2024/6/12 11:32
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class UtilException extends RuntimeException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 8247642119125313488L;
|
||||||
|
|
||||||
|
public UtilException(Throwable e)
|
||||||
|
{
|
||||||
|
super(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UtilException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UtilException(String message, Throwable throwable)
|
||||||
|
{
|
||||||
|
super(message, throwable);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.m2pool.common.core.exception.auth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 没有通过的登陆认证异常
|
||||||
|
* @Date 2024/6/12 9:39
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class NotApiKeyException extends RuntimeException{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public NotApiKeyException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.m2pool.common.core.exception.auth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 没有通过的登陆认证异常
|
||||||
|
* @Date 2024/6/12 9:39
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class NotLoginException extends RuntimeException{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public NotLoginException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.m2pool.common.core.exception.auth;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 未能通过的权限认证异常
|
||||||
|
* @Date 2024/6/12 9:45
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class NotPermissionException extends RuntimeException{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public NotPermissionException(String permission)
|
||||||
|
{
|
||||||
|
super(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotPermissionException(String[] permissions)
|
||||||
|
{
|
||||||
|
super(StringUtils.join(permissions, ","));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.m2pool.common.core.exception.auth;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 未能通过的角色认证异常
|
||||||
|
* @Date 2024/6/12 9:48
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class NotRoleException extends RuntimeException{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public NotRoleException(String role)
|
||||||
|
{
|
||||||
|
super(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotRoleException(String[] roles)
|
||||||
|
{
|
||||||
|
super(StringUtils.join(roles, ","));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.m2pool.common.core.exception.base;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 基础异常
|
||||||
|
* @Date 2024/6/12 11:42
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class BaseException extends RuntimeException{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属模块
|
||||||
|
*/
|
||||||
|
private String module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误码
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误码对应的参数
|
||||||
|
*/
|
||||||
|
private Object[] args;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误消息
|
||||||
|
*/
|
||||||
|
private String defaultMessage;
|
||||||
|
|
||||||
|
public BaseException(String module, String code, Object[] args, String defaultMessage)
|
||||||
|
{
|
||||||
|
this.module = module;
|
||||||
|
this.code = code;
|
||||||
|
this.args = args;
|
||||||
|
this.defaultMessage = defaultMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseException(String module, String code, Object[] args)
|
||||||
|
{
|
||||||
|
this(module, code, args, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseException(String module, String defaultMessage)
|
||||||
|
{
|
||||||
|
this(module, null, null, defaultMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseException(String code, Object[] args)
|
||||||
|
{
|
||||||
|
this(null, code, args, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public BaseException(String defaultMessage)
|
||||||
|
{
|
||||||
|
this(null, null, null, defaultMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModule()
|
||||||
|
{
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] getArgs()
|
||||||
|
{
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultMessage()
|
||||||
|
{
|
||||||
|
return defaultMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.m2pool.common.core.exception.file;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.exception.base.BaseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件信息异常类
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
public class FileException extends BaseException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public FileException(String code, Object[] args)
|
||||||
|
{
|
||||||
|
super("file", code, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.m2pool.common.core.exception.file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件名称超长限制异常类
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
public class FileNameLengthLimitExceededException extends FileException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public FileNameLengthLimitExceededException(int defaultFileNameLength)
|
||||||
|
{
|
||||||
|
super("upload.filename.exceed.length", new Object[] { defaultFileNameLength });
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.m2pool.common.core.exception.file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件名大小限制异常类
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
public class FileSizeLimitExceededException extends FileException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public FileSizeLimitExceededException(long defaultMaxSize)
|
||||||
|
{
|
||||||
|
super("文件名超长", new Object[] { defaultMaxSize });
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.m2pool.common.core.exception.file;
|
||||||
|
|
||||||
|
import org.apache.commons.fileupload.FileUploadException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传 误异常类
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
public class InvalidExtensionException extends FileUploadException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String[] allowedExtension;
|
||||||
|
private String extension;
|
||||||
|
private String filename;
|
||||||
|
|
||||||
|
public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
|
||||||
|
{
|
||||||
|
super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
|
||||||
|
this.allowedExtension = allowedExtension;
|
||||||
|
this.extension = extension;
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getAllowedExtension()
|
||||||
|
{
|
||||||
|
return allowedExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExtension()
|
||||||
|
{
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilename()
|
||||||
|
{
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InvalidImageExtensionException extends InvalidExtensionException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
|
||||||
|
{
|
||||||
|
super(allowedExtension, extension, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InvalidFlashExtensionException extends InvalidExtensionException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
|
||||||
|
{
|
||||||
|
super(allowedExtension, extension, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InvalidMediaExtensionException extends InvalidExtensionException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
|
||||||
|
{
|
||||||
|
super(allowedExtension, extension, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InvalidVideoExtensionException extends InvalidExtensionException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
|
||||||
|
{
|
||||||
|
super(allowedExtension, extension, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.m2pool.common.core.exception.pool;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.exception.base.BaseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description pool模块异常类
|
||||||
|
* @Date 2024/6/12 14:05
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class PoolException extends BaseException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public PoolException(String code, Object[] args) {
|
||||||
|
|
||||||
|
super("pool",code, args,null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.m2pool.common.core.exception.user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 验证码失效异常类
|
||||||
|
* @Date 2024/6/11 17:51
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class CaptchaExpireException extends UserException{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public CaptchaExpireException()
|
||||||
|
{
|
||||||
|
super("user.jcaptcha.expire", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.m2pool.common.core.exception.user;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.exception.base.BaseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 用户信息异常类
|
||||||
|
* @Date 2024/6/12 14:05
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class UserException extends BaseException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public UserException(String code, Object[] args) {
|
||||||
|
|
||||||
|
super("user",code, args,null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.m2pool.common.core.text;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.utils.StringUtils;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 字符集工具
|
||||||
|
* @Date 2024/6/11 9:01
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class CharsetKit
|
||||||
|
{
|
||||||
|
/** ISO-8859-1 */
|
||||||
|
public static final String ISO_8859_1 = "ISO-8859-1";
|
||||||
|
/** UTF-8 */
|
||||||
|
public static final String UTF_8 = "UTF-8";
|
||||||
|
/** GBK */
|
||||||
|
public static final String GBK = "GBK";
|
||||||
|
|
||||||
|
/** ISO-8859-1 */
|
||||||
|
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
|
||||||
|
/** UTF-8 */
|
||||||
|
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
|
||||||
|
/** GBK */
|
||||||
|
public static final Charset CHARSET_GBK = Charset.forName(GBK);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Charset对象
|
||||||
|
*
|
||||||
|
* @param charset 字符集,为空则返回默认字符集
|
||||||
|
* @return Charset
|
||||||
|
*/
|
||||||
|
public static Charset charset(String charset)
|
||||||
|
{
|
||||||
|
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换字符串的字符集编码
|
||||||
|
*
|
||||||
|
* @param source 字符串
|
||||||
|
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||||
|
* @param destCharset 目标字符集,默认UTF-8
|
||||||
|
* @return 转换后的字符集
|
||||||
|
*/
|
||||||
|
public static String convert(String source, String srcCharset, String destCharset)
|
||||||
|
{
|
||||||
|
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换字符串的字符集编码
|
||||||
|
*
|
||||||
|
* @param source 字符串
|
||||||
|
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||||
|
* @param destCharset 目标字符集,默认UTF-8
|
||||||
|
* @return 转换后的字符集
|
||||||
|
*/
|
||||||
|
public static String convert(String source, Charset srcCharset, Charset destCharset)
|
||||||
|
{
|
||||||
|
if (null == srcCharset)
|
||||||
|
{
|
||||||
|
srcCharset = StandardCharsets.ISO_8859_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == destCharset)
|
||||||
|
{
|
||||||
|
destCharset = StandardCharsets.UTF_8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
return new String(source.getBytes(srcCharset), destCharset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 系统字符集编码
|
||||||
|
*/
|
||||||
|
public static String systemCharset()
|
||||||
|
{
|
||||||
|
return Charset.defaultCharset().name();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,916 @@
|
||||||
|
package com.m2pool.common.core.text;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.utils.StringUtils;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 类型转换器
|
||||||
|
* @Date 2024/6/11 9:13
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class Convert
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 转换为字符串<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String toStr(Object value, String defaultValue)
|
||||||
|
{
|
||||||
|
if (null == value)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof String)
|
||||||
|
{
|
||||||
|
return (String) value;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为字符串<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String toStr(Object value)
|
||||||
|
{
|
||||||
|
return toStr(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为字符<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Character toChar(Object value, Character defaultValue)
|
||||||
|
{
|
||||||
|
if (null == value)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Character)
|
||||||
|
{
|
||||||
|
return (Character) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为字符<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Character toChar(Object value)
|
||||||
|
{
|
||||||
|
return toChar(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为byte<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Byte toByte(Object value, Byte defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Byte)
|
||||||
|
{
|
||||||
|
return (Byte) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Number)
|
||||||
|
{
|
||||||
|
return ((Number) value).byteValue();
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Byte.parseByte(valueStr);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为byte<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Byte toByte(Object value)
|
||||||
|
{
|
||||||
|
return toByte(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Short<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Short toShort(Object value, Short defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Short)
|
||||||
|
{
|
||||||
|
return (Short) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Number)
|
||||||
|
{
|
||||||
|
return ((Number) value).shortValue();
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Short.parseShort(valueStr.trim());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Short<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Short toShort(Object value)
|
||||||
|
{
|
||||||
|
return toShort(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Number<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Number toNumber(Object value, Number defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Number)
|
||||||
|
{
|
||||||
|
return (Number) value;
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return NumberFormat.getInstance().parse(valueStr);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Number<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Number toNumber(Object value)
|
||||||
|
{
|
||||||
|
return toNumber(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为int<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Integer toInt(Object value, Integer defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Integer)
|
||||||
|
{
|
||||||
|
return (Integer) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Number)
|
||||||
|
{
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Integer.parseInt(valueStr.trim());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为int<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Integer toInt(Object value)
|
||||||
|
{
|
||||||
|
return toInt(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Integer数组<br>
|
||||||
|
*
|
||||||
|
* @param str 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Integer[] toIntArray(String str)
|
||||||
|
{
|
||||||
|
return toIntArray(",", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Long数组<br>
|
||||||
|
*
|
||||||
|
* @param str 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Long[] toLongArray(String str)
|
||||||
|
{
|
||||||
|
return toLongArray(",", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Integer数组<br>
|
||||||
|
*
|
||||||
|
* @param split 分隔符
|
||||||
|
* @param split 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Integer[] toIntArray(String split, String str)
|
||||||
|
{
|
||||||
|
if (StringUtils.isEmpty(str))
|
||||||
|
{
|
||||||
|
return new Integer[] {};
|
||||||
|
}
|
||||||
|
String[] arr = str.split(split);
|
||||||
|
final Integer[] ints = new Integer[arr.length];
|
||||||
|
for (int i = 0; i < arr.length; i++)
|
||||||
|
{
|
||||||
|
final Integer v = toInt(arr[i], 0);
|
||||||
|
ints[i] = v;
|
||||||
|
}
|
||||||
|
return ints;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Long数组<br>
|
||||||
|
*
|
||||||
|
* @param split 分隔符
|
||||||
|
* @param str 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Long[] toLongArray(String split, String str)
|
||||||
|
{
|
||||||
|
if (StringUtils.isEmpty(str))
|
||||||
|
{
|
||||||
|
return new Long[] {};
|
||||||
|
}
|
||||||
|
String[] arr = str.split(split);
|
||||||
|
final Long[] longs = new Long[arr.length];
|
||||||
|
for (int i = 0; i < arr.length; i++)
|
||||||
|
{
|
||||||
|
final Long v = toLong(arr[i], null);
|
||||||
|
longs[i] = v;
|
||||||
|
}
|
||||||
|
return longs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为String数组<br>
|
||||||
|
*
|
||||||
|
* @param str 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String[] toStrArray(String str)
|
||||||
|
{
|
||||||
|
return toStrArray(",", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为String数组<br>
|
||||||
|
*
|
||||||
|
* @param split 分隔符
|
||||||
|
* @param split 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String[] toStrArray(String split, String str)
|
||||||
|
{
|
||||||
|
return str.split(split);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为long<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Long toLong(Object value, Long defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Long)
|
||||||
|
{
|
||||||
|
return (Long) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Number)
|
||||||
|
{
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 支持科学计数法
|
||||||
|
return new BigDecimal(valueStr.trim()).longValue();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为long<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Long toLong(Object value)
|
||||||
|
{
|
||||||
|
return toLong(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为double<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Double toDouble(Object value, Double defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Double)
|
||||||
|
{
|
||||||
|
return (Double) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Number)
|
||||||
|
{
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 支持科学计数法
|
||||||
|
return new BigDecimal(valueStr.trim()).doubleValue();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为double<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Double toDouble(Object value)
|
||||||
|
{
|
||||||
|
return toDouble(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Float<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Float toFloat(Object value, Float defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Float)
|
||||||
|
{
|
||||||
|
return (Float) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Number)
|
||||||
|
{
|
||||||
|
return ((Number) value).floatValue();
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Float.parseFloat(valueStr.trim());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Float<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Float toFloat(Object value)
|
||||||
|
{
|
||||||
|
return toFloat(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为boolean<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Boolean toBool(Object value, Boolean defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Boolean)
|
||||||
|
{
|
||||||
|
return (Boolean) value;
|
||||||
|
}
|
||||||
|
String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
valueStr = valueStr.trim().toLowerCase();
|
||||||
|
switch (valueStr)
|
||||||
|
{
|
||||||
|
case "true":
|
||||||
|
return true;
|
||||||
|
case "false":
|
||||||
|
return false;
|
||||||
|
case "yes":
|
||||||
|
return true;
|
||||||
|
case "ok":
|
||||||
|
return true;
|
||||||
|
case "no":
|
||||||
|
return false;
|
||||||
|
case "1":
|
||||||
|
return true;
|
||||||
|
case "0":
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为boolean<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Boolean toBool(Object value)
|
||||||
|
{
|
||||||
|
return toBool(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为BigInteger<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static BigInteger toBigInteger(Object value, BigInteger defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof BigInteger)
|
||||||
|
{
|
||||||
|
return (BigInteger) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Long)
|
||||||
|
{
|
||||||
|
return BigInteger.valueOf((Long) value);
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new BigInteger(valueStr);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为BigInteger<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static BigInteger toBigInteger(Object value)
|
||||||
|
{
|
||||||
|
return toBigInteger(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为BigDecimal<br>
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof BigDecimal)
|
||||||
|
{
|
||||||
|
return (BigDecimal) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Long)
|
||||||
|
{
|
||||||
|
return new BigDecimal((Long) value);
|
||||||
|
}
|
||||||
|
if (value instanceof Double)
|
||||||
|
{
|
||||||
|
return new BigDecimal((Double) value);
|
||||||
|
}
|
||||||
|
if (value instanceof Integer)
|
||||||
|
{
|
||||||
|
return new BigDecimal((Integer) value);
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (StringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new BigDecimal(valueStr);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为BigDecimal<br>
|
||||||
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
|
* 转换失败不会报错
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static BigDecimal toBigDecimal(Object value)
|
||||||
|
{
|
||||||
|
return toBigDecimal(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将对象转为字符串<br>
|
||||||
|
*
|
||||||
|
* @param obj 对象
|
||||||
|
* @return 字符串
|
||||||
|
*/
|
||||||
|
public static String utf8Str(Object obj)
|
||||||
|
{
|
||||||
|
return str(obj, CharsetKit.CHARSET_UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将对象转为字符串<br>
|
||||||
|
*
|
||||||
|
* @param obj 对象
|
||||||
|
* @param charsetName 字符集
|
||||||
|
* @return 字符串
|
||||||
|
*/
|
||||||
|
public static String str(Object obj, String charsetName)
|
||||||
|
{
|
||||||
|
return str(obj, Charset.forName(charsetName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将对象转为字符串<br>
|
||||||
|
*
|
||||||
|
* @param obj 对象
|
||||||
|
* @param charset 字符集
|
||||||
|
* @return 字符串
|
||||||
|
*/
|
||||||
|
public static String str(Object obj, Charset charset)
|
||||||
|
{
|
||||||
|
if (null == obj)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj instanceof String)
|
||||||
|
{
|
||||||
|
return (String) obj;
|
||||||
|
}
|
||||||
|
else if (obj instanceof byte[] || obj instanceof Byte[])
|
||||||
|
{
|
||||||
|
if (obj instanceof byte[])
|
||||||
|
{
|
||||||
|
return str((byte[]) obj, charset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Byte[] bytes = (Byte[]) obj;
|
||||||
|
int length = bytes.length;
|
||||||
|
byte[] dest = new byte[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
dest[i] = bytes[i];
|
||||||
|
}
|
||||||
|
return str(dest, charset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (obj instanceof ByteBuffer)
|
||||||
|
{
|
||||||
|
return str((ByteBuffer) obj, charset);
|
||||||
|
}
|
||||||
|
return obj.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将byte数组转为字符串
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @param charset 字符集
|
||||||
|
* @return 字符串
|
||||||
|
*/
|
||||||
|
public static String str(byte[] bytes, String charset)
|
||||||
|
{
|
||||||
|
return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解码字节码
|
||||||
|
*
|
||||||
|
* @param data 字符串
|
||||||
|
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
|
||||||
|
* @return 解码后的字符串
|
||||||
|
*/
|
||||||
|
public static String str(byte[] data, Charset charset)
|
||||||
|
{
|
||||||
|
if (data == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == charset)
|
||||||
|
{
|
||||||
|
return new String(data);
|
||||||
|
}
|
||||||
|
return new String(data, charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将编码的byteBuffer数据转换为字符串
|
||||||
|
*
|
||||||
|
* @param data 数据
|
||||||
|
* @param charset 字符集,如果为空使用当前系统字符集
|
||||||
|
* @return 字符串
|
||||||
|
*/
|
||||||
|
public static String str(ByteBuffer data, String charset)
|
||||||
|
{
|
||||||
|
if (data == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str(data, Charset.forName(charset));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将编码的byteBuffer数据转换为字符串
|
||||||
|
*
|
||||||
|
* @param data 数据
|
||||||
|
* @param charset 字符集,如果为空使用当前系统字符集
|
||||||
|
* @return 字符串
|
||||||
|
*/
|
||||||
|
public static String str(ByteBuffer data, Charset charset)
|
||||||
|
{
|
||||||
|
if (null == charset)
|
||||||
|
{
|
||||||
|
charset = Charset.defaultCharset();
|
||||||
|
}
|
||||||
|
return charset.decode(data).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- 全角半角转换
|
||||||
|
/**
|
||||||
|
* 半角转全角
|
||||||
|
*
|
||||||
|
* @param input String.
|
||||||
|
* @return 全角字符串.
|
||||||
|
*/
|
||||||
|
public static String toSBC(String input)
|
||||||
|
{
|
||||||
|
return toSBC(input, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 半角转全角
|
||||||
|
*
|
||||||
|
* @param input String
|
||||||
|
* @param notConvertSet 不替换的字符集合
|
||||||
|
* @return 全角字符串.
|
||||||
|
*/
|
||||||
|
public static String toSBC(String input, Set<Character> notConvertSet)
|
||||||
|
{
|
||||||
|
char c[] = input.toCharArray();
|
||||||
|
for (int i = 0; i < c.length; i++)
|
||||||
|
{
|
||||||
|
if (null != notConvertSet && notConvertSet.contains(c[i]))
|
||||||
|
{
|
||||||
|
// 跳过不替换的字符
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c[i] == ' ')
|
||||||
|
{
|
||||||
|
c[i] = '\u3000';
|
||||||
|
}
|
||||||
|
else if (c[i] < '\177')
|
||||||
|
{
|
||||||
|
c[i] = (char) (c[i] + 65248);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new String(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全角转半角
|
||||||
|
*
|
||||||
|
* @param input String.
|
||||||
|
* @return 半角字符串
|
||||||
|
*/
|
||||||
|
public static String toDBC(String input)
|
||||||
|
{
|
||||||
|
return toDBC(input, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换全角为半角
|
||||||
|
*
|
||||||
|
* @param text 文本
|
||||||
|
* @param notConvertSet 不替换的字符集合
|
||||||
|
* @return 替换后的字符
|
||||||
|
*/
|
||||||
|
public static String toDBC(String text, Set<Character> notConvertSet)
|
||||||
|
{
|
||||||
|
char c[] = text.toCharArray();
|
||||||
|
for (int i = 0; i < c.length; i++)
|
||||||
|
{
|
||||||
|
if (null != notConvertSet && notConvertSet.contains(c[i]))
|
||||||
|
{
|
||||||
|
// 跳过不替换的字符
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c[i] == '\u3000')
|
||||||
|
{
|
||||||
|
c[i] = ' ';
|
||||||
|
}
|
||||||
|
else if (c[i] > '\uFF00' && c[i] < '\uFF5F')
|
||||||
|
{
|
||||||
|
c[i] = (char) (c[i] - 65248);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String returnString = new String(c);
|
||||||
|
|
||||||
|
return returnString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数字金额大写转换 先写个完整的然后将如零拾替换成零
|
||||||
|
*
|
||||||
|
* @param n 数字
|
||||||
|
* @return 中文大写数字
|
||||||
|
*/
|
||||||
|
public static String digitUppercase(double n)
|
||||||
|
{
|
||||||
|
String[] fraction = { "角", "分" };
|
||||||
|
String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
|
||||||
|
String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } };
|
||||||
|
|
||||||
|
String head = n < 0 ? "负" : "";
|
||||||
|
n = Math.abs(n);
|
||||||
|
|
||||||
|
String s = "";
|
||||||
|
for (int i = 0; i < fraction.length; i++)
|
||||||
|
{
|
||||||
|
s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
|
||||||
|
}
|
||||||
|
if (s.length() < 1)
|
||||||
|
{
|
||||||
|
s = "整";
|
||||||
|
}
|
||||||
|
int integerPart = (int) Math.floor(n);
|
||||||
|
|
||||||
|
for (int i = 0; i < unit[0].length && integerPart > 0; i++)
|
||||||
|
{
|
||||||
|
String p = "";
|
||||||
|
for (int j = 0; j < unit[1].length && n > 0; j++)
|
||||||
|
{
|
||||||
|
p = digit[integerPart % 10] + unit[1][j] + p;
|
||||||
|
integerPart = integerPart / 10;
|
||||||
|
}
|
||||||
|
s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
|
||||||
|
}
|
||||||
|
return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
package com.m2pool.common.core.text;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 浮点数计算
|
||||||
|
* @Date 2024/6/12 15:46
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class DoubleCalculate {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 除法 v1除v2 默认保留一位小数 四舍五入
|
||||||
|
* @param v1
|
||||||
|
* @param v2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double divide(double v1, double v2) {
|
||||||
|
|
||||||
|
return divide(v1,v2,1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 除法 v1除v2 默认保留一位小数 向上取整
|
||||||
|
* @param v1
|
||||||
|
* @param v2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double divideCEILING(double v1, double v2) {
|
||||||
|
|
||||||
|
return divideCEILING(v1,v2,1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 除法 v1除v2 默认保留一位小数 向下取整
|
||||||
|
* @param v1
|
||||||
|
* @param v2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double divideFLOOR(double v1, double v2) {
|
||||||
|
|
||||||
|
return divideFLOOR(v1,v2,1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 除法 v1除v2 向上取整
|
||||||
|
* @param v1
|
||||||
|
* @param v2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double divideCEILING(double v1, double v2,int scale) {
|
||||||
|
|
||||||
|
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||||
|
|
||||||
|
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||||
|
|
||||||
|
//scale表示保留几位小数 ROUND_CEILING向上取整
|
||||||
|
return b1.divide(b2,scale, BigDecimal.ROUND_CEILING).doubleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 除法 v1除v2 向下取整
|
||||||
|
* @param v1
|
||||||
|
* @param v2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double divideFLOOR(double v1, double v2,int scale) {
|
||||||
|
|
||||||
|
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||||
|
|
||||||
|
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||||
|
|
||||||
|
//scale表示保留几位小数 ROUND_FLOOR
|
||||||
|
return b1.divide(b2,scale, BigDecimal.ROUND_FLOOR).doubleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 除法 v1除v2 四舍五入
|
||||||
|
* @param v1
|
||||||
|
* @param v2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double divide(double v1, double v2,int scale) {
|
||||||
|
|
||||||
|
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||||
|
|
||||||
|
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||||
|
|
||||||
|
//scale表示保留几位小数 ROUND_HALF_UP四舍五入
|
||||||
|
return b1.divide(b2,scale, BigDecimal.ROUND_HALF_UP).doubleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v1-v2
|
||||||
|
* @param v1
|
||||||
|
* @param v2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double subtract(double v1, double v2) {
|
||||||
|
|
||||||
|
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||||
|
|
||||||
|
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||||
|
|
||||||
|
return b1.subtract(b2).doubleValue();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v1 + v2
|
||||||
|
* @param v1
|
||||||
|
* @param v2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double add(double v1, double v2) {
|
||||||
|
|
||||||
|
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||||
|
|
||||||
|
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||||
|
|
||||||
|
return b1.add(b2).doubleValue();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v1*v2
|
||||||
|
* @param v1
|
||||||
|
* @param v2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double multiply(double v1, double v2) {
|
||||||
|
|
||||||
|
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||||
|
|
||||||
|
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||||
|
|
||||||
|
return b1.multiply(b2).doubleValue();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.m2pool.common.core.text;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.utils.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 字符串格式化
|
||||||
|
* @Date 2024/6/13 9:52
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class StrFormatter
|
||||||
|
{
|
||||||
|
public static final String EMPTY_JSON = "{}";
|
||||||
|
public static final char C_BACKSLASH = '\\';
|
||||||
|
public static final char C_DELIM_START = '{';
|
||||||
|
public static final char C_DELIM_END = '}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化字符串<br>
|
||||||
|
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
||||||
|
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
|
||||||
|
* 例:<br>
|
||||||
|
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
|
||||||
|
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
|
||||||
|
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
|
||||||
|
*
|
||||||
|
* @param strPattern 字符串模板
|
||||||
|
* @param argArray 参数列表
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String format(final String strPattern, final Object... argArray)
|
||||||
|
{
|
||||||
|
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
|
||||||
|
{
|
||||||
|
return strPattern;
|
||||||
|
}
|
||||||
|
final int strPatternLength = strPattern.length();
|
||||||
|
|
||||||
|
// 初始化定义好的长度以获得更好的性能
|
||||||
|
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
|
||||||
|
|
||||||
|
int handledPosition = 0;
|
||||||
|
int delimIndex;// 占位符所在位置
|
||||||
|
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
|
||||||
|
{
|
||||||
|
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
|
||||||
|
if (delimIndex == -1)
|
||||||
|
{
|
||||||
|
if (handledPosition == 0)
|
||||||
|
{
|
||||||
|
return strPattern;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
|
||||||
|
sbuf.append(strPattern, handledPosition, strPatternLength);
|
||||||
|
return sbuf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
|
||||||
|
{
|
||||||
|
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
|
||||||
|
{
|
||||||
|
// 转义符之前还有一个转义符,占位符依旧有效
|
||||||
|
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||||
|
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||||
|
handledPosition = delimIndex + 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 占位符被转义
|
||||||
|
argIndex--;
|
||||||
|
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||||
|
sbuf.append(C_DELIM_START);
|
||||||
|
handledPosition = delimIndex + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 正常占位符
|
||||||
|
sbuf.append(strPattern, handledPosition, delimIndex);
|
||||||
|
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||||
|
handledPosition = delimIndex + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 加入最后一个占位符后所有的字符
|
||||||
|
sbuf.append(strPattern, handledPosition, strPattern.length());
|
||||||
|
|
||||||
|
return sbuf.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
//package com.m2pool.common.core.utils;
|
||||||
|
//
|
||||||
|
//import java.util.regex.Matcher;
|
||||||
|
//import java.util.regex.Pattern;
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * @Description TODO
|
||||||
|
// * @Date 2024/6/14 11:47
|
||||||
|
// * @Author dy
|
||||||
|
// */
|
||||||
|
//public class CheckMobile {
|
||||||
|
//
|
||||||
|
// // \b 是单词边界(连着的两个(字母字符 与 非字母字符) 之间的逻辑上的间隔),
|
||||||
|
// // 字符串在编译时会被转码一次,所以是 "\\b"
|
||||||
|
// // \B 是单词内部逻辑间隔(连着的两个字母字符之间的逻辑上的间隔)
|
||||||
|
// static String phoneReg = "\\b(ip(hone|od)|android|opera m(ob|in)i"
|
||||||
|
// +"|windows (phone|ce)|blackberry"
|
||||||
|
// +"|s(ymbian|eries60|amsung)|p(laybook|alm|rofile/midp"
|
||||||
|
// +"|laystation portable)|nokia|fennec|htc[-_]"
|
||||||
|
// +"|mobile|up.browser|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";
|
||||||
|
// static String tableReg = "\\b(ipad|tablet|(Nexus 7)|up.browser"
|
||||||
|
// +"|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";
|
||||||
|
//
|
||||||
|
// //移动设备正则匹配:手机端、平板
|
||||||
|
// static Pattern phonePat = Pattern.compile(phoneReg, Pattern.CASE_INSENSITIVE);
|
||||||
|
// static Pattern tablePat = Pattern.compile(tableReg, Pattern.CASE_INSENSITIVE);
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @Description 检测是否是移动设备访问
|
||||||
|
// * @param userAgent 浏览器标识
|
||||||
|
// * @return true:pc端接入,false:移动设备接入
|
||||||
|
// */
|
||||||
|
// public static boolean isPC(String userAgent){
|
||||||
|
// if(null == userAgent){
|
||||||
|
// userAgent = "";
|
||||||
|
// }
|
||||||
|
// // 匹配
|
||||||
|
// Matcher matcherPhone = phonePat.matcher(userAgent);
|
||||||
|
// Matcher matcherTable = tablePat.matcher(userAgent);
|
||||||
|
// if(matcherPhone.find() || matcherTable.find()){
|
||||||
|
// return false;
|
||||||
|
// } else {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description TODO
|
||||||
|
* @Date 2024/6/13 14:26
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class CodeUtils {
|
||||||
|
//public static void main(String[] args) {
|
||||||
|
// String s = creatCode(4);
|
||||||
|
// //System.out.println("随机验证码为:" + s);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//定义一个方法返回一个随机验证码
|
||||||
|
public static String creatCode(int n) {
|
||||||
|
|
||||||
|
String code = "";
|
||||||
|
Random r = new Random();
|
||||||
|
//2.在方法内部使用for循环生成指定位数的随机字符,并连接起来
|
||||||
|
for (int i = 0; i <= n; i++) {
|
||||||
|
//生成一个随机字符:大写 ,小写 ,数字(0 1 2)
|
||||||
|
int type = r.nextInt(3);
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
char ch = (char) (r.nextInt(26) + 65);
|
||||||
|
code += ch;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
char ch1 = (char) (r.nextInt(26) + 97);
|
||||||
|
code += ch1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
code += r.nextInt(10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,323 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.*;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 时间工具类
|
||||||
|
* @Date 2024/6/13 11:21
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
||||||
|
{
|
||||||
|
public static String YYYY = "yyyy";
|
||||||
|
|
||||||
|
public static String YYYY_MM = "yyyy-MM";
|
||||||
|
|
||||||
|
public static String YYYY_MM_DD = "yyyy-MM-dd";
|
||||||
|
|
||||||
|
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
|
||||||
|
|
||||||
|
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
private static String[] parsePatterns = {
|
||||||
|
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
|
||||||
|
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
|
||||||
|
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前Date型日期
|
||||||
|
*
|
||||||
|
* @return Date() 当前日期
|
||||||
|
*/
|
||||||
|
public static Date getNowDate()
|
||||||
|
{
|
||||||
|
return new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前日期, 默认格式为yyyy-MM-dd
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public static String getDate()
|
||||||
|
{
|
||||||
|
return dateTimeNow(YYYY_MM_DD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String getTime()
|
||||||
|
{
|
||||||
|
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String dateTimeNow()
|
||||||
|
{
|
||||||
|
return dateTimeNow(YYYYMMDDHHMMSS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String dateTimeNow(final String format)
|
||||||
|
{
|
||||||
|
return parseDateToStr(format, new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String dateTime(final Date date)
|
||||||
|
{
|
||||||
|
return parseDateToStr(YYYY_MM_DD, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String parseDateToStr(final String format, final Date date)
|
||||||
|
{
|
||||||
|
return new SimpleDateFormat(format).format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Date dateTime(final String format, final String ts)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new SimpleDateFormat(format).parse(ts);
|
||||||
|
}
|
||||||
|
catch (ParseException e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期路径 即年/月/日 如2018/08/08
|
||||||
|
*/
|
||||||
|
public static final String datePath()
|
||||||
|
{
|
||||||
|
Date now = new Date();
|
||||||
|
return DateFormatUtils.format(now, "yyyy/MM/dd");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期路径 即年/月/日 如20180808
|
||||||
|
*/
|
||||||
|
public static final String dateTime()
|
||||||
|
{
|
||||||
|
Date now = new Date();
|
||||||
|
return DateFormatUtils.format(now, "yyyyMMdd");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期型字符串转化为日期 格式
|
||||||
|
*/
|
||||||
|
public static Date parseDate(Object str)
|
||||||
|
{
|
||||||
|
if (str == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return parseDate(str.toString(), parsePatterns);
|
||||||
|
}
|
||||||
|
catch (ParseException e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期型字符串转化为日期 格式
|
||||||
|
*/
|
||||||
|
public static Date parseCNDate(Object str)
|
||||||
|
{
|
||||||
|
if (str == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Date date = parseDate(str.toString(), parsePatterns);
|
||||||
|
return UTCToCNDate(date);
|
||||||
|
}
|
||||||
|
catch (ParseException e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取服务器启动时间
|
||||||
|
*/
|
||||||
|
public static Date getServerStartDate()
|
||||||
|
{
|
||||||
|
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
|
||||||
|
return new Date(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算两个时间差
|
||||||
|
*/
|
||||||
|
public static String getDatePoor(Date endDate, Date nowDate)
|
||||||
|
{
|
||||||
|
long nd = 1000 * 24 * 60 * 60;
|
||||||
|
long nh = 1000 * 60 * 60;
|
||||||
|
long nm = 1000 * 60;
|
||||||
|
// long ns = 1000;
|
||||||
|
// 获得两个时间的毫秒时间差异
|
||||||
|
long diff = endDate.getTime() - nowDate.getTime();
|
||||||
|
// 计算差多少天
|
||||||
|
long day = diff / nd;
|
||||||
|
// 计算差多少小时
|
||||||
|
long hour = diff % nd / nh;
|
||||||
|
// 计算差多少分钟
|
||||||
|
long min = diff % nd % nh / nm;
|
||||||
|
// 计算差多少秒//输出结果
|
||||||
|
// long sec = diff % nd % nh % nm / ns;
|
||||||
|
return day + "天" + hour + "小时" + min + "分钟";
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 计算两个时间差 天数
|
||||||
|
*/
|
||||||
|
public static Long getDateDiff(Date endDate, Date nowDate)
|
||||||
|
{
|
||||||
|
long nd = 1000 * 24 * 60 * 60;
|
||||||
|
long nh = 1000 * 60 * 60;
|
||||||
|
long nm = 1000 * 60;
|
||||||
|
// long ns = 1000;
|
||||||
|
// 获得两个时间的毫秒时间差异
|
||||||
|
long diff = endDate.getTime() - nowDate.getTime();
|
||||||
|
// 计算差多少天
|
||||||
|
long day = diff / nd;
|
||||||
|
return day;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long getDateDiffSecond(Date endDate, Date nowDate)
|
||||||
|
{
|
||||||
|
long nd = 1000 * 24 * 60 * 60;
|
||||||
|
long nh = 1000 * 60 * 60;
|
||||||
|
long nm = 1000 * 60;
|
||||||
|
long ns = 1000;
|
||||||
|
// 获得两个时间的毫秒时间差异
|
||||||
|
long diff = endDate.getTime() - nowDate.getTime();
|
||||||
|
// 计算差多少秒
|
||||||
|
long sec = diff % nd % nh % nm / ns;
|
||||||
|
return sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long getDateDiffMinute(Date endDate, Date preDate)
|
||||||
|
{
|
||||||
|
long nd = 1000 * 24 * 60 * 60;
|
||||||
|
long nh = 1000 * 60 * 60;
|
||||||
|
long nm = 1000 * 60;
|
||||||
|
long ns = 1000;
|
||||||
|
// 获得两个时间的毫秒时间差异
|
||||||
|
long diff = endDate.getTime() - preDate.getTime();
|
||||||
|
// 计算差多少秒
|
||||||
|
long minute = diff / nm;
|
||||||
|
return minute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算两个时间差 按月
|
||||||
|
*/
|
||||||
|
public static int getMonthDiff(Date d1, Date d2) {
|
||||||
|
Calendar c1 = Calendar.getInstance();
|
||||||
|
Calendar c2 = Calendar.getInstance();
|
||||||
|
c1.setTime(d1);
|
||||||
|
c2.setTime(d2);
|
||||||
|
int year1 = c1.get(Calendar.YEAR);
|
||||||
|
int year2 = c2.get(Calendar.YEAR);
|
||||||
|
int month1 = c1.get(Calendar.MONTH);
|
||||||
|
int month2 = c2.get(Calendar.MONTH);
|
||||||
|
int day1 = c1.get(Calendar.DAY_OF_MONTH);
|
||||||
|
int day2 = c2.get(Calendar.DAY_OF_MONTH);
|
||||||
|
// 获取年的差值
|
||||||
|
int yearInterval = year1 - year2;
|
||||||
|
// 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
|
||||||
|
if (month1 < month2 || month1 == month2 && day1 < day2) {
|
||||||
|
yearInterval--;
|
||||||
|
}
|
||||||
|
// 获取月数差值
|
||||||
|
int monthInterval = (month1 + 12) - month2;
|
||||||
|
if (day1 < day2) {
|
||||||
|
monthInterval--;
|
||||||
|
}
|
||||||
|
monthInterval %= 12;
|
||||||
|
int monthsDiff = Math.abs(yearInterval * 12 + monthInterval);
|
||||||
|
return monthsDiff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增加 LocalDateTime ==> Date
|
||||||
|
*/
|
||||||
|
public static Date toDate(LocalDateTime temporalAccessor)
|
||||||
|
{
|
||||||
|
ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
|
||||||
|
return Date.from(zdt.toInstant());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增加 LocalDate ==> Date
|
||||||
|
*/
|
||||||
|
public static Date toDate(LocalDate temporalAccessor)
|
||||||
|
{
|
||||||
|
LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
|
||||||
|
ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
|
||||||
|
return Date.from(zdt.toInstant());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LocalDate toLocalDate(Date date)
|
||||||
|
{
|
||||||
|
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||||
|
return localDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LocalDateTime toLocalDateTime(Date date)
|
||||||
|
{
|
||||||
|
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
|
return localDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSameDay(final Date d1,final Date d2){
|
||||||
|
String s1 = dateTime(d1);
|
||||||
|
String s2 = dateTime(d2);
|
||||||
|
|
||||||
|
if (s1 == null || s2 == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s1.equals(s2)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSameDate(final Date d1,final Date d2){
|
||||||
|
|
||||||
|
String s1 = parseDateToStr(YYYY_MM_DD_HH_MM_SS,d1);
|
||||||
|
String s2 = parseDateToStr(YYYY_MM_DD_HH_MM_SS,d2);
|
||||||
|
|
||||||
|
if (s1 == null || s2 == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s1.equals(s2)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Date UTCToCNDate(Date date)
|
||||||
|
{
|
||||||
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
// 设置时区为北京
|
||||||
|
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
|
||||||
|
|
||||||
|
String format = simpleDateFormat.format(date);
|
||||||
|
|
||||||
|
return DateUtils.parseDate(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 错误信息处理类
|
||||||
|
* @Date 2024/6/12 14:06
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class ExceptionUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取exception的详细错误信息。
|
||||||
|
*/
|
||||||
|
public static String getExceptionMessage(Throwable e)
|
||||||
|
{
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
e.printStackTrace(new PrintWriter(sw, true));
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getRootErrorMessage(Exception e)
|
||||||
|
{
|
||||||
|
Throwable root = ExceptionUtils.getRootCause(e);
|
||||||
|
root = (root == null ? e : root);
|
||||||
|
if (root == null)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String msg = root.getMessage();
|
||||||
|
if (msg == null)
|
||||||
|
{
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
return StringUtils.defaultString(msg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,282 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.exception.file.FileNameLengthLimitExceededException;
|
||||||
|
import com.m2pool.common.core.exception.file.FileSizeLimitExceededException;
|
||||||
|
import com.m2pool.common.core.exception.file.InvalidExtensionException;
|
||||||
|
import com.m2pool.common.core.utils.file.MimeTypeUtils;
|
||||||
|
import com.m2pool.common.core.utils.uuid.Seq;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传工具类
|
||||||
|
*
|
||||||
|
* @author dy
|
||||||
|
*/
|
||||||
|
public class FileUploadUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 默认大小 200M
|
||||||
|
*/
|
||||||
|
public static final long DEFAULT_MAX_SIZE = 10 * 1024 * 1024;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认的文件名最大长度 100
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_FILE_NAME_LENGTH = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统工具大小 200M
|
||||||
|
*/
|
||||||
|
public static final long TOOLS_MAX_SIZE = 200 * 1024 * 1024;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统工具的文件名最大长度 100
|
||||||
|
*/
|
||||||
|
public static final int TOOLS_NAME_LENGTH = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件路径上传
|
||||||
|
*
|
||||||
|
* @param baseDir 相对应用的基目录
|
||||||
|
* @param file 上传的文件
|
||||||
|
* @return 文件名称
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static final String upload(String baseDir, MultipartFile file) throws IOException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new IOException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
*
|
||||||
|
* @param baseDir 相对应用的基目录
|
||||||
|
* @param file 上传的文件
|
||||||
|
* @param allowedExtension 上传文件类型
|
||||||
|
* @return 返回上传成功的文件名
|
||||||
|
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||||
|
* @throws FileNameLengthLimitExceededException 文件名太长
|
||||||
|
* @throws IOException 比如读写文件出错时
|
||||||
|
* @throws InvalidExtensionException 文件校验异常
|
||||||
|
*/
|
||||||
|
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
|
||||||
|
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
|
||||||
|
InvalidExtensionException
|
||||||
|
{
|
||||||
|
int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
|
||||||
|
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
|
||||||
|
{
|
||||||
|
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertAllowed(file, allowedExtension);
|
||||||
|
|
||||||
|
String fileName = extractFilename(file);
|
||||||
|
|
||||||
|
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
|
||||||
|
file.transferTo(Paths.get(absPath));
|
||||||
|
return getPathFileName(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
///**
|
||||||
|
// * 系统工具文件上传
|
||||||
|
// *
|
||||||
|
// * @param baseDir 相对应用的基目录
|
||||||
|
// * @param file 上传的文件
|
||||||
|
// * @param allowedExtension 上传文件类型
|
||||||
|
// * @return 返回上传成功的文件名
|
||||||
|
// * @throws FileSizeLimitExceededException 如果超出最大大小
|
||||||
|
// * @throws FileNameLengthLimitExceededException 文件名太长
|
||||||
|
// * @throws IOException 比如读写文件出错时
|
||||||
|
// * @throws InvalidExtensionException 文件校验异常
|
||||||
|
// */
|
||||||
|
//public static final String toolsUpload(String baseDir, MultipartFile file, String fileName, String[] allowedExtension)
|
||||||
|
// throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
|
||||||
|
// InvalidExtensionException
|
||||||
|
//{
|
||||||
|
// int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
|
||||||
|
// if (fileNamelength > FileUploadUtils.TOOLS_NAME_LENGTH)
|
||||||
|
// {
|
||||||
|
// throw new FileNameLengthLimitExceededException(FileUploadUtils.TOOLS_NAME_LENGTH);
|
||||||
|
// }
|
||||||
|
// System.out.println("toolsAssertAllowed调用");
|
||||||
|
// toolsAssertAllowed(file, allowedExtension);
|
||||||
|
// System.out.println("toolsAssertAllowed调用结束");
|
||||||
|
// String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
|
||||||
|
// System.out.println("absPath|"+absPath);
|
||||||
|
// file.transferTo(Paths.get(absPath));
|
||||||
|
// return getPathFileName(fileName);
|
||||||
|
//}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编码文件名
|
||||||
|
*/
|
||||||
|
public static final String extractFilename(MultipartFile file)
|
||||||
|
{
|
||||||
|
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
|
||||||
|
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
|
||||||
|
{
|
||||||
|
File desc = new File(uploadDir + File.separator + fileName);
|
||||||
|
|
||||||
|
if (!desc.exists())
|
||||||
|
{
|
||||||
|
if (!desc.getParentFile().exists())
|
||||||
|
{
|
||||||
|
desc.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return desc.isAbsolute() ? desc : desc.getAbsoluteFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String getPathFileName(String fileName) throws IOException
|
||||||
|
{
|
||||||
|
String pathFileName = "/" + fileName;
|
||||||
|
return pathFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件大小校验
|
||||||
|
*
|
||||||
|
* @param file 上传的文件
|
||||||
|
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||||
|
* @throws InvalidExtensionException 文件校验异常
|
||||||
|
*/
|
||||||
|
public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
|
||||||
|
throws FileSizeLimitExceededException, InvalidExtensionException
|
||||||
|
{
|
||||||
|
long size = file.getSize();
|
||||||
|
if (size > DEFAULT_MAX_SIZE)
|
||||||
|
{
|
||||||
|
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileName = file.getOriginalFilename();
|
||||||
|
String extension = getExtension(file);
|
||||||
|
if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
|
||||||
|
{
|
||||||
|
if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
|
||||||
|
{
|
||||||
|
throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
|
||||||
|
fileName);
|
||||||
|
}
|
||||||
|
else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
|
||||||
|
{
|
||||||
|
throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
|
||||||
|
fileName);
|
||||||
|
}
|
||||||
|
else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
|
||||||
|
{
|
||||||
|
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
|
||||||
|
fileName);
|
||||||
|
}
|
||||||
|
else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
|
||||||
|
{
|
||||||
|
throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
|
||||||
|
fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidExtensionException(allowedExtension, extension, fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///**
|
||||||
|
// * tools文件大小校验
|
||||||
|
// *
|
||||||
|
// * @param file 上传的文件
|
||||||
|
// * @throws FileSizeLimitExceededException 如果超出最大大小
|
||||||
|
// * @throws InvalidExtensionException 文件校验异常
|
||||||
|
// */
|
||||||
|
//public static final void toolsAssertAllowed(MultipartFile file, String[] allowedExtension)
|
||||||
|
// throws FileSizeLimitExceededException, InvalidExtensionException
|
||||||
|
//{
|
||||||
|
// long size = file.getSize();
|
||||||
|
// if (size > TOOLS_MAX_SIZE)
|
||||||
|
// {
|
||||||
|
// throw new FileSizeLimitExceededException(TOOLS_MAX_SIZE / 1024 / 1024);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// String fileName = file.getOriginalFilename();
|
||||||
|
// String extension = getExtension(file);
|
||||||
|
// if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
|
||||||
|
// {
|
||||||
|
// if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
|
||||||
|
// {
|
||||||
|
// throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
|
||||||
|
// fileName);
|
||||||
|
// }
|
||||||
|
// else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
|
||||||
|
// {
|
||||||
|
// throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
|
||||||
|
// fileName);
|
||||||
|
// }
|
||||||
|
// else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
|
||||||
|
// {
|
||||||
|
// throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
|
||||||
|
// fileName);
|
||||||
|
// }
|
||||||
|
// else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
|
||||||
|
// {
|
||||||
|
// throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
|
||||||
|
// fileName);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// throw new InvalidExtensionException(allowedExtension, extension, fileName);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断MIME类型是否是允许的MIME类型
|
||||||
|
*
|
||||||
|
* @param extension 上传文件类型
|
||||||
|
* @param allowedExtension 允许上传文件类型
|
||||||
|
* @return true/false
|
||||||
|
*/
|
||||||
|
public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
|
||||||
|
{
|
||||||
|
for (String str : allowedExtension)
|
||||||
|
{
|
||||||
|
if (str.equalsIgnoreCase(extension))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件名的后缀
|
||||||
|
*
|
||||||
|
* @param file 表单文件
|
||||||
|
* @return 后缀名
|
||||||
|
*/
|
||||||
|
public static final String getExtension(MultipartFile file)
|
||||||
|
{
|
||||||
|
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
|
||||||
|
if (StringUtils.isEmpty(extension))
|
||||||
|
{
|
||||||
|
extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
|
||||||
|
}
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base32;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 谷歌身份验证器工具类
|
||||||
|
* @Date 2024/8/21 10:14
|
||||||
|
* @Author 杜懿
|
||||||
|
*/
|
||||||
|
public class GoogleAuthenticator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间前后偏移量
|
||||||
|
* 用于防止客户端时间不精确导致生成的TOTP与服务器端的TOTP一直不一致
|
||||||
|
* 如果为0,当前时间为 10:10:15
|
||||||
|
* 则表明在 10:10:00-10:10:30 之间生成的TOTP 能校验通过
|
||||||
|
* 如果为1,则表明在
|
||||||
|
* 10:09:30-10:10:00
|
||||||
|
* 10:10:00-10:10:30
|
||||||
|
* 10:10:30-10:11:00 之间生成的TOTP 能校验通过
|
||||||
|
* 以此类推
|
||||||
|
*/
|
||||||
|
private static int WINDOW_SIZE = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密方式,HmacSHA1、HmacSHA256、HmacSHA512
|
||||||
|
*/
|
||||||
|
private static final String CRYPTO = "HmacSHA1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成密钥,每个用户独享一份密钥
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getSecretKey() {
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
// byte[] bytes = new byte[20];
|
||||||
|
byte[] bytes = new byte[10];
|
||||||
|
random.nextBytes(bytes);
|
||||||
|
Base32 base32 = new Base32();
|
||||||
|
String secretKey = base32.encodeToString(bytes);
|
||||||
|
// make the secret key more human-readable by lower-casing and
|
||||||
|
// inserting spaces between each group of 4 characters
|
||||||
|
return secretKey.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成二维码内容
|
||||||
|
* @param secretKey 密钥
|
||||||
|
* @param account 账户名
|
||||||
|
* @param issuer 网站地址(可不写)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getQrCodeText(String secretKey, String account, String issuer) {
|
||||||
|
String normalizedBase32Key = secretKey.replace(" ", "").toUpperCase();
|
||||||
|
try {
|
||||||
|
return "otpauth://totp/"
|
||||||
|
+ URLEncoder.encode((!StringUtils.isEmpty(issuer) ? (issuer + ":") : "") + account, "UTF-8").replace("+", "%20")
|
||||||
|
+ "?secret=" + URLEncoder.encode(normalizedBase32Key, "UTF-8").replace("+", "%20")
|
||||||
|
+ (!StringUtils.isEmpty(issuer) ? ("&issuer=" + URLEncoder.encode(issuer, "UTF-8").replace("+", "%20")) : "");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取验证码
|
||||||
|
* @param secretKey
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getCode(String secretKey) {
|
||||||
|
String normalizedBase32Key = secretKey.replace(" ", "").toUpperCase();
|
||||||
|
Base32 base32 = new Base32();
|
||||||
|
byte[] bytes = base32.decode(normalizedBase32Key);
|
||||||
|
String hexKey = Hex.encodeHexString(bytes);
|
||||||
|
long time = (System.currentTimeMillis() / 1000) / 30;
|
||||||
|
String hexTime = Long.toHexString(time);
|
||||||
|
return TOTP.generateTOTP(hexKey, hexTime, "6", CRYPTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检验 code 是否正确
|
||||||
|
* @param secret 密钥
|
||||||
|
* @param code code
|
||||||
|
* @param time 时间戳
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean checkCode(String secret, long code, long time) {
|
||||||
|
Base32 codec = new Base32();
|
||||||
|
byte[] decodedKey = codec.decode(secret);
|
||||||
|
// convert unix msec time into a 30 second "window"
|
||||||
|
// this is per the TOTP spec (see the RFC for details)
|
||||||
|
long t = (time / 1000L) / 30L;
|
||||||
|
// Window is used to check codes generated in the near past.
|
||||||
|
// You can use this value to tune how far you're willing to go.
|
||||||
|
long hash;
|
||||||
|
for (int i = -WINDOW_SIZE; i <= WINDOW_SIZE; ++i) {
|
||||||
|
try {
|
||||||
|
hash = verifyCode(decodedKey, t + i);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Yes, this is bad form - but
|
||||||
|
// the exceptions thrown would be rare and a static
|
||||||
|
// configuration problem
|
||||||
|
// e.printStackTrace();
|
||||||
|
|
||||||
|
// throw new RuntimeException(e.getMessage());
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (hash == code) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据时间偏移量计算
|
||||||
|
* @param key
|
||||||
|
* @param t
|
||||||
|
* @return
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
* @throws java.security.InvalidKeyException
|
||||||
|
*/
|
||||||
|
private static long verifyCode(byte[] key, long t) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
|
byte[] data = new byte[8];
|
||||||
|
long value = t;
|
||||||
|
for (int i = 8; i-- > 0; value >>>= 8) {
|
||||||
|
data[i] = (byte) value;
|
||||||
|
}
|
||||||
|
SecretKeySpec signKey = new SecretKeySpec(key, CRYPTO);
|
||||||
|
Mac mac = Mac.getInstance(CRYPTO);
|
||||||
|
mac.init(signKey);
|
||||||
|
byte[] hash = mac.doFinal(data);
|
||||||
|
int offset = hash[20 - 1] & 0xF;
|
||||||
|
// We're using a long because Java hasn't got unsigned int.
|
||||||
|
long truncatedHash = 0;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
truncatedHash <<= 8;
|
||||||
|
// We are dealing with signed bytes:
|
||||||
|
// we just keep the first byte.
|
||||||
|
truncatedHash |= (hash[offset + i] & 0xFF);
|
||||||
|
}
|
||||||
|
truncatedHash &= 0x7FFFFFFF;
|
||||||
|
truncatedHash %= 1000000;
|
||||||
|
return truncatedHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.constant.SecurityConstants;
|
||||||
|
import com.m2pool.common.core.constant.TokenConstants;
|
||||||
|
import com.m2pool.common.core.text.Convert;
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description Jwt工具类
|
||||||
|
* @Date 2024/6/12 16:38
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class JwtUtils
|
||||||
|
{
|
||||||
|
public static String secret = TokenConstants.SECRET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据声明生成令牌
|
||||||
|
*
|
||||||
|
* @param claims 数据声明
|
||||||
|
* @return 令牌
|
||||||
|
*/
|
||||||
|
public static String createToken(Map<String, Object> claims)
|
||||||
|
{
|
||||||
|
String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从令牌中获取数据声明
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 数据声明
|
||||||
|
*/
|
||||||
|
public static Claims parseToken(String token)
|
||||||
|
{
|
||||||
|
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据令牌获取用户标识
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 用户ID
|
||||||
|
*/
|
||||||
|
public static String getUserKey(String token)
|
||||||
|
{
|
||||||
|
Claims claims = parseToken(token);
|
||||||
|
return getValue(claims, SecurityConstants.USER_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据令牌获取用户标识
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @return 用户ID
|
||||||
|
*/
|
||||||
|
public static String getUserKey(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, SecurityConstants.USER_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据令牌获取用户ID
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 用户ID
|
||||||
|
*/
|
||||||
|
public static String getUserId(String token)
|
||||||
|
{
|
||||||
|
Claims claims = parseToken(token);
|
||||||
|
return getValue(claims, SecurityConstants.DETAILS_USER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据身份信息获取用户ID
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @return 用户ID
|
||||||
|
*/
|
||||||
|
public static String getUserId(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, SecurityConstants.DETAILS_USER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据令牌获取用户名
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 用户名
|
||||||
|
*/
|
||||||
|
public static String getUserName(String token)
|
||||||
|
{
|
||||||
|
Claims claims = parseToken(token);
|
||||||
|
return getValue(claims, SecurityConstants.DETAILS_USERNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据身份信息获取用户名
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @return 用户名
|
||||||
|
*/
|
||||||
|
public static String getUserName(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, SecurityConstants.DETAILS_USERNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据身份信息获取键值
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @param key 键
|
||||||
|
* @return 值
|
||||||
|
*/
|
||||||
|
public static String getValue(Claims claims, String key)
|
||||||
|
{
|
||||||
|
return Convert.toStr(claims.get(key), "");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.constant.OpenApiKeyConstants;
|
||||||
|
import com.m2pool.common.core.constant.TokenConstants;
|
||||||
|
import com.m2pool.common.core.text.Convert;
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description Jwt工具类
|
||||||
|
* @Date 2024/6/12 16:38
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class OpenApiJwtUtils
|
||||||
|
{
|
||||||
|
public static String secret = TokenConstants.API_SECRET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据声明生成令牌
|
||||||
|
*
|
||||||
|
* @param claims 数据声明
|
||||||
|
* @return 令牌
|
||||||
|
*/
|
||||||
|
public static String createApiKey(Map<String, Object> claims)
|
||||||
|
{
|
||||||
|
String apiKey = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
|
||||||
|
return apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从令牌中获取数据声明
|
||||||
|
*
|
||||||
|
* @param apiKey 令牌
|
||||||
|
* @return 数据声明
|
||||||
|
*/
|
||||||
|
public static Claims parseApiKey(String apiKey)
|
||||||
|
{
|
||||||
|
Claims claims = null;
|
||||||
|
try {
|
||||||
|
claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(apiKey).getBody();
|
||||||
|
}catch (Exception e){
|
||||||
|
System.out.println("Jwt解析失败");
|
||||||
|
}
|
||||||
|
return claims;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据apiKey获取apiKey
|
||||||
|
*
|
||||||
|
* @param apiKey 令牌
|
||||||
|
* @return apiKey
|
||||||
|
*/
|
||||||
|
public static String getApiKey(String apiKey)
|
||||||
|
{
|
||||||
|
Claims claims = parseApiKey(apiKey);
|
||||||
|
return getValue(claims, OpenApiKeyConstants.API_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据apiKey获取apiKey
|
||||||
|
*
|
||||||
|
* @return apiKey
|
||||||
|
*/
|
||||||
|
public static String getApiKey(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, OpenApiKeyConstants.API_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据apiKey获取用户邮箱
|
||||||
|
*
|
||||||
|
* @param apiKey 令牌
|
||||||
|
* @return 用户邮箱
|
||||||
|
*/
|
||||||
|
public static String getApiUser(String apiKey)
|
||||||
|
{
|
||||||
|
Claims claims = parseApiKey(apiKey);
|
||||||
|
return getValue(claims, OpenApiKeyConstants.API_USER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据身份信息获取用户邮箱
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @return 用户有
|
||||||
|
*/
|
||||||
|
public static String getApiUser(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, OpenApiKeyConstants.API_USER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据apiKey获取用户绑定ip
|
||||||
|
*
|
||||||
|
* @param apiKey 令牌
|
||||||
|
* @return 用户绑定ip
|
||||||
|
*/
|
||||||
|
public static String getApiIp(String apiKey)
|
||||||
|
{
|
||||||
|
Claims claims = parseApiKey(apiKey);
|
||||||
|
return getValue(claims, OpenApiKeyConstants.API_IP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据apiKey获取用户绑定ip
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @return 用户绑定ip
|
||||||
|
*/
|
||||||
|
public static String getApiIp(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, OpenApiKeyConstants.API_IP);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据身份信息获取用户绑定ip
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @return 用户绑定ip
|
||||||
|
*/
|
||||||
|
public static String getUserName(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, OpenApiKeyConstants.API_IP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据身份信息获取键值
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @param key 键
|
||||||
|
* @return 值
|
||||||
|
*/
|
||||||
|
public static String getValue(Claims claims, String key)
|
||||||
|
{
|
||||||
|
return Convert.toStr(claims.get(key), "");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import com.m2pool.common.core.utils.sql.SqlUtil;
|
||||||
|
import com.m2pool.common.core.web.page.Page;
|
||||||
|
import com.m2pool.common.core.web.page.TableSupport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 分页工具类
|
||||||
|
* @Date 2024/6/12 14:37
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class PageUtils extends PageHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 设置请求分页数据
|
||||||
|
*/
|
||||||
|
public static void startPage()
|
||||||
|
{
|
||||||
|
Page page = TableSupport.buildPageRequest();
|
||||||
|
Integer pageNum = page.getPageNum();
|
||||||
|
Integer pageSize = page.getPageSize();
|
||||||
|
String orderBy = SqlUtil.escapeOrderBySql(page.getOrderBy());
|
||||||
|
Boolean reasonable = page.getReasonable();
|
||||||
|
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理分页的线程变量
|
||||||
|
*/
|
||||||
|
public static void clearPage()
|
||||||
|
{
|
||||||
|
PageHelper.clearPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,304 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||||
|
import org.springframework.web.context.request.RequestAttributes;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.m2pool.common.core.constant.Constants;
|
||||||
|
import com.m2pool.common.core.Result.R;
|
||||||
|
import com.m2pool.common.core.text.Convert;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 客户端工具类
|
||||||
|
* @Date 2024/6/12 14:45
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class ServletUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取String参数
|
||||||
|
*/
|
||||||
|
public static String getParameter(String name)
|
||||||
|
{
|
||||||
|
return getRequest().getParameter(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取String参数
|
||||||
|
*/
|
||||||
|
public static String getParameter(String name, String defaultValue)
|
||||||
|
{
|
||||||
|
return Convert.toStr(getRequest().getParameter(name), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Integer参数
|
||||||
|
*/
|
||||||
|
public static Integer getParameterToInt(String name)
|
||||||
|
{
|
||||||
|
return Convert.toInt(getRequest().getParameter(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Integer参数
|
||||||
|
*/
|
||||||
|
public static Integer getParameterToInt(String name, Integer defaultValue)
|
||||||
|
{
|
||||||
|
return Convert.toInt(getRequest().getParameter(name), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Boolean参数
|
||||||
|
*/
|
||||||
|
public static Boolean getParameterToBool(String name)
|
||||||
|
{
|
||||||
|
return Convert.toBool(getRequest().getParameter(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Boolean参数
|
||||||
|
*/
|
||||||
|
public static Boolean getParameterToBool(String name, Boolean defaultValue)
|
||||||
|
{
|
||||||
|
return Convert.toBool(getRequest().getParameter(name), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取request
|
||||||
|
*/
|
||||||
|
public static HttpServletRequest getRequest()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getRequestAttributes().getRequest();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取response
|
||||||
|
*/
|
||||||
|
public static HttpServletResponse getResponse()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getRequestAttributes().getResponse();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取session
|
||||||
|
*/
|
||||||
|
public static HttpSession getSession()
|
||||||
|
{
|
||||||
|
return getRequest().getSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ServletRequestAttributes getRequestAttributes()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
|
||||||
|
return (ServletRequestAttributes) attributes;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getHeader(HttpServletRequest request, String name)
|
||||||
|
{
|
||||||
|
String value = request.getHeader(name);
|
||||||
|
if (StringUtils.isEmpty(value))
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
return urlDecode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, String> getHeaders(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
Map<String, String> map = new LinkedHashMap<>();
|
||||||
|
Enumeration<String> enumeration = request.getHeaderNames();
|
||||||
|
if (enumeration != null)
|
||||||
|
{
|
||||||
|
while (enumeration.hasMoreElements())
|
||||||
|
{
|
||||||
|
String key = enumeration.nextElement();
|
||||||
|
String value = request.getHeader(key);
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串渲染到客户端
|
||||||
|
*
|
||||||
|
* @param response 渲染对象
|
||||||
|
* @param string 待渲染的字符串
|
||||||
|
*/
|
||||||
|
public static void renderString(HttpServletResponse response, String string)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response.setStatus(200);
|
||||||
|
response.setContentType("application/json");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
response.getWriter().print(string);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是Ajax异步请求
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
*/
|
||||||
|
public static boolean isAjaxRequest(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
String accept = request.getHeader("accept");
|
||||||
|
if (accept != null && accept.contains("application/json"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String xRequestedWith = request.getHeader("X-Requested-With");
|
||||||
|
if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String uri = request.getRequestURI();
|
||||||
|
if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String ajax = request.getParameter("__ajax");
|
||||||
|
return StringUtils.inStringIgnoreCase(ajax, "json", "xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容编码
|
||||||
|
*
|
||||||
|
* @param str 内容
|
||||||
|
* @return 编码后的内容
|
||||||
|
*/
|
||||||
|
public static String urlEncode(String str)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return URLEncoder.encode(str, Constants.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e)
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容解码
|
||||||
|
*
|
||||||
|
* @param str 内容
|
||||||
|
* @return 解码后的内容
|
||||||
|
*/
|
||||||
|
public static String urlDecode(String str)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return URLDecoder.decode(str, Constants.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e)
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置webflux模型响应
|
||||||
|
*
|
||||||
|
* @param response ServerHttpResponse
|
||||||
|
* @param value 响应内容
|
||||||
|
* @return Mono<Void>
|
||||||
|
*/
|
||||||
|
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value)
|
||||||
|
{
|
||||||
|
return webFluxResponseWriter(response, HttpStatus.OK, value, R.FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置webflux模型响应
|
||||||
|
*
|
||||||
|
* @param response ServerHttpResponse
|
||||||
|
* @param code 响应状态码
|
||||||
|
* @param value 响应内容
|
||||||
|
* @return Mono<Void>
|
||||||
|
*/
|
||||||
|
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value, int code)
|
||||||
|
{
|
||||||
|
return webFluxResponseWriter(response, HttpStatus.OK, value, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置webflux模型响应
|
||||||
|
*
|
||||||
|
* @param response ServerHttpResponse
|
||||||
|
* @param status http状态码
|
||||||
|
* @param code 响应状态码
|
||||||
|
* @param value 响应内容
|
||||||
|
* @return Mono<Void>
|
||||||
|
*/
|
||||||
|
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code)
|
||||||
|
{
|
||||||
|
return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置webflux模型响应
|
||||||
|
*
|
||||||
|
* @param response ServerHttpResponse
|
||||||
|
* @param contentType content-type
|
||||||
|
* @param status http状态码
|
||||||
|
* @param code 响应状态码
|
||||||
|
* @param value 响应内容
|
||||||
|
* @return Mono<Void>
|
||||||
|
*/
|
||||||
|
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code)
|
||||||
|
{
|
||||||
|
response.setStatusCode(status);
|
||||||
|
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);
|
||||||
|
R<?> result = R.fail(code, value.toString());
|
||||||
|
DataBuffer dataBuffer = response.bufferFactory().wrap(JSONObject.toJSONString(result).getBytes());
|
||||||
|
return response.writeWith(Mono.just(dataBuffer));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import org.springframework.aop.framework.AopContext;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description Spring工具类
|
||||||
|
* 方便在非spring管理环境中获取bean
|
||||||
|
* @Date 2024/6/12 17:27
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public final class SpringUtils implements BeanFactoryPostProcessor
|
||||||
|
{
|
||||||
|
/** Spring应用Context环境 */
|
||||||
|
private static ConfigurableListableBeanFactory beanFactory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
|
||||||
|
{
|
||||||
|
SpringUtils.beanFactory = beanFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对象
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return Object
|
||||||
|
* @throws org.springframework.beans.BeansException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T getBean(String name) throws BeansException
|
||||||
|
{
|
||||||
|
return (T) beanFactory.getBean(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取类型为requiredType的对象
|
||||||
|
*
|
||||||
|
* @param clz
|
||||||
|
* @return
|
||||||
|
* @throws org.springframework.beans.BeansException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static <T> T getBean(Class<T> clz) throws BeansException
|
||||||
|
{
|
||||||
|
T result = (T) beanFactory.getBean(clz);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*判断BeanFactory中是否包含有所给名字的bean
|
||||||
|
* @param name
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static boolean containsBean(String name)
|
||||||
|
{
|
||||||
|
return beanFactory.containsBean(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return boolean
|
||||||
|
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
|
||||||
|
{
|
||||||
|
return beanFactory.isSingleton(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* @return Class 注册对象的类型
|
||||||
|
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
|
||||||
|
{
|
||||||
|
return beanFactory.getType(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
|
||||||
|
{
|
||||||
|
return beanFactory.getAliases(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取aop代理对象
|
||||||
|
*
|
||||||
|
* @param invoker
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T getAopProxy(T invoker)
|
||||||
|
{
|
||||||
|
return (T) AopContext.currentProxy();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,548 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.m2pool.common.core.text.StrFormatter;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
import com.m2pool.common.core.constant.Constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 字符串工具类
|
||||||
|
* @Date 2024/6/12 14:41
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class StringUtils extends org.apache.commons.lang3.StringUtils
|
||||||
|
{
|
||||||
|
/** 空字符串 */
|
||||||
|
private static final String NULLSTR = "";
|
||||||
|
|
||||||
|
public static final int INDEX_NOT_FOUND = -1;
|
||||||
|
|
||||||
|
/** 下划线 */
|
||||||
|
private static final char SEPARATOR = '_';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取参数不为空值
|
||||||
|
*
|
||||||
|
* @param value defaultValue 要判断的value
|
||||||
|
* @return value 返回值
|
||||||
|
*/
|
||||||
|
public static <T> T nvl(T value, T defaultValue)
|
||||||
|
{
|
||||||
|
return value != null ? value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个Collection是否为空, 包含List,Set,Queue
|
||||||
|
*
|
||||||
|
* @param coll 要判断的Collection
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Collection<?> coll)
|
||||||
|
{
|
||||||
|
return isNull(coll) || coll.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个Collection是否非空,包含List,Set,Queue
|
||||||
|
*
|
||||||
|
* @param coll 要判断的Collection
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(Collection<?> coll)
|
||||||
|
{
|
||||||
|
return !isEmpty(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象数组是否为空
|
||||||
|
*
|
||||||
|
* @param objects 要判断的对象数组
|
||||||
|
** @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Object[] objects)
|
||||||
|
{
|
||||||
|
return isNull(objects) || (objects.length == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象数组是否非空
|
||||||
|
*
|
||||||
|
* @param objects 要判断的对象数组
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(Object[] objects)
|
||||||
|
{
|
||||||
|
return !isEmpty(objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个Map是否为空
|
||||||
|
*
|
||||||
|
* @param map 要判断的Map
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Map<?, ?> map)
|
||||||
|
{
|
||||||
|
return isNull(map) || map.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个Map是否为空
|
||||||
|
*
|
||||||
|
* @param map 要判断的Map
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(Map<?, ?> map)
|
||||||
|
{
|
||||||
|
return !isEmpty(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个字符串是否为空串
|
||||||
|
*
|
||||||
|
* @param str String
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(String str)
|
||||||
|
{
|
||||||
|
return isNull(str) || NULLSTR.equals(str.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个字符串是否为非空串
|
||||||
|
*
|
||||||
|
* @param str String
|
||||||
|
* @return true:非空串 false:空串
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(String str)
|
||||||
|
{
|
||||||
|
return !isEmpty(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象是否为空
|
||||||
|
*
|
||||||
|
* @param object Object
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isNull(Object object)
|
||||||
|
{
|
||||||
|
return object == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象是否非空
|
||||||
|
*
|
||||||
|
* @param object Object
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotNull(Object object)
|
||||||
|
{
|
||||||
|
return !isNull(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象是否是数组类型(Java基本型别的数组)
|
||||||
|
*
|
||||||
|
* @param object 对象
|
||||||
|
* @return true:是数组 false:不是数组
|
||||||
|
*/
|
||||||
|
public static boolean isArray(Object object)
|
||||||
|
{
|
||||||
|
return isNotNull(object) && object.getClass().isArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 去空格
|
||||||
|
*/
|
||||||
|
public static String trim(String str)
|
||||||
|
{
|
||||||
|
return (str == null ? "" : str.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 截取字符串
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @param start 开始
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String substring(final String str, int start)
|
||||||
|
{
|
||||||
|
if (str == null)
|
||||||
|
{
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start < 0)
|
||||||
|
{
|
||||||
|
start = str.length() + start;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start < 0)
|
||||||
|
{
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
if (start > str.length())
|
||||||
|
{
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str.substring(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 截取字符串
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @param start 开始
|
||||||
|
* @param end 结束
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String substring(final String str, int start, int end)
|
||||||
|
{
|
||||||
|
if (str == null)
|
||||||
|
{
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end < 0)
|
||||||
|
{
|
||||||
|
end = str.length() + end;
|
||||||
|
}
|
||||||
|
if (start < 0)
|
||||||
|
{
|
||||||
|
start = str.length() + start;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end > str.length())
|
||||||
|
{
|
||||||
|
end = str.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start > end)
|
||||||
|
{
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start < 0)
|
||||||
|
{
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
if (end < 0)
|
||||||
|
{
|
||||||
|
end = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str.substring(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为空,并且不是空白字符
|
||||||
|
*
|
||||||
|
* @param str 要判断的value
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static boolean hasText(String str)
|
||||||
|
{
|
||||||
|
return (str != null && !str.isEmpty() && containsText(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean containsText(CharSequence str)
|
||||||
|
{
|
||||||
|
int strLen = str.length();
|
||||||
|
for (int i = 0; i < strLen; i++)
|
||||||
|
{
|
||||||
|
if (!Character.isWhitespace(str.charAt(i)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化文本, {} 表示占位符<br>
|
||||||
|
*
|
||||||
|
* @param template 文本模板,被替换的部分用 {} 表示
|
||||||
|
* @param params 参数值
|
||||||
|
* @return 格式化后的文本
|
||||||
|
*/
|
||||||
|
public static String format(String template, Object... params)
|
||||||
|
{
|
||||||
|
if (isEmpty(params) || isEmpty(template))
|
||||||
|
{
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
return StrFormatter.format(template, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为http(s)://开头
|
||||||
|
*
|
||||||
|
* @param link 链接
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static boolean isHttp(String link)
|
||||||
|
{
|
||||||
|
return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驼峰转下划线命名
|
||||||
|
*/
|
||||||
|
public static String toUnderScoreCase(String str)
|
||||||
|
{
|
||||||
|
if (str == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
// 前置字符是否大写
|
||||||
|
boolean preCharIsUpperCase = true;
|
||||||
|
// 当前字符是否大写
|
||||||
|
boolean curreCharIsUpperCase = true;
|
||||||
|
// 下一字符是否大写
|
||||||
|
boolean nexteCharIsUpperCase = true;
|
||||||
|
for (int i = 0; i < str.length(); i++)
|
||||||
|
{
|
||||||
|
char c = str.charAt(i);
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
preCharIsUpperCase = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
curreCharIsUpperCase = Character.isUpperCase(c);
|
||||||
|
|
||||||
|
if (i < (str.length() - 1))
|
||||||
|
{
|
||||||
|
nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
|
||||||
|
{
|
||||||
|
sb.append(SEPARATOR);
|
||||||
|
}
|
||||||
|
else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
|
||||||
|
{
|
||||||
|
sb.append(SEPARATOR);
|
||||||
|
}
|
||||||
|
sb.append(Character.toLowerCase(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否包含字符串
|
||||||
|
*
|
||||||
|
* @param str 验证字符串
|
||||||
|
* @param strs 字符串组
|
||||||
|
* @return 包含返回true
|
||||||
|
*/
|
||||||
|
public static boolean inStringIgnoreCase(String str, String... strs)
|
||||||
|
{
|
||||||
|
if (str != null && strs != null)
|
||||||
|
{
|
||||||
|
for (String s : strs)
|
||||||
|
{
|
||||||
|
if (str.equalsIgnoreCase(trim(s)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
|
||||||
|
*
|
||||||
|
* @param name 转换前的下划线大写方式命名的字符串
|
||||||
|
* @return 转换后的驼峰式命名的字符串
|
||||||
|
*/
|
||||||
|
public static String convertToCamelCase(String name)
|
||||||
|
{
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
// 快速检查
|
||||||
|
if (name == null || name.isEmpty())
|
||||||
|
{
|
||||||
|
// 没必要转换
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if (!name.contains("_"))
|
||||||
|
{
|
||||||
|
// 不含下划线,仅将首字母大写
|
||||||
|
return name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||||
|
}
|
||||||
|
// 用下划线将原始字符串分割
|
||||||
|
String[] camels = name.split("_");
|
||||||
|
for (String camel : camels)
|
||||||
|
{
|
||||||
|
// 跳过原始字符串中开头、结尾的下换线或双重下划线
|
||||||
|
if (camel.isEmpty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 首字母大写
|
||||||
|
result.append(camel.substring(0, 1).toUpperCase());
|
||||||
|
result.append(camel.substring(1).toLowerCase());
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驼峰式命名法 例如:user_name->userName
|
||||||
|
*/
|
||||||
|
public static String toCamelCase(String s)
|
||||||
|
{
|
||||||
|
if (s == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
s = s.toLowerCase();
|
||||||
|
StringBuilder sb = new StringBuilder(s.length());
|
||||||
|
boolean upperCase = false;
|
||||||
|
for (int i = 0; i < s.length(); i++)
|
||||||
|
{
|
||||||
|
char c = s.charAt(i);
|
||||||
|
|
||||||
|
if (c == SEPARATOR)
|
||||||
|
{
|
||||||
|
upperCase = true;
|
||||||
|
}
|
||||||
|
else if (upperCase)
|
||||||
|
{
|
||||||
|
sb.append(Character.toUpperCase(c));
|
||||||
|
upperCase = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
|
||||||
|
*
|
||||||
|
* @param str 指定字符串
|
||||||
|
* @param strs 需要检查的字符串数组
|
||||||
|
* @return 是否匹配
|
||||||
|
*/
|
||||||
|
public static boolean matches(String str, List<String> strs)
|
||||||
|
{
|
||||||
|
if (isEmpty(str) || isEmpty(strs))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (String pattern : strs)
|
||||||
|
{
|
||||||
|
if (isMatch(pattern, str))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断url是否与规则配置:
|
||||||
|
* ? 表示单个字符;
|
||||||
|
* * 表示一层路径内的任意字符串,不可跨层级;
|
||||||
|
* ** 表示任意层路径;
|
||||||
|
*
|
||||||
|
* @param pattern 匹配规则
|
||||||
|
* @param url 需要匹配的url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isMatch(String pattern, String url)
|
||||||
|
{
|
||||||
|
AntPathMatcher matcher = new AntPathMatcher();
|
||||||
|
return matcher.match(pattern, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T cast(Object obj)
|
||||||
|
{
|
||||||
|
return (T) obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
|
||||||
|
*
|
||||||
|
* @param num 数字对象
|
||||||
|
* @param size 字符串指定长度
|
||||||
|
* @return 返回数字的字符串格式,该字符串为指定长度。
|
||||||
|
*/
|
||||||
|
public static final String padl(final Number num, final int size)
|
||||||
|
{
|
||||||
|
return padl(num.toString(), size, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
|
||||||
|
*
|
||||||
|
* @param s 原始字符串
|
||||||
|
* @param size 字符串指定长度
|
||||||
|
* @param c 用于补齐的字符
|
||||||
|
* @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
|
||||||
|
*/
|
||||||
|
public static final String padl(final String s, final int size, final char c)
|
||||||
|
{
|
||||||
|
final StringBuilder sb = new StringBuilder(size);
|
||||||
|
if (s != null)
|
||||||
|
{
|
||||||
|
final int len = s.length();
|
||||||
|
if (s.length() <= size)
|
||||||
|
{
|
||||||
|
for (int i = size - len; i > 0; i--)
|
||||||
|
{
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
sb.append(s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return s.substring(len - size, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = size; i > 0; i--)
|
||||||
|
{
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
public static String substringAfter(final String str, final String separator) {
|
||||||
|
if (isEmpty(str)) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
if (separator == null) {
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
final int pos = str.indexOf(separator);
|
||||||
|
if (pos == INDEX_NOT_FOUND) {
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
return str.substring(pos + separator.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String clean(String str){
|
||||||
|
if (isEmpty(str)) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str.replaceAll("\\r\\n|\\n|\\\\n| |\\s","");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.m2pool.common.core.utils;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 验证码生成工具类
|
||||||
|
* @Date 2024/8/21 11:12
|
||||||
|
* @Author 杜懿
|
||||||
|
*/
|
||||||
|
public class TOTP {
|
||||||
|
|
||||||
|
// 0 1 2 3 4 5 6 7 8
|
||||||
|
private static final int[] DIGITS_POWER = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method uses the JCE to provide the crypto algorithm. HMAC computes a
|
||||||
|
* Hashed Message Authentication Code with the crypto hash algorithm as a
|
||||||
|
* parameter.
|
||||||
|
*
|
||||||
|
* @param crypto : the crypto algorithm (HmacSHA1, HmacSHA256, HmacSHA512)
|
||||||
|
* @param keyBytes : the bytes to use for the HMAC key
|
||||||
|
* @param text : the message or text to be authenticated
|
||||||
|
*/
|
||||||
|
private static byte[] hmac_sha(String crypto, byte[] keyBytes, byte[] text) {
|
||||||
|
try {
|
||||||
|
Mac hmac;
|
||||||
|
hmac = Mac.getInstance(crypto);
|
||||||
|
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
|
||||||
|
hmac.init(macKey);
|
||||||
|
return hmac.doFinal(text);
|
||||||
|
} catch (GeneralSecurityException gse) {
|
||||||
|
throw new UndeclaredThrowableException(gse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method converts a HEX string to Byte[]
|
||||||
|
*
|
||||||
|
* @param hex : the HEX string
|
||||||
|
* @return: a byte array
|
||||||
|
*/
|
||||||
|
private static byte[] hexStr2Bytes(String hex) {
|
||||||
|
// Adding one byte to get the right conversion
|
||||||
|
// Values starting with "0" can be converted
|
||||||
|
byte[] bArray = new BigInteger("10" + hex, 16).toByteArray();
|
||||||
|
|
||||||
|
// Copy all the REAL bytes, not the "first"
|
||||||
|
byte[] ret = new byte[bArray.length - 1];
|
||||||
|
System.arraycopy(bArray, 1, ret, 0, ret.length);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method generates a TOTP value for the given set of parameters.
|
||||||
|
*
|
||||||
|
* @param key : the shared secret, HEX encoded
|
||||||
|
* @param time : a value that reflects a time
|
||||||
|
* @param returnDigits : number of digits to return
|
||||||
|
* @param crypto : the crypto function to use
|
||||||
|
* @return: a numeric String in base 10 that includes
|
||||||
|
*/
|
||||||
|
public static String generateTOTP(String key, String time, String returnDigits, String crypto) {
|
||||||
|
int codeDigits = Integer.decode(returnDigits);
|
||||||
|
String result = null;
|
||||||
|
|
||||||
|
// Using the counter
|
||||||
|
// First 8 bytes are for the movingFactor
|
||||||
|
// Compliant with base RFC 4226 (HOTP)
|
||||||
|
while (time.length() < 16) {
|
||||||
|
time = "0" + time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the HEX in a Byte[]
|
||||||
|
byte[] msg = hexStr2Bytes(time);
|
||||||
|
byte[] k = hexStr2Bytes(key);
|
||||||
|
byte[] hash = hmac_sha(crypto, k, msg);
|
||||||
|
|
||||||
|
// put selected bytes into result int
|
||||||
|
int offset = hash[hash.length - 1] & 0xf;
|
||||||
|
|
||||||
|
int binary = ((hash[offset] & 0x7f) << 24)
|
||||||
|
| ((hash[offset + 1] & 0xff) << 16)
|
||||||
|
| ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
|
||||||
|
|
||||||
|
int otp = binary % DIGITS_POWER[codeDigits];
|
||||||
|
|
||||||
|
result = Integer.toString(otp);
|
||||||
|
while (result.length() < codeDigits) {
|
||||||
|
result = "0" + result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
package com.m2pool.common.core.utils.bean;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description Bean工具类
|
||||||
|
* @Date 2024/6/12 10:16
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BeanUtils extends org.springframework.beans.BeanUtils
|
||||||
|
{
|
||||||
|
/** Bean方法名中属性名开始的下标 */
|
||||||
|
private static final int BEAN_METHOD_PROP_INDEX = 3;
|
||||||
|
|
||||||
|
/** * 匹配getter方法的正则表达式 */
|
||||||
|
private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
|
||||||
|
|
||||||
|
/** * 匹配setter方法的正则表达式 */
|
||||||
|
private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean属性复制工具方法。
|
||||||
|
*
|
||||||
|
* @param dest 目标对象
|
||||||
|
* @param src 源对象
|
||||||
|
*/
|
||||||
|
public static void copyBeanProp(Object dest, Object src)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
copyProperties(src, dest);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对象的setter方法。
|
||||||
|
*
|
||||||
|
* @param obj 对象
|
||||||
|
* @return 对象的setter方法列表
|
||||||
|
*/
|
||||||
|
public static List<Method> getSetterMethods(Object obj)
|
||||||
|
{
|
||||||
|
// setter方法列表
|
||||||
|
List<Method> setterMethods = new ArrayList<Method>();
|
||||||
|
|
||||||
|
// 获取所有方法
|
||||||
|
Method[] methods = obj.getClass().getMethods();
|
||||||
|
|
||||||
|
// 查找setter方法
|
||||||
|
|
||||||
|
for (Method method : methods)
|
||||||
|
{
|
||||||
|
Matcher m = SET_PATTERN.matcher(method.getName());
|
||||||
|
if (m.matches() && (method.getParameterTypes().length == 1))
|
||||||
|
{
|
||||||
|
setterMethods.add(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 返回setter方法列表
|
||||||
|
return setterMethods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对象的getter方法。
|
||||||
|
*
|
||||||
|
* @param obj 对象
|
||||||
|
* @return 对象的getter方法列表
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static List<Method> getGetterMethods(Object obj)
|
||||||
|
{
|
||||||
|
// getter方法列表
|
||||||
|
List<Method> getterMethods = new ArrayList<Method>();
|
||||||
|
// 获取所有方法
|
||||||
|
Method[] methods = obj.getClass().getMethods();
|
||||||
|
// 查找getter方法
|
||||||
|
for (Method method : methods)
|
||||||
|
{
|
||||||
|
Matcher m = GET_PATTERN.matcher(method.getName());
|
||||||
|
if (m.matches() && (method.getParameterTypes().length == 0))
|
||||||
|
{
|
||||||
|
getterMethods.add(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 返回getter方法列表
|
||||||
|
return getterMethods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查Bean方法名中的属性名是否相等。<br>
|
||||||
|
* 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。
|
||||||
|
*
|
||||||
|
* @param m1 方法名1
|
||||||
|
* @param m2 方法名2
|
||||||
|
* @return 属性名一样返回true,否则返回false
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static boolean isMethodPropEquals(String m1, String m2)
|
||||||
|
{
|
||||||
|
return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.m2pool.common.core.utils.bean;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.ConstraintViolationException;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description bean对象属性验证
|
||||||
|
* @Date 2024/6/12 10:43
|
||||||
|
* @Author dy
|
||||||
|
*/
|
||||||
|
public class BeanValidators {
|
||||||
|
|
||||||
|
public static void validateWithException(Validator validator, Object object, Class<?>... groups)
|
||||||
|
throws ConstraintViolationException
|
||||||
|
{
|
||||||
|
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
|
||||||
|
if (!constraintViolations.isEmpty())
|
||||||
|
{
|
||||||
|
throw new ConstraintViolationException(constraintViolations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue