fix: 码全代码添加

This commit is contained in:
2024-10-11 15:56:51 +08:00
parent 9a853f40c2
commit 7776e95902
907 changed files with 81296 additions and 324 deletions

View File

@@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2023 codvision.com All Rights Reserved.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.codvision</groupId>
<artifactId>cvbp-public</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cvbp-common-core</artifactId>
<packaging>jar</packaging>
<version>1.0.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-json</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,16 @@
package com.codvision.commoncore.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* @author codvision
*/
@Data
@AllArgsConstructor
public class CoordinatePoint {
Double lng;
Double lat;
}

View File

@@ -0,0 +1,189 @@
package com.codvision.commoncore.common;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ExpiryMap<K, V> implements Map<K, V> {
private boolean isRefresh = false;
private ScheduledExecutorService scheduledExecutorService;
private static final ConcurrentHashMap WORK_MAP = new ConcurrentHashMap();
private static final ConcurrentHashMap<Object, Long> EXPIRY_MAP = new ConcurrentHashMap<>();
public ExpiryMap() {
super();
}
public ExpiryMap(boolean isRefresh) {
this.isRefresh = isRefresh;
startClearKey();
}
public void closeMap() {
scheduledExecutorService.shutdown();
}
/**
* 定时清除失效key
*/
public void startClearKey() {
scheduledExecutorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build());
scheduledExecutorService.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
System.out.println("===" + Thread.currentThread().getName() + "===");
removeInvalidKeys();
}
}
, 0, 3600, TimeUnit.SECONDS);
}
private static void removeInvalidKeys() {
EXPIRY_MAP.keySet().forEach(key -> {
if (EXPIRY_MAP.get(key) < System.currentTimeMillis()) {
EXPIRY_MAP.remove(key);
WORK_MAP.remove(key);
}
});
System.gc();
}
/**
* put方法需要设置key 的有效期!单位为:毫秒
*
* @param key
* @param value
* @param expiry key的有效期单位毫秒
* @return
*/
public V put(K key, V value, long expiry) {
if (!containsKey(key) || isRefresh) {//更新value只有需要刷新时间时才需要操作expiryMap
EXPIRY_MAP.put(key, System.currentTimeMillis() + expiry);
}
WORK_MAP.put(key, value);
return value;
}
@Override
public int size() {
return keySet().size();
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean containsKey(Object key) {
if (key != null && EXPIRY_MAP.containsKey(key)) {
boolean flag = EXPIRY_MAP.get(key) > System.currentTimeMillis();
return flag;
}
return false;
}
@Override
public boolean containsValue(Object value) {
Collection values = WORK_MAP.values();
if (values != null) {
return values.contains(value);
}
return false;
}
@Override
public V get(Object key) {
if (containsKey(key)) {
return (V) WORK_MAP.get(key);
}
return null;
}
@Deprecated
@Override
public V put(K key, V value) {
throw new RuntimeException("此方法已废弃请加上key失效时间");
}
@Override
public V remove(Object key) {
boolean containKey = containsKey(key);
EXPIRY_MAP.remove(key);
if (containKey) {
return (V) WORK_MAP.remove(key);
} else {
return null;
}
}
@Deprecated
@Override
public void putAll(Map<? extends K, ? extends V> m) {
throw new RuntimeException("此方法已废弃!");
}
@Override
public void clear() {
EXPIRY_MAP.clear();
WORK_MAP.clear();
}
@Override
public Set<K> keySet() {
removeInvalidKeys();
return WORK_MAP.keySet();
}
@Override
public Collection<V> values() {
removeInvalidKeys();
return WORK_MAP.values();
}
@Override
public Set<Entry<K, V>> entrySet() {
removeInvalidKeys();
return WORK_MAP.entrySet();
}
public static void main(String[] args) {
//ExpiryMap emap=new ExpiryMap();
ExpiryMap emap = new ExpiryMap(true);
emap.put("key1", "value1", 2 * 1000);
emap.put("key2", "value2", 5 * 1000);
emap.put("key3", "value3", 15 * 1000);
System.out.println(emap.size());
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(emap.size());
System.out.println(emap.keySet());
System.out.println(emap.values());
System.out.println(emap.entrySet());
emap.put("key4", "value4", 8 * 1000);
System.out.println(emap.size());
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(emap.size());
System.out.println(emap.keySet());
System.out.println(emap.values());
System.out.println(emap.entrySet());
emap.closeMap();
}
}

View File

@@ -0,0 +1,133 @@
package com.codvision.commoncore.common;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.HashMap;
/**
* @author codvision
*/
@ApiModel(description = "返回响应数据")
public class ResponseEntity<T> {
@ApiModelProperty(value = "编码")
private int code = 200;
@ApiModelProperty(value = "基本信息")
private String message = "成功";
@ApiModelProperty(value = "返回对象")
private T data;
private static final HashMap<Integer, String> ERROR_CODE = new HashMap<Integer, String>() {
{
put(100, "暂无数据");
put(200, "成功");
put(10000, "通用错误");
///用户类
put(10001, "用户名或密码错误");
put(10002, "登录状态已过期");
put(10003, "注册用户已存在");
put(10004, "账号已被锁定,请在一小时后重试");
///操作权限类
put(20001, "无操作权限");
///参数类
put(30001, "非法参数");
put(30002, "缺少必要参数");
put(30003, "文件内容为空");
put(30004, "不支持的文件格式");
put(30005, "获取参数失败");
////数据操作类
put(40001, "添加数据失败");
put(40002, "更新数据失败");
put(40003, "删除数据失败");
put(50001, "不存在的对象");
put(50002, "文件上传超过最大限制!");
put(50003, "文件上传失败!");
put(110000, "获取用户失败或用户不存在!");
put(100001, "钉钉获取用户信息失败,请稍后再试");
put(110002, "小程序授权获取手机号失败");
put(990000, "系统错误");
}
};
public ResponseEntity() {
}
public ResponseEntity(T data) {
this.data = data;
}
public int getCode() {
return code;
}
public ResponseEntity setCode(int code) {
this.code = code;
if (ERROR_CODE.containsKey(code)) {
setMessage(ERROR_CODE.get(code));
}
return this;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public ResponseEntity setData(T data) {
this.data = data;
return this;
}
public static <T> ResponseEntity<T> def(Class<T> clazz) {
return new ResponseEntity<>();
}
public ResponseEntity<T> ok() {
setCode(200);
return this;
}
public ResponseEntity<T> error(int code) {
setCode(code);
return this;
}
public ResponseEntity<T> error(int code, String message) {
setCode(code);
setMessage(message);
return this;
}
public ResponseEntity<T> message(String message) {
setMessage(message);
return this;
}
public ResponseEntity<T> data(T data) {
setData(data);
return this;
}
public ResponseEntity<T> back(int code, String message, T data) {
setCode(code);
setMessage(message);
setData(data);
return this;
}
}

View File

@@ -0,0 +1,43 @@
package com.codvision.commoncore.enums;
/**
* @author codvision
*/
public enum NetworkData {
/**
* 月的天数
*/
MONTH(30, ""),
/**
* 周的天数
*/
WEEK(7, ""),
/**
* NET_WORK_ID
*/
NET_WORK_ID(0, "0:0:0:0:0:0:0:1"),
/**
* 成功
*/
OK(200, "ok");
private final int code;
private final String desc;
NetworkData(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1,64 @@
package com.codvision.commoncore.enums;
/**
* where 条件操作符号
*
* @author lingee
* @date 2022/5/9
*/
public enum SqlOperator {
/**
* like
*/
LIKE("LIKE"),
/**
* =
*/
EQ("="),
/**
* 不等于
*/
NE("<>"),
/**
* 大于
*/
GT(">"),
/**
* 大于等于
*/
GE(">="),
/**
* 小于
*/
LT("<"),
/**
* 小于等于
*/
LE("<="),
/**
* 为空
*/
IS_NULL("IS NULL"),
/**
* 不为空
*/
IS_NOT_NULL("IS NOT NULL"),
/**
* 范围查找
*/
BETWEEN("BETWEEN"),
/**
* 多数据查找
*/
IN("IN");
private final String operator;
SqlOperator(String operator) {
this.operator = operator;
}
public String getOperator() {
return operator;
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.commoncore.enums;
/**
* TrueOrFalse
*
* @author lingee
* @since 2024/4/29
*/
public enum TrueOrFalse {
FALSE("0", 0, false),
TRUE("1", 1, true);
private final String key;
private final int intVal;
private final boolean val;
TrueOrFalse(String key, int intVal, boolean val) {
this.key = key;
this.intVal = intVal;
this.val = val;
}
public String getKey() {
return key;
}
public int getIntVal() {
return intVal;
}
public boolean isVal() {
return val;
}
}

View File

@@ -0,0 +1,38 @@
package com.codvision.commoncore.exception;
import lombok.Getter;
import lombok.Setter;
/**
* 认证异常
*
* @author hxl
*/
@Getter
@Setter
public class AuthException extends RuntimeException {
private Integer code;
private String message;
public AuthException() {
super();
}
public AuthException(int code) {
this.code = code;
}
public AuthException(String message) {
super(message);
this.message = message;
}
public AuthException(int code, String message) {
super(message);
this.code = code;
this.message = message;
}
}

View File

@@ -0,0 +1,37 @@
package com.codvision.commoncore.exception;
import lombok.Getter;
import lombok.Setter;
/**
* 业务异常
*
* @author hxl
*/
@Getter
@Setter
public class BusinessException extends RuntimeException {
private Integer code;
private String message;
public BusinessException() {
super();
}
public BusinessException(String message) {
super(message);
this.message = message;
}
public BusinessException(int code) {
this.code = code;
}
public BusinessException(int code, String message) {
super(message);
this.code = code;
this.message = message;
}
}

View File

@@ -0,0 +1,15 @@
package com.codvision.commoncore.exception;
/**
* @Author huxb
* @description:
* @create 2023/2/7 16:16
*/
public class IdempotentException extends RuntimeException {
public IdempotentException() {
}
public IdempotentException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,16 @@
package com.codvision.commoncore.exception;
/**
* @Author huxb
* @description:
* @create 2022/11/22 10:28
*/
public class LimitException extends RuntimeException{
public LimitException() {
super();
}
public LimitException(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,38 @@
package com.codvision.commoncore.exception;
import lombok.Getter;
import lombok.Setter;
/**
* 权限异常
*
* @author hxl
*/
@Getter
@Setter
public class PermissionException extends RuntimeException {
private Integer code;
private String message;
public PermissionException() {
super();
}
public PermissionException(int code) {
this.code = code;
}
public PermissionException(String message) {
super(message);
this.message = message;
}
public PermissionException(int code, String message) {
super(message);
this.code = code;
this.message = message;
}
}

View File

@@ -0,0 +1,11 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
/**
* 公共模块
*
* @author lingee
* @date 2023/7/14
*/
package com.codvision.commoncore;

View File

@@ -0,0 +1,139 @@
package com.codvision.commoncore.utils;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.management.openmbean.InvalidKeyException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
/**
* @author zjm
* @version V1.0
* @Package com.codvision.xlwzl.util
* @date 2020/7/3 10:59
* @Copyright © 2017-2020 杭州码全科技有限公司
* @Description 使用ECB模式加密
*/
public class AES {
/**
* 偏移量字符串必须是16位 当模式是CBC的时候必须设置偏移量
*/
private static final String iv = "0123456789ABCDEF";
private static final String Algorithm = "AES";
/**
* 算法/模式/补码方式
*/
private static final String AlgorithmProvider = "AES/ECB/PKCS5Padding";
public static byte[] generatorKey() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(Algorithm);
//默认128获得无政策权限后可为192或256
keyGenerator.init(256);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
}
public static IvParameterSpec getIv() throws UnsupportedEncodingException {
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
System.out.println("偏移量:" + byteToHexString(ivParameterSpec.getIV()));
return ivParameterSpec;
}
public static byte[] encrypt(String src) throws NoSuchPaddingException, NoSuchAlgorithmException, java.security.InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
return encrypt(src, "codvision@2020YH".getBytes(StandardCharsets.UTF_8));
}
public static byte[] encrypt(String src, byte[] key) throws NoSuchPaddingException, NoSuchAlgorithmException, java.security.InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
SecretKey secretKey = new SecretKeySpec(key, Algorithm);
//IvParameterSpec ivParameterSpec = getIv();
Cipher cipher = Cipher.getInstance(AlgorithmProvider);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] cipherBytes = cipher.doFinal(src.getBytes(StandardCharsets.UTF_8));
return cipherBytes;
}
public static String decrypt(String src) throws Exception {
return decrypt(src, "codvision@2020YH".getBytes(StandardCharsets.UTF_8));
}
public static String decrypt(String src, byte[] key) throws Exception {
SecretKey secretKey = new SecretKeySpec(key, Algorithm);
//IvParameterSpec ivParameterSpec = getIv();
Cipher cipher = Cipher.getInstance(AlgorithmProvider);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] hexBytes = hexStringToBytes(src);
byte[] plainBytes = cipher.doFinal(hexBytes);
return new String(plainBytes, StandardCharsets.UTF_8);
}
/**
* 将byte转换为16进制字符串
*
* @param src
* @return
*/
public static String byteToHexString(byte[] src) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xff;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
sb.append("0");
}
sb.append(hv);
}
return sb.toString();
}
/**
* 将16进制字符串装换为byte数组
*
* @param hexString
* @return
*/
public static byte[] hexStringToBytes(String hexString) {
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] b = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return b;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
public static void main(String[] args) {
try {
// byte key[] = generatorKey();
// 密钥必须是16的倍数
String src = "6ea40c84b3fe7c6c3033e59bd59643a3";
System.out.println("原字符串:" + src);
String enc = byteToHexString(encrypt(src));
System.out.println("加密:" + enc);
System.out.println("解密:" + decrypt(enc));
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,76 @@
package com.codvision.commoncore.utils;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.CryptoException;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
/**
* @author hxl
*/
public class AesUtil {
/**
* Cipher负责完成加密或解密工作
*/
private Cipher cipher;
/**
* 密钥
*/
private SecretKey secretKey;
/**
* @param key 密钥 转为为字节后支持三种密钥长度128、192、256位
*/
public AesUtil(String key) {
this(new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), SymmetricAlgorithm.AES.getValue()));
}
public AesUtil(SecretKey secretKey) {
try {
this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (Exception e) {
throw new CryptoException(e);
}
this.secretKey = secretKey;
}
public byte[] encrypt(byte[] data) {
try {
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(new byte[cipher.getBlockSize()]));
return cipher.doFinal(data);
} catch (Exception e) {
throw new CryptoException(e);
}
}
public byte[] decrypt(byte[] data) {
try {
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(new byte[cipher.getBlockSize()]));
return cipher.doFinal(data);
} catch (Exception e) {
throw new CryptoException(e);
}
}
public String encryptHex(byte[] data) {
return HexUtil.encodeHexStr(encrypt(data));
}
public byte[] decryptHex(String data) {
return decrypt(HexUtil.decodeHex(data));
}
public String encryptBase64(byte[] data) {
return Base64.encode(encrypt(data));
}
public byte[] decryptBase64(String data) {
return decrypt(Base64.decode(data));
}
}

View File

@@ -0,0 +1,74 @@
package com.codvision.commoncore.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.UUID;
/**
* @Author huxb
* @description: 随机生成appKeyappSecret
* @create 2021/12/21 16:44
*/
public class AppUtils {
//生成 app_secret 密钥
private final static String SERVER_NAME = "maquan_codvision";
private final static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
"t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z"};
/**
* 短8位UUID思想其实借鉴微博短域名的生成方式但是其重复概率过高而且每次生成4个需要随即选取一个。
* 本算法利用62个可打印字符通过随机生成32位UUID由于UUID都为十六进制所以将UUID分成8组每4个为一组然后通过模62操作结果作为索引取出字符
* 这样重复率大大降低。
* 经测试,在生成一千万个数据也没有出现重复,完全满足大部分需求。
*/
public static String getAppId() {
StringBuffer shortBuffer = new StringBuffer();
String uuid = UUID.randomUUID().toString().replace("-", "");
for (int i = 0; i < 8; i++) {
String str = uuid.substring(i * 4, i * 4 + 4);
int x = Integer.parseInt(str, 16);
shortBuffer.append(chars[x % 0x3E]);
}
return shortBuffer.toString();
}
/**
* 通过appId和内置关键词生成APP Secret
*/
public static String getAppSecret(String appId) {
try {
String[] array = new String[]{appId, SERVER_NAME};
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < array.length; i++) {
sb.append(array[i]);
}
String str = sb.toString();
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
}

View File

@@ -0,0 +1,163 @@
package com.codvision.commoncore.utils;
import cn.hutool.core.util.ObjectUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 对象工具类
*
* @author lingee
* @since 2023-7-20
*/
public class BeanUtil extends cn.hutool.core.bean.BeanUtil {
/**
* 获取属性名数组
*
* @param o 获取字段的对象
* @return 返回各个字段
*/
public static Field[] getFields(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
Field[] superFields = o.getClass().getSuperclass().getDeclaredFields();
Field[] allFields = new Field[fields.length + superFields.length];
int index = 0;
for (int i = 0; i < fields.length; i++) {
if ("serialVersionUID".equals(fields[i].getName())) {
continue;
}
Field field = fields[i];
if (ObjectUtil.isNotEmpty(field)) {
allFields[index] = field;
}
index++;
}
for (int i = 0; i < superFields.length; i++) {
if ("id".equals(superFields[i].getName())
|| "serialVersionUID".equals(superFields[i].getName())) {
continue;
}
Field field = superFields[i];
if (ObjectUtil.isNotEmpty(field)) {
allFields[index] = field;
}
index++;
}
return allFields;
}
/**
* 获取属性名数组
*
* @param o 获取字段的对象
* @return 返回各个字段
*/
public static String[] getFieldName(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
Field[] superFields = o.getClass().getSuperclass().getDeclaredFields();
String[] fieldNames = new String[fields.length + superFields.length];
int index = 0;
for (int i = 0; i < fields.length; i++) {
fieldNames[index] = fields[i].getName();
index++;
}
for (int i = 0; i < superFields.length; i++) {
if ("id".equals(superFields[i].getName())) {
continue;
}
fieldNames[index] = superFields[i].getName();
index++;
}
return fieldNames;
}
/**
* 根据属性名获取属性值
*
* @param fieldName 属性名
* @param o 对象
* @return 属性值
*/
public static Object getFieldValueByName(String fieldName, Object o) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = o.getClass().getMethod(getter, new Class[]{});
Object value = method.invoke(o, new Object[]{});
return value;
} catch (Exception e) {
return null;
}
}
/**
* 将对象转换为key value
* A=a&B=b&C=c 格式
*
* @param object 对象
* @return 格式化结果
*/
public static String formatKeyValuePair(Object object) {
//准备接受的字符串
StringBuilder stringBuffer = new StringBuilder();
//获取对象字段
String[] fieldNames = BeanUtil.getFieldName(object);
//遍历所有属性
for (int j = 0; j < fieldNames.length; j++) {
//不是第一个并且不是最后一个,拼接&
if (j != 0) {
stringBuffer.append("&");
}
//获取属性的名字
String key = fieldNames[j];
//获取值
Object value = BeanUtil.getFieldValueByName(key, object);
assert value != null;
stringBuffer.append(key).append("=").append(value.toString());
}
return stringBuffer.toString();
}
/**
* key value键值对 转换为 对象
* A=a&B=b&C=c 格式 转换为对象
*
* @param str 对象字符串
* @param t 范型
* @param <T> 范型
* @return 格式化结果
*/
public static <T> T formatKeyValuePair(String str, T t) {
//填写对参数键值对
String[] params = str.split("&");
//获取对象字段
String[] fieldNames = BeanUtil.getFieldName(t);
try {
//循环每个参数
for (String param : params) {
String[] keyValues = param.split("=");
for (int i = 0; i < fieldNames.length; i++) {
if (fieldNames[i].equals(keyValues[0])) {
Field f = t.getClass().getDeclaredField(fieldNames[i]);
f.setAccessible(true);
//长度为2 才转换,否则不转
if (keyValues.length == 2) {
f.set(t, keyValues[1]);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return t;
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.commoncore.utils;
import org.apache.commons.lang3.StringUtils;
/**
* 强密码校验包含数字、大小写字母和特殊符号长度要求8-15位且不与用户名相同
* @author hxl
*/
@SuppressWarnings("all")
public class CheckPwdUtil {
// 数字
public static final String REG_NUMBER = ".*\\d+.*";
// 小写字母
public static final String REG_UPPERCASE = ".*[A-Z]+.*";
// 大写字母
public static final String REG_LOWERCASE = ".*[a-z]+.*";
// 特殊符号(~!@#$%^&*()_+|<>,.?/:;'[]{}\)
public static final String REG_SYMBOL = ".*[~!@#$%^&*()_+|<>,.?/:;'\\[\\]{}\"]+.*";
public static boolean checkPasswordRule(String username, String password) {
if (StringUtils.isBlank(password) || password.length() < 8 || password.length() > 15) {
return false;
}
int i = 0;
if (password.matches(REG_NUMBER)) { i++; }
if (password.matches(REG_LOWERCASE)) { i++; }
if (password.matches(REG_UPPERCASE)) { i++; }
if (password.matches(REG_SYMBOL)) { i++; }
boolean contains = password.equals(username);
if (i < 4 || contains) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,139 @@
package com.codvision.commoncore.utils;
import com.codvision.commoncore.bean.CoordinatePoint;
/**
* 坐标工具类
*
* @author codvision
*/
public class CoordinateUtil {
public static final String BAIDU_LBS_TYPE = "bd09ll";
public static double pi = 3.1415926535897932384626;
public static double a = 6378245.0;
public static double ee = 0.00669342162296594323;
/**
* 84 to 火星坐标系 (GCJ-02)
*
* @param lat
* @param lon
* @return
*/
public static CoordinatePoint wgs84ToGcj02(double lon, double lat) {
if (outOfChina(lon, lat)) {
return null;
}
double dLat = transformLat(lon - 105.0, lat - 35.0);
double dLon = transformLon(lon - 105.0, lat - 35.0);
double radLat = lat / 180.0 * pi;
double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
double mgLat = lat + dLat;
double mgLon = lon + dLon;
return new CoordinatePoint(mgLon, mgLat);
}
/**
* * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return
*/
public static CoordinatePoint gcj02ToWgs84(double lon, double lat) {
CoordinatePoint gps = transform(lon, lat);
double lontitude = lon * 2 - gps.getLng();
double latitude = lat * 2 - gps.getLat();
return new CoordinatePoint(lontitude, latitude);
}
/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
*
* @param ggLat
* @param ggLat
*/
public static CoordinatePoint gcj02ToBd09(double ggLng, double ggLat) {
double x = ggLng, y = ggLat;
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);
double bdLng = z * Math.cos(theta) + 0.0065;
double bdLat = z * Math.sin(theta) + 0.006;
return new CoordinatePoint(bdLng, bdLat);
}
/**
* * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param
* bd_lat * @param bd_lon * @return
*/
public static CoordinatePoint bd09ToGcj02(double bdLng, double bdLat) {
double x = bdLng - 0.0065, y = bdLat - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
double ggLng = z * Math.cos(theta);
double ggLat = z * Math.sin(theta);
return new CoordinatePoint(ggLng, ggLat);
}
/**
* (BD-09)-->84
*
* @param bdLng
* @param bdLat
* @return
*/
public static CoordinatePoint bd09ToWgs84(double bdLng, double bdLat) {
CoordinatePoint gcj02 = bd09ToGcj02(bdLng, bdLat);
CoordinatePoint map84 = gcj02ToWgs84(gcj02.getLng(),
gcj02.getLat());
return map84;
}
public static boolean outOfChina(double lon, double lat) {
if (lon < 72.004 || lon > 137.8347) {
return true;
}
return lat < 0.8293 || lat > 55.8271;
}
public static CoordinatePoint transform(double lon, double lat) {
if (outOfChina(lon, lat)) {
return new CoordinatePoint(lat, lon);
}
double dLat = transformLat(lon - 105.0, lat - 35.0);
double dLon = transformLon(lon - 105.0, lat - 35.0);
double radLat = lat / 180.0 * pi;
double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
double mgLat = lat + dLat;
double mgLon = lon + dLon;
return new CoordinatePoint(mgLon, mgLat);
}
public static double transformLat(double x, double y) {
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
+ 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
public static double transformLon(double x, double y) {
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
* Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
* pi)) * 2.0 / 3.0;
return ret;
}
}

View File

@@ -0,0 +1,564 @@
package com.codvision.commoncore.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author codvision
*/
public class DateUtil extends cn.hutool.core.date.DateUtil {
public static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String STANDARD_DATE_FORMAT = "yyyy-MM-dd";
public static final String STANDARD_DATE_NO_UNDERLINE_FORMAT = "yyyyMMdd";
public static final String FULL_DATE = "yyyyMMddHHmmss";
public static Date getSomeWeekAgoDate(Date date, int weeks) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.WEEK_OF_YEAR, -weeks);
Date someWeeksAgo = calendar.getTime();
return someWeeksAgo;
}
/**
* 获取N个月前日期
*
* @param date
* @param month
* @return
*/
public static Date getSomeMonthAgoDate(Date date, int month) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, -month);
Date someMonthAgo = calendar.getTime();
return someMonthAgo;
}
/**
* 获取N年前日期
*
* @param date
* @return
*/
public static Date getSomeYearAgoDate(Date date, int year) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.YEAR, -year);
Date someYearAgo = calendar.getTime();
return someYearAgo;
}
public static String strToStr(String strDate) {
Date date = new Date();
try {
//先按照原格式转换为时间
date = new SimpleDateFormat("yyyyMMddHHmmss").parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
//再将时间转换为对应格式字符串
String str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
return str;
}
/**
* 根据系统时间返回一串无符号字符串
*/
public static String toString(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
return simpleDateFormat.format(date);
}
/**
* 根据系统时间返回一串无符号字符串
*/
public static String monthToString(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");
return simpleDateFormat.format(date);
}
/**
* 根据系统时间返回一串无符号字符串
*/
public static String dayToString(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
return simpleDateFormat.format(date);
}
/**
* 根据系统时间返回一串无符号字符串
*/
public static String toStringFor16(Date date, String value) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
String data = simpleDateFormat.format(date);
Random rome = new Random();
int last = rome.nextInt(90000000) + 10000000;
return value + data + last;
}
public static Date toDate(String date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return simpleDateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
/**
* 将一个字符串转换成日期格式
*
* @param date 字符串日期
* @param pattern 日期格式
* @return date
*/
public static Date toDate(String date, String pattern) {
if ("".equals("" + date)) {
return null;
}
if (pattern == null) {
pattern = STANDARD_DATE_FORMAT;
}
SimpleDateFormat sdf = new SimpleDateFormat(pattern, Locale.ENGLISH);
Date newDate = new Date();
try {
newDate = sdf.parse(date);
} catch (Exception ex) {
ex.printStackTrace();
}
return newDate;
}
public static String sdf(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return simpleDateFormat.format(date);
}
public static String getMonthBeginTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
Calendar c = Calendar.getInstance();
c.add(Calendar.MONTH, 0);
//设置为1号,当前日期既为本月第一天
c.set(Calendar.DAY_OF_MONTH, 1);
return sdf.format(c.getTime());
}
public static String getMonthEndTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
Calendar c = Calendar.getInstance();
c.add(Calendar.MONTH, 0);
c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
return sdf.format(c.getTime());
}
public static String getMonthBeginTimeOfLastYear() {
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
c.add(Calendar.MONTH, 0);
c.add(Calendar.YEAR, -1);
//设置为1号,当前日期既为本月第一天
c.set(Calendar.DAY_OF_MONTH, 1);
return sdf.format(c.getTime());
}
public static String getMonthEndTimeOfLastYear() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
Calendar c = Calendar.getInstance();
c.add(Calendar.MONTH, 0);
c.add(Calendar.YEAR, -1);
c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
return sdf.format(c.getTime());
}
public static String getToday() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(new Date());
}
/**
* 获得昨天日期:yyyy-MM-dd HH:mm:ss
*/
public static String getYesterdayBeginTime() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, -1);
SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
return startSdf.format(c.getTime());
}
/**
* 获得昨天日期:yyyy-MM-dd HH:mm:ss
*/
public static String getYesterdayEndTime() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, -1);
SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
return startSdf.format(c.getTime());
}
public static String getTodayBeginTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
return sdf.format(new Date());
}
public static String getTodayEndTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
return sdf.format(new Date());
}
public static String getNowDateTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date());
}
/**
* 获得明天日期:yyyy-MM-dd HH:mm:ss
*/
public static String getTomorrowBeginTime() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, 1);
SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
return startSdf.format(c.getTime());
}
/**
* 获得明天日期:yyyy-MM-dd HH:mm:ss
*/
public static String getTomorrowEndTime() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, 1);
SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
return startSdf.format(c.getTime());
}
/**
* 获得明天日期:yyyy-MM-dd time
*/
public static String getTomorrowTime(String time) {
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, 1);
SimpleDateFormat startSdf = new SimpleDateFormat(String.format("yyyy-MM-dd %s", time));
return startSdf.format(c.getTime());
}
public static String getYearBeginTime() {
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-01-01 00:00:00");
return sdf.format(c.getTime());
}
public static String getYearEndTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-12-31 23:59:59");
Calendar c = Calendar.getInstance();
return sdf.format(c.getTime());
}
public static String getYearBeginTimeOfLastYear() {
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-01-01 00:00:00");
c.add(Calendar.YEAR, -1);
return sdf.format(c.getTime());
}
public static String getYearEndTimeOfLastYear() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-12-31 23:59:59");
Calendar c = Calendar.getInstance();
c.add(Calendar.YEAR, -1);
return sdf.format(c.getTime());
}
/**
* 默认当天
*
* @return
*/
public static Map<String, Integer> getWeekOfMonth() {
return DateUtil.getWeekOfMonth(DateUtil.getToday());
}
/**
* 当前时间所属周,一周占用两个月的情况下属于上个月
*
* @param time
* @return
*/
public static Map<String, Integer> getWeekOfMonth(String time) {
//Calendar周日为一周的第一天
//1.当月的1号为周日:
//日期是否为周日 是,周数-1 第一个周日属于上个月最后一周
//2.当月的1号为周一:
//日期是否为周日 是,周数-1
//3.当月的1号为周二--六:
//日期是否为周日 是,周数-2 否,周数-1 为0属于上个月最后一周
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
int resultYear;
int resultMonth;
int resultWeekOfMonth;
Map<String, Integer> resultMap = new HashMap<>(16);
try {
Date parse = sdf.parse(time);
Calendar calendar = Calendar.getInstance();
calendar.setTime(parse);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
resultYear = year;
resultMonth = month + 1;
Calendar monthCalendar = Calendar.getInstance();
monthCalendar.set(Calendar.YEAR, year);
monthCalendar.set(Calendar.MONTH, month);
monthCalendar.set(Calendar.DAY_OF_MONTH, 1);
int monthDayOfWeek = monthCalendar.get(Calendar.DAY_OF_WEEK);
if (monthDayOfWeek == Calendar.SUNDAY) {
if (dayOfWeek == Calendar.SUNDAY) {
if (dayOfMonth == 1) {
if (month == 0) {
resultWeekOfMonth = getLastWeekOfMonth(year - 1, 11);
resultYear = year - 1;
resultMonth = 12;
} else {
resultWeekOfMonth = getLastWeekOfMonth(year, month - 1);
resultMonth = month;
}
} else {
resultWeekOfMonth = weekOfMonth - 1;
}
} else {
resultWeekOfMonth = weekOfMonth;
}
} else if (monthDayOfWeek == Calendar.MONDAY) {
if (dayOfWeek == Calendar.SUNDAY) {
resultWeekOfMonth = weekOfMonth - 1;
} else {
resultWeekOfMonth = weekOfMonth;
}
} else {
if (dayOfWeek == Calendar.SUNDAY) {
resultWeekOfMonth = weekOfMonth - 2;
} else {
resultWeekOfMonth = weekOfMonth - 1;
}
if (resultWeekOfMonth == 0) {
if (month == 0) {
resultWeekOfMonth = getLastWeekOfMonth(year - 1, 11);
resultYear = year - 1;
resultMonth = 12;
} else {
resultWeekOfMonth = getLastWeekOfMonth(year, month - 1);
resultMonth = month;
}
}
}
resultMap.put("year", resultYear);
resultMap.put("month", resultMonth);
resultMap.put("weekOfMonth", resultWeekOfMonth);
} catch (ParseException e) {
e.printStackTrace();
}
return resultMap;
}
/**
* 按月度获取当月最后一周是第几周
*
* @param year
* @param month
* @return
*/
private static int getLastWeekOfMonth(int year, int month) {
int result;
//当月1号
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, 1);
//当月最后一天
Calendar lastDayOfMonth = Calendar.getInstance();
lastDayOfMonth.set(Calendar.YEAR, year);
lastDayOfMonth.set(Calendar.MONTH, month);
lastDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
lastDayOfMonth.roll(Calendar.DAY_OF_MONTH, -1);
//
int lastWeekOfMonth = lastDayOfMonth.get(Calendar.WEEK_OF_MONTH);
//
int lastDayOfWeek = lastDayOfMonth.get(Calendar.DAY_OF_WEEK);
//当月1号是周几
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
//如果1号是周日或周一,那么这个月的所有除了周日的日期用Calendar获取的周数与需要的周数是一致的;
if (dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.MONDAY) {
//如果最后一天是周日需要的周数要-1
if (lastDayOfWeek == Calendar.SUNDAY) {
result = lastWeekOfMonth - 1;
} else {
result = lastWeekOfMonth;
}
} else {//1号是周二,三,四,五,六的情况下,这个月的所有除了周日的日期用Calendar获取的周数-1后与需要的周数是一致的;
//是周日的日期需要-2
if (lastDayOfWeek == Calendar.SUNDAY) {
result = lastWeekOfMonth - 2;
} else {
result = lastWeekOfMonth - 1;
}
}
return result;
}
public static String getWeekBeginTime() {
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
if (dayofweek == 1) {
dayofweek += 7;
}
cal.add(Calendar.DATE, 2 - dayofweek);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
return sdf.format(cal.getTime());
}
/**
* 获取本周的结束时间
*
* @return
*/
public static String getWeekEndTime() {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
if (dayofweek == 1) {
dayofweek += 7;
}
cal.add(Calendar.DATE, 2 - dayofweek);
cal.setTime(cal.getTime());
cal.add(Calendar.DAY_OF_WEEK, 6);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
return sdf.format(cal.getTime());
}
public static String getSomeHoursAgo(int hours) {
Date date = new Date(System.currentTimeMillis() - hours * 3600 * 1000L);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}
public static String getSomeHoursLater(int hours) {
Date date = new Date(System.currentTimeMillis() + hours * 3600 * 1000L);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}
public static String getSomeDaysAgo(int days) {
Date date = new Date(System.currentTimeMillis() - days * 86400 * 1000L);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}
public static String getSomeDaysLater(int days) {
Date date = new Date(System.currentTimeMillis() + days * 86400 * 1000L);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}
public static long getHourLeftMilliseconds() {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:59:59");
try {
Date end = sdf.parse(sdf2.format(now));
return end.getTime() - now.getTime();
} catch (Exception ex) {
}
return 0;
}
public static long getDayLeftMilliseconds() {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String endTime = getTodayEndTime();
try {
Date end = sdf.parse(endTime);
return end.getTime() - now.getTime();
} catch (Exception ex) {
}
return 0;
}
public static long getWeekLeftMilliseconds() {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String endTime = getWeekEndTime();
try {
Date end = sdf.parse(endTime);
return end.getTime() - now.getTime();
} catch (Exception ex) {
}
return 0;
}
public static long getMonthLeftMilliseconds() {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String endTime = getMonthEndTime();
try {
Date end = sdf.parse(endTime);
return end.getTime() - now.getTime();
} catch (Exception ex) {
}
return 0;
}
public static long getYearLeftMilliseconds() {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String endTime = getYearEndTime();
try {
Date end = sdf.parse(endTime);
return end.getTime() - now.getTime();
} catch (Exception ex) {
}
return 0;
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.commoncore.utils;
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import com.codvision.commoncore.exception.BusinessException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
/**
* 登陆密码解密
*
* @author hxl
*/
public class DecPwdUtil {
/**
* AES数据块长度为128位IV偏移量长度需要为16个字符ECB模式不用IV
* 密钥SECRET_KEY根据指定密钥位数分别为16、24、32个字符IV与密钥超过长度则截取不足则在末尾填充'\0'补足
*/
private static final String SECRET_KEY = "8237909036518327";
private static final String IV = "4a3f824766747c27";
public static String encryptAes(String password) {
AES aes = new AES(Mode.CBC, Padding.ZeroPadding, new SecretKeySpec(SECRET_KEY.getBytes(), "AES"), new IvParameterSpec(IV.getBytes()));
try {
return Base64.encode(aes.encrypt(password, StandardCharsets.UTF_8));
} catch (Exception e) {
throw new BusinessException(30001, "密码加密失败!");
}
}
public static String decryptAes(String password) {
AES aes = new AES(Mode.CBC, Padding.ZeroPadding, new SecretKeySpec(SECRET_KEY.getBytes(), "AES"), new IvParameterSpec(IV.getBytes()));
try {
byte[] decrypt = aes.decrypt(Base64.decode(password.getBytes(StandardCharsets.UTF_8)));
return new String(decrypt, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new BusinessException(30001, "密码解密失败!");
}
}
public static void main(String[] args) {
System.out.println(encryptAes("Jcpt@2023"));
}
}

View File

@@ -0,0 +1,143 @@
package com.codvision.commoncore.utils;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
/**
* 加解密工具类
*
* @author codvision
*/
public class Encryption {
private static final String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private static final int scale = 62;
/**
* 进行加密
*
* @return
*/
public String encoding(String password) {
String md5 = "";
try {
// 创建一个md5算法对象
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageByte = ("Codvision" + password).getBytes(StandardCharsets.UTF_8);
// 获得MD5字节数组,16*8=128位
byte[] md5Byte = md.digest(messageByte);
// 转换为16进制字符串
md5 = bytesToHex(md5Byte);
} catch (Exception e) {
e.printStackTrace();
}
return md5;
}
/**
* 二进制转十六进制
*
* @param bytes
* @return
*/
public static String bytesToHex(byte[] bytes) {
StringBuffer hexStr = new StringBuffer();
int num;
for (int i = 0; i < bytes.length; i++) {
num = bytes[i];
if (num < 0) {
num += 256;
}
if (num < 16) {
hexStr.append("0");
}
hexStr.append(Integer.toHexString(num));
}
return hexStr.toString().toUpperCase();
}
public static String getSign(String jsTicket, String nonceStr, long timeStamp, String url) throws Exception {
String planTex = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonceStr + "&timestamp=" + timeStamp + "&url=" + url;
MessageDigest crypt = null;
try {
crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(planTex.getBytes(StandardCharsets.UTF_8));
return byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException e) {
throw new Exception(e.getMessage());
}
}
/**
* 将bytes类型的数据转化为16进制类型
*
* @param digest
* @return
*/
private static String byteToHex(byte[] digest) {
Formatter formatter = new Formatter();
for (byte b : digest) {
formatter.format("%02x", Byte.valueOf(b));
}
String result = formatter.toString();
formatter.close();
return result;
}
/**
* 10进制转62进制
*
* @param num
* @return
*/
public static String encode(int num) {
java.util.Random random = new java.util.Random();
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < 4; i++) {
int a = random.nextInt(10);
sbf.append(a);
}
StringBuilder sb = new StringBuilder();
int remainder = 0;
while (num > scale - 1) {
/**
* 对 scale 进行求余,然后将余数追加至 sb 中由于是从末位开始追加的因此最后需要反转reverse字符串
*/
remainder = Long.valueOf(num % scale).intValue();
sb.append(chars.charAt(remainder));
num = num / scale;
}
sb.append(chars.charAt(Long.valueOf(num).intValue()));
String value = sb.reverse().toString() + sbf;
return value;
}
public static int decode(String str) {
str = str.substring(0, str.length() - 4);
int num = 0;
int index = 0;
for (int i = 0; i < str.length(); i++) {
/**
* 查找字符的索引位置
*/
index = chars.indexOf(str.charAt(i));
/**
* 索引位置代表字符的数值
*/
num += (long) (index * (Math.pow(scale, str.length() - i - 1)));
}
return num;
}
}

View File

@@ -0,0 +1,346 @@
package com.codvision.commoncore.utils;
import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.*;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.URI;
import java.net.UnknownHostException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
/**
* HttpClientUtils
*
* @author Bulbasaur
* @since 2021/7/9 1:40 上午
*/
@Slf4j
public class HttpClientUtils {
/**
* org.apache.http.impl.client.CloseableHttpClient
*/
private static CloseableHttpClient httpClient = null;
private static CloseableHttpClient httpsClient = null;
//这里就直接默认固定了,因为以下三个参数在新建的method中仍然可以重新配置并被覆盖.
/**
* ms毫秒,从池中获取链接超时时间
*/
static final int CONNECTION_REQUEST_TIMEOUT = 30000;
/**
* ms毫秒,建立链接超时时间
*/
static final int CONNECT_TIMEOUT = 60000;
/**
* ms毫秒,读取超时时间
*/
static final int SOCKET_TIMEOUT = 60000;
/**
* 总配置,主要涉及是以下两个参数,如果要作调整没有用到properties会比较后麻烦,但鉴于一经粘贴,随处可用的特点,就不再做依赖性配置化处理了.
* 而且这个参数同一家公司基本不会变动.
* 最大总并发,很重要的参数
*/
static final int MAX_TOTAL = 500;
/**
* 每路并发,很重要的参数
*/
static final int MAX_PER_ROUTE = 100;
/**
* 正常情况这里应该配成MAP或LIST
* 细化配置参数,用来对每路参数做精细化处理,可以管控各ip的流量,比如默认配置请求baidu:80端口最大100个并发链接,
* 每个细化配置之ip(不重要,在特殊场景很有用)
*/
static final String DETAIL_HOST_NAME = "http://www.baidu.com";
/**
* 每个细化配置之port(不重要,在特殊场景很有用)
*/
static final int DETAIL_PORT = 80;
/**
* 每个细化配置之最大并发数(不重要,在特殊场景很有用)
*/
static final int DETAIL_MAX_PER_ROUTE = 100;
private synchronized static CloseableHttpClient getHttpClient() {
if (null == httpClient) {
httpClient = initHttp();
}
return httpClient;
}
private synchronized static CloseableHttpClient getHttpsClient() {
if (null == httpsClient) {
httpsClient = initHttps();
}
return httpsClient;
}
//绕过证书
public static CloseableHttpClient initHttps() {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] arg0,
String arg1) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0,
String arg1) throws CertificateException {
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(
ctx, NoopHostnameVerifier.INSTANCE);
httpsClient = HttpClients.custom()
.setSSLSocketFactory(ssf).build();
return httpsClient;
} catch (Exception e) {
return HttpClients.createDefault();
}
}
/**
* 链接池初始化 这里最重要的一点理解就是. 让CloseableHttpClient 一直活在池的世界里, 但是HttpPost却一直用完就消掉.
* 这样可以让链接一直保持着.
*/
private static CloseableHttpClient initHttp() {
CloseableHttpClient newHotpoint;
//设置连接池
ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", plainsf).register("https", sslsf).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
//将最大连接数增加
cm.setMaxTotal(MAX_TOTAL);
//将每个路由基础的连接增加
cm.setDefaultMaxPerRoute(MAX_PER_ROUTE);
//细化配置开始,其实这里用Map或List的for循环来配置每个链接,在特殊场景很有用.
//将每个路由基础的连接做特殊化配置,一般用不着
HttpHost httpHost = new HttpHost(DETAIL_HOST_NAME, DETAIL_PORT);
//将目标主机的最大连接数增加
cm.setMaxPerRoute(new HttpRoute(httpHost), DETAIL_MAX_PER_ROUTE);
//细化配置结束
//请求重试处理
HttpRequestRetryHandler httpRequestRetryHandler = (exception, executionCount, context) -> {
if (executionCount >= 2) {//如果已经重试了2次就放弃
return false;
}
if (exception instanceof NoHttpResponseException) {//如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof SSLHandshakeException) {//不要重试SSL握手异常
return false;
}
if (exception instanceof InterruptedIOException) {//超时
return false;
}
if (exception instanceof UnknownHostException) {//目标服务器不可达
return false;
}
if (exception instanceof SSLException) {//SSL握手异常
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
//如果请求是幂等的,就再次尝试
return !(request instanceof HttpEntityEnclosingRequest);
};
//配置请求的超时设置
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
newHotpoint = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).setRetryHandler(httpRequestRetryHandler).build();
return newHotpoint;
}
public static String doGet(String url, Map<String, Object> param) {
//httpClient
CloseableHttpClient httpClient;
if (url.startsWith("https://")) {
httpClient = getHttpsClient();
} else {
httpClient = getHttpClient();
}
String resultString = "";
CloseableHttpResponse response = null;
try {
//创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, (String) param.get(key));
}
}
URI uri = builder.build();
//创建http GET请求
HttpGet httpGet = new HttpGet(uri);
log.info(httpGet.toString());
//执行请求
response = httpClient.execute(httpGet);
//判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
log.info(resultString);
} else {
log.error(url + "请求失败:" + response);
}
} catch (Exception e) {
log.error(url + "get请求错误", e);
throw new RuntimeException(e.getMessage());
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
log.error("Get错误", e);
throw new RuntimeException(e.getMessage());
}
}
return resultString;
}
public static String doPost(String url, Map<String, String> headers, String body) {
//httpClient
CloseableHttpClient httpClient;
if (url.startsWith("https://")) {
httpClient = getHttpsClient();
} else {
httpClient = getHttpClient();
}
String resultString = "";
CloseableHttpResponse response = null;
try {
//创建http GET请求
HttpPost httpPost = new HttpPost(url);
log.info(httpPost.toString());
httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
if (CollectionUtil.isNotEmpty(headers)) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue());
}
}
StringEntity stringEntity = new StringEntity(body, "UTF-8");
httpPost.setEntity(stringEntity);
//执行请求
response = httpClient.execute(httpPost);
//判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
log.info(resultString);
} else {
log.error(url + "请求失败:" + response);
}
} catch (Exception e) {
log.error(url + "post请求错误", e);
throw new RuntimeException(e.getMessage());
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
log.error("Post错误", e);
throw new RuntimeException(e.getMessage());
}
}
return resultString;
}
public static String doPost(String url, Map<String, String> headers, Map<String, String> params) {
//httpClient
CloseableHttpClient httpClient;
if (url.startsWith("https://")) {
httpClient = getHttpsClient();
} else {
httpClient = getHttpClient();
}
String resultString = "";
CloseableHttpResponse response = null;
try {
//创建uri
URIBuilder builder = new URIBuilder(url);
if (params != null) {
for (String key : params.keySet()) {
builder.addParameter(key, (String) params.get(key));
}
}
URI uri = builder.build();
HttpPost httpPost = new HttpPost(uri);
log.info(httpPost.toString());
if (CollectionUtil.isNotEmpty(headers)) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue());
}
}
//执行请求
response = httpClient.execute(httpPost);
//判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
log.info(resultString);
} else {
log.error(url + "请求失败:" + response);
}
} catch (Exception e) {
log.error(url + "post请求错误", e);
throw new RuntimeException(e.getMessage());
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
log.error("Post错误", e);
throw new RuntimeException(e.getMessage());
}
}
return resultString;
}
}

View File

@@ -0,0 +1,339 @@
package com.codvision.commoncore.utils;
import org.apache.commons.lang3.StringUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 身份证号码的格式610821-20061222-612-X 由18位数字组成前6位为地址码第7至14位为出生日期码第15至17位为顺序码
* 第18位为校验码。检验码分别是0-10共11个数字当检验码为“10”时为了保证公民身份证号码18位所以用“X”表示。虽然校验码为“X”不能更换但若需全用数字表示只需将18位公民身份号码转换成15位居民身份证号码去掉第7至8位和最后1位3个数码。
* 当今的身份证号码有15位和18位之分。1985年我国实行居民身份证制度当时签发的身份证号码是15位的1999年签发的身份证由于年份的扩展由两位变为四位和末尾加了效验码就成了18位。
* 1前1、2位数字表示所在省份的代码
* 2第3、4位数字表示所在城市的代码
* 3第5、6位数字表示所在区县的代码
* 4第7~14位数字表示出生年、月、日
* 5第15、16位数字表示所在地的派出所的代码
* 6第17位数字表示性别奇数表示男性偶数表示女性
* 7第18位数字是校检码根据一定算法生成
*
* @author codvision
*/
public class IdCardUtil {
/**
* 身份证有效
*/
public static final String VALIDITY = "该身份证有效!";
/**
* 位数不足
*/
public static final String LACKDIGITS = "身份证号码长度应该为15位或18位。请检查是否有多余的空格";
/**
* 最后一位应为数字
*/
public static final String LASTOFNUMBER = "身份证15位号码都应为数字 ; 18位号码除最后一位外都应为数字。";
/**
* 出生日期无效
*/
public static final String INVALIDBIRTH = "身份证出生日期无效。";
/**
* 生日不在有效范围
*/
public static final String INVALIDSCOPE = "身份证生日不在有效范围。";
/**
* 月份无效
*/
public static final String INVALIDMONTH = "身份证月份无效";
/**
* 日期无效
*/
public static final String INVALIDDAY = "身份证日期无效";
/**
* 身份证地区编码错误
*/
public static final String CODINGERROR = "身份证地区编码错误。";
/**
* 身份证校验码无效
*/
public static final String INVALIDCALIBRATION = "身份证校验码无效,不是合法的身份证号码";
private static final Pattern pattern = Pattern.compile("[0-9]*");
private static final Pattern idCardPattern = Pattern.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))?$");
public static Integer getCardSex(String cardCode) {
int sex = 0;
if (StringUtils.isNotEmpty(cardCode)) {
if (cardCode.length() == 18) {
if (Integer.parseInt(cardCode.substring(16).substring(0, 1)) % 2 == 0) {
sex = 2;
} else {
sex = 1;
}
} else if (cardCode.length() == 15) {
if (Integer.parseInt(cardCode.substring(14, 15)) % 2 == 0) {
sex = 2;
} else {
sex = 1;
}
}
}
return sex;
}
/**
* 检验身份证号码是否符合规范
*
* @param idStr 身份证号码
* @return 错误信息或成功信息
*/
public static String cardCodeVerifySimple(String idStr) {
//记录错误信息
String tipInfo = VALIDITY;
String ai = "";
idStr = idStr.trim();
// 判断号码的长度 15位或18位
if (idStr.length() != 15 && idStr.length() != 18) {
tipInfo = LACKDIGITS;
return tipInfo;
}
// 18位身份证前17位位数字如果是15位的身份证则所有号码都为数字
if (idStr.length() == 18) {
ai = idStr.substring(0, 17);
} else if (idStr.length() == 15) {
ai = idStr.substring(0, 6) + "19" + idStr.substring(6, 15);
}
if (isNumeric(ai) == false) {
tipInfo = LASTOFNUMBER;
return tipInfo;
}
// 判断出生年月是否有效
//年份
String strYear = ai.substring(6, 10);
// 月份
String strMonth = ai.substring(10, 12);
// 日期
String strDay = ai.substring(12, 14);
if (isDate(strYear + "-" + strMonth + "-" + strDay) == false) {
tipInfo = INVALIDBIRTH;
return tipInfo;
}
GregorianCalendar gc = new GregorianCalendar();
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
try {
if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150
|| (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
tipInfo = INVALIDSCOPE;
return tipInfo;
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
tipInfo = INVALIDMONTH;
return tipInfo;
}
if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
tipInfo = INVALIDDAY;
return tipInfo;
}
// 判断地区码是否有效
Hashtable<String, String> areacode = getAreaCode();
// 如果身份证前两位的地区码不在Hashtable则地区码有误
if (areacode.get(ai.substring(0, 2)) == null) {
tipInfo = CODINGERROR;
return tipInfo;
}
if (isVarifyCode(ai, idStr) == false) {
tipInfo = INVALIDCALIBRATION;
return tipInfo;
}
return tipInfo;
}
/**
* 根据身份证的号码算出当前身份证持有者的性别和年龄 18位身份证
*
* @return
* @throws Exception
*/
public static Map<String, Object> getCarInfo18W(String cardCode)
throws Exception {
Map<String, Object> map = new HashMap<String, Object>(16);
// 得到年份
String year = cardCode.substring(6).substring(0, 4);
// 得到月份
String yue = cardCode.substring(10).substring(0, 2);
String sex;
// 判断性别
if (Integer.parseInt(cardCode.substring(16).substring(0, 1)) % 2 == 0) {
sex = "";
} else {
sex = "";
}
// 得到当前的系统时间
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
// 当前年份
String fyear = format.format(date).substring(0, 4);
// 月份
String fyue = format.format(date).substring(5, 7);
int age = 0;
// 当前月份大于用户出身的月份表示已过生
if (Integer.parseInt(yue) <= Integer.parseInt(fyue)) {
age = Integer.parseInt(fyear) - Integer.parseInt(year) + 1;
// 当前用户还没过生
} else {
age = Integer.parseInt(fyear) - Integer.parseInt(year);
}
map.put("sex", sex);
map.put("age", age);
return map;
}
/**
* 15位身份证的验证
*
* @param
* @throws Exception
*/
public static Map<String, Object> getCarInfo15W(String card)
throws Exception {
Map<String, Object> map = new HashMap<String, Object>(16);
// 年份
String uyear = "19" + card.substring(6, 8);
// 月份
String uyue = card.substring(8, 10);
// 用户的性别
String usex = card.substring(14, 15);
String sex;
if (Integer.parseInt(usex) % 2 == 0) {
sex = "";
} else {
sex = "";
}
// 得到当前的系统时间
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
// 当前年份
String fyear = format.format(date).substring(0, 4);
// 月份
String fyue = format.format(date).substring(5, 7);
int age = 0;
// 当前月份大于用户出身的月份表示已过生
if (Integer.parseInt(uyue) <= Integer.parseInt(fyue)) {
age = Integer.parseInt(fyear) - Integer.parseInt(uyear) + 1;
// 当前用户还没过生
} else {
age = Integer.parseInt(fyear) - Integer.parseInt(uyear);
}
map.put("sex", sex);
map.put("age", age);
return map;
}
/**
* 判断第18位校验码是否正确 第18位校验码的计算方式
* 1. 对前17位数字本体码加权求和 公式为S = Sum(Ai * Wi), i =
* 0, ... , 16 其中Ai表示第i个位置上的身份证号码数字值Wi表示第i位置上的加权因子其各位对应的值依次为 7 9 10 5 8 4
* 2 1 6 3 7 9 10 5 8 4 2
* 2. 用11对计算结果取模 Y = mod(S, 11)
* 3. 根据模的值得到对应的校验码
* 对应关系为: Y值 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0 X 9 8 7 6 5 4 3 2
*/
private static boolean isVarifyCode(String ai, String idStr) {
String[] varifyCode = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
String[] wi = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"};
int sum = 0;
for (int i = 0; i < 17; i++) {
sum = sum + Integer.parseInt(String.valueOf(ai.charAt(i))) * Integer.parseInt(wi[i]);
}
int modValue = sum % 11;
String strVerifyCode = varifyCode[modValue];
ai = ai + strVerifyCode;
if (idStr.length() == 18) {
return ai.equals(idStr) != false;
}
return true;
}
/**
* 将所有地址编码保存在一个Hashtable中
*
* @return Hashtable 对象
*/
private static Hashtable<String, String> getAreaCode() {
Hashtable<String, String> hashtable = new Hashtable<String, String>();
hashtable.put("11", "北京");
hashtable.put("12", "天津");
hashtable.put("13", "河北");
hashtable.put("14", "山西");
hashtable.put("15", "内蒙古");
hashtable.put("21", "辽宁");
hashtable.put("22", "吉林");
hashtable.put("23", "黑龙江");
hashtable.put("31", "上海");
hashtable.put("32", "江苏");
hashtable.put("33", "浙江");
hashtable.put("34", "安徽");
hashtable.put("35", "福建");
hashtable.put("36", "江西");
hashtable.put("37", "山东");
hashtable.put("41", "河南");
hashtable.put("42", "湖北");
hashtable.put("43", "湖南");
hashtable.put("44", "广东");
hashtable.put("45", "广西");
hashtable.put("46", "海南");
hashtable.put("50", "重庆");
hashtable.put("51", "四川");
hashtable.put("52", "贵州");
hashtable.put("53", "云南");
hashtable.put("54", "西藏");
hashtable.put("61", "陕西");
hashtable.put("62", "甘肃");
hashtable.put("63", "青海");
hashtable.put("64", "宁夏");
hashtable.put("65", "新疆");
hashtable.put("71", "台湾");
hashtable.put("81", "香港");
hashtable.put("82", "澳门");
hashtable.put("91", "国外");
return hashtable;
}
/**
* 判断字符串是否为数字,0-9重复0次或者多次
*
* @param strnum
* @return true, 符合; false, 不符合。
*/
private static boolean isNumeric(String strnum) {
Matcher isNum = pattern.matcher(strnum);
return isNum.matches();
}
/**
* 功能判断字符串出生日期是否符合正则表达式包括年月日闰年、平年和每月31天、30天和闰月的28天或者29天
*
* @param strDate
* @return true, 符合; false, 不符合。
*/
public static boolean isDate(String strDate) {
Matcher m = idCardPattern.matcher(strDate);
return m.matches();
}
}

View File

@@ -0,0 +1,82 @@
package com.codvision.commoncore.utils;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.CryptoException;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import java.security.*;
/**
* @author hxl
*/
public class LySign {
/**
* 算法
*/
protected String algorithm;
protected String algorithmAfterWith;
/**
* 公钥
*/
protected PublicKey publicKey;
/**
* 私钥
*/
protected PrivateKey privateKey;
/**
* 签名,用于签名和验证
*/
protected Signature signature;
public LySign(SignAlgorithm algorithmE, byte[] privateKey, byte[] publicKey) {
this.algorithm = algorithmE.getValue();
this.algorithmAfterWith = KeyUtil.getAlgorithmAfterWith(this.algorithm);
this.privateKey = SecureUtil.generatePrivateKey(this.algorithmAfterWith, privateKey);
this.publicKey = SecureUtil.generatePublicKey(this.algorithmAfterWith, publicKey);
try {
this.signature = Signature.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
throw new CryptoException(e);
}
}
public static LySign of(SignAlgorithm algorithm, String privateKey, String publicKey, boolean hexStr) {
byte[] privateBytes;
byte[] publicBytes;
if (hexStr) {
privateBytes = HexUtil.decodeHex(privateKey);
publicBytes = HexUtil.decodeHex(publicKey);
} else {
privateBytes = Base64.decode(privateKey);
publicBytes = Base64.decode(publicKey);
}
return new LySign(algorithm, privateBytes, publicBytes);
}
public String sign(String data) {
try {
signature.initSign(privateKey);
signature.update(data.getBytes());
byte[] sign = signature.sign();
return HexUtil.encodeHexStr(sign, false);
} catch (InvalidKeyException | SignatureException e) {
throw new CryptoException(e);
}
}
public boolean verify(String data, String sign) {
try {
signature.initVerify(publicKey);
signature.update(data.getBytes());
return signature.verify(HexUtil.decodeHex(sign));
} catch (InvalidKeyException | SignatureException e) {
throw new CryptoException(e);
}
}
}

View File

@@ -0,0 +1,145 @@
package com.codvision.commoncore.utils;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @author zjm
* @version V1.0
* @Package com.codvision.serverboot.util
* @date 2020/3/4 10:00
* @Copyright © 2017-2020 杭州码全科技有限公司
*/
public class Md5Utils {
/**
* md5加密
*
* @param message 内容
* @return 摘要
*/
public static String md5Encode(String message) {
String temp = "";
try {
MessageDigest md5Digest = MessageDigest.getInstance("MD5");
byte[] d = md5Digest.digest(message.getBytes());
temp = converByteToHexString(d);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return temp;
}
/**
* 转换byte到16进制
*
* @param b 要转换的byte
* @return 16进制对应的字符
*/
private static String converByteToHexString(byte[] b) {
String result = "";
for (int i = 1; i < b.length; i++) {
int temp = b[i] & 0xff;
String tempHex = Integer.toHexString(temp);
if (tempHex.length() < 2) {
result += "" + tempHex;
} else {
result += tempHex;
}
}
return result;
}
/**
* 获取摘要
*
* @param str 内容
* @return 摘要
*/
public static String getMd5(String str) {
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算md5函数
md.update(str.getBytes());
String md5 = new BigInteger(1, md.digest()).toString(16);
return fillMd5(md5);
} catch (Exception e) {
throw new RuntimeException("MD5加密错误:" + e.getMessage(), e);
}
}
/**
* 填充摘要
*
* @param md5 摘要
* @return 填充后的摘要
*/
public static String fillMd5(String md5) {
return md5.length() == 32 ? md5 : fillMd5("0" + md5);
}
/**
* 使用指定哈希算法计算摘要信息
*
* @param content 内容
* @param algorithm 哈希算法
* @return 内容摘要
*/
public static String getMd5Digest(String content, String algorithm) {
try {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
messageDigest.update(content.getBytes(StandardCharsets.UTF_8));
return bytesToHexString(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* 将字节数组转换成16进制字符串
*
* @param bytes 即将转换的数据
* @return 16进制字符串
*/
private static String bytesToHexString(byte[] bytes) {
StringBuffer sb = new StringBuffer(bytes.length);
String temp = null;
for (int i = 0; i < bytes.length; i++) {
temp = Integer.toHexString(0xFF & bytes[i]);
if (temp.length() < 2) {
sb.append(0);
}
sb.append(temp);
}
return sb.toString();
}
public static String md532Encode(String s) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytes = md.digest(s.getBytes(StandardCharsets.UTF_8));
return toHex(bytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String toHex(byte[] bytes) {
final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
StringBuilder ret = new StringBuilder(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
}
return ret.toString();
}
}

View File

@@ -0,0 +1,54 @@
package com.codvision.commoncore.utils;
import com.codvision.commoncore.enums.NetworkData;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 网络工具类
* Created by mrhe on 2018/2/17.
*/
public class NetworkUtils {
/**
* 获取请求主机IP地址,如果通过代理进来则透过防火墙获取真实IP地址;
*
* @param request
* @return
* @throws IOException
*/
public static String getIpAddress(HttpServletRequest request) throws IOException {
// 获取请求主机IP地址,如果通过代理进来则透过防火墙获取真实IP地址
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} else if (ip.length() > 15) {
String[] ips = ip.split(",");
for (int index = 0; index < ips.length; index++) {
String strIp = ips[index];
if (!("unknown".equalsIgnoreCase(strIp))) {
ip = strIp;
break;
}
}
}
return ip.equals(NetworkData.NET_WORK_ID.getDesc()) ? "127.0.0.1" : ip;
}
}

View File

@@ -0,0 +1,46 @@
package com.codvision.commoncore.utils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* @author zjm
* @version V1.0
* @Package com.codvision.serverboot.util
* @date 2020/3/4 9:48
* @Copyright © 2017-2020 杭州码全科技有限公司
*/
public class ParamUtil {
public static boolean isKeyExist(Map<String, Object> params, String key) {
return isKeyExist(params, key, true);
}
public static boolean isKeyExist(Map<String, Object> params, String key, boolean ignoreEmptyValue) {
if (ignoreEmptyValue) {
return params.containsKey(key) && null != params.get(key) && StringUtils.isNotEmpty(params.get(key).toString());
} else {
return params.containsKey(key) && null != params.get(key);
}
}
public static Map<String, String> objectToMap(Object obj) throws IllegalAccessException {
Map<String, String> map = new HashMap<String, String>(16);
Class<?> clazz = obj.getClass();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String fieldName = field.getName();
if (!(ObjectUtils.isEmpty(field.get(obj)))) {
Object value = field.get(obj);
map.put(fieldName, String.valueOf(value));
}
}
return map;
}
}

View File

@@ -0,0 +1,36 @@
package com.codvision.commoncore.utils;
import com.codvision.commoncore.common.ResponseEntity;
import com.codvision.commoncore.exception.BusinessException;
import lombok.NonNull;
/**
* @author hxl
*/
public final class Preconditions {
/**
* @param expression 布尔表达式
* @param code 自定义响应状态码
* @param errorMsg 检查失败时使用的异常消息
* @throws BusinessException if {@code expression} is false
*/
public static void checkArgument(boolean expression, int code, @NonNull Object errorMsg) {
if (!expression) {
throw new BusinessException(code, String.valueOf(errorMsg));
}
}
public static void checkArgument(boolean expression, @NonNull Object errorMsg) {
if (!expression) {
throw new BusinessException(String.valueOf(errorMsg));
}
}
public static void checkArgument(boolean expression, int code) {
if (!expression) {
throw new BusinessException(code, new ResponseEntity<>().setCode(code).getMessage());
}
}
}

View File

@@ -0,0 +1,45 @@
package com.codvision.commoncore.utils;
import java.util.Random;
/**
* @author: fuyuaaaaa
* @description: 随机数 工具 类
* @program: smart-rear
* @creat: 2018-09-21 10:10
**/
public class RandomUtil {
/**
* 获取6位数验证码
*
* @return 验证码
*/
public static String getVerificationCode() {
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 6; i++) {
int a = random.nextInt(10);
sb.append(a);
}
return sb.toString();
}
/**
* 获取指定长度验证码
*
* @param length 长度
* @return 验证码
*/
public static String getRandomStr(int length) {
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random random = new Random();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < length; i++) {
int number = random.nextInt(26);
stringBuilder.append(str.charAt(number));
}
return stringBuilder.toString();
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.commoncore.utils;
import com.codvision.commoncore.common.ResponseEntity;
import org.apache.commons.lang3.ObjectUtils;
/**
* 响应工具类
*
* @author lingee
* @date 2023/7/18
*/
public class ResponseUtil {
/**
* 判断请求是否成功
*
* @param response
* @return
*/
public static boolean isSuccess(ResponseEntity response) {
if (ObjectUtils.isNotEmpty(response)
&& response.getCode() == 200
&& ObjectUtils.isNotEmpty(response.getData())) {
return true;
}
return false;
}
public static boolean isSuccessNotData(ResponseEntity response) {
if (ObjectUtils.isNotEmpty(response)
&& response.getCode() == 200) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,49 @@
package com.codvision.commoncore.utils;
import java.util.List;
/**
* 树节点父类
* <p>
* 所有需要使用{@linkplain TreeUtils}工具类形成树形结构等操作的节点都需要实现该接口
*
* @author lingee
* @date 2024/04/24
*/
public interface TreeNode<T> {
/**
* 获取节点id
*
* @return 树节点id
*/
T id();
/**
* 获取该节点的父节点id
*
* @return 父节点id
*/
T parentId();
/**
* 是否是根节点
*
* @return true根节点
*/
boolean root();
/**
* 设置节点的子节点列表
*
* @param children 子节点
*/
void setChildren(List<? extends TreeNode<T>> children);
/**
* 获取所有子节点
*
* @return 子节点列表
*/
List<? extends TreeNode<T>> getChildren();
}

View File

@@ -0,0 +1,117 @@
package com.codvision.commoncore.utils;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
/**
* 树形结构工具类
*
* @author lingee
* @date 2024/04/24
*/
public class TreeUtils {
/**
* 根据所有树节点列表,生成含有所有树形结构的列表
*
* @param nodes 树形节点列表
* @param <T> 节点类型
* @return 树形结构列表
*/
public static <T extends TreeNode<?>> List<T> generateTrees(List<T> nodes) {
List<T> roots = new ArrayList<>();
for (Iterator<T> ite = nodes.iterator(); ite.hasNext(); ) {
T node = ite.next();
if (node.root()) {
roots.add(node);
// 从所有节点列表中删除该节点,以免后续重复遍历该节点
ite.remove();
}
}
if (CollectionUtils.isEmpty(roots)) {
roots.addAll(nodes);
}
roots.forEach(r -> {
setChildren(r, nodes);
});
return roots;
}
/**
* 从所有节点列表中查找并设置parent的所有子节点
*
* @param parent 父节点
* @param nodes 所有树节点列表
*/
public static <T extends TreeNode> void setChildren(T parent, List<T> nodes) {
List<T> children = new ArrayList<>();
Object parentId = parent.id();
for (Iterator<T> ite = nodes.iterator(); ite.hasNext(); ) {
T node = ite.next();
if (Objects.equals(node.parentId(), parentId)) {
children.add(node);
// 从所有节点列表中删除该节点,以免后续重复遍历该节点
ite.remove();
}
}
// 如果孩子为空,则直接返回,否则继续递归设置孩子的孩子
if (children.isEmpty()) {
return;
}
parent.setChildren(children);
children.forEach(m -> {
// 递归设置子节点
setChildren(m, nodes);
});
}
/**
* 移除父节点下的所有子节点
*
* @param parentId 父级id
* @param nodes 节点列表
* @param <T>
* @return
*/
public static <T extends TreeNode> List<Integer> removeChildren(Integer parentId, List<T> nodes) {
List<Integer> removeIds = new ArrayList<>();
for (Iterator<T> ite = nodes.iterator(); ite.hasNext(); ) {
T node = ite.next();
if (Objects.equals(node.parentId(), parentId)) {
removeIds.add((Integer) node.id());
ite.remove();
}
}
return removeIds;
}
/**
* 将parent的所有叶子节点填充至leafs列表中
*
* @param parent 父节点
* @param leafs 叶子节点列表
* @param <T> 实际节点类型
*/
public static <T extends TreeNode> void fillLeaf(T parent, List<T> leafs) {
List<T> children = parent.getChildren();
// 如果节点没有子节点则说明为叶子节点
if (CollectionUtils.isEmpty(children)) {
leafs.add(parent);
return;
}
// 递归调用子节点,查找叶子节点
for (T child : children) {
fillLeaf(child, leafs);
}
}
}