master
xiwa 2023-10-03 10:23:43 +08:00
parent e074b1026c
commit 8233338198
176 changed files with 11409 additions and 86 deletions

0
.gitee/ISSUE_TEMPLATE.zh-CN.md Normal file → Executable file
View File

0
.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md Normal file → Executable file
View File

45
.gitignore vendored Normal file → Executable file
View File

@ -1,18 +1,33 @@
# Build and Release Folders
bin-debug/
bin-release/
[Oo]bj/
[Bb]in/
# Compiled class file
*.class
# Other files and folders
.settings/
# Log file
log
*.log
# Executables
*.swf
*.air
*.ipa
*.apk
# BlueJ files
*.ctxt
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
.idea
target
*.iml
data/elasticsearch
.init
*.db
.flattened-pom.xml
.DS_Store
dependency-reduced-pom.xml

0
LICENSE Normal file → Executable file
View File

View File

@ -1,36 +0,0 @@
# iot-iita-core
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

37
README.md Normal file → Executable file
View File

@ -1,39 +1,6 @@
# iot-iita-core
#### 介绍
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
[iot-iita](https://gitee.com/open-iita/iotkit-parent) 中使用的核心库
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
编译iot-iita时请先install本仓库。

113
iot-common-core/pom.xml Executable file
View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>iot-iita-core</artifactId>
<groupId>cc.iotkit</groupId>
<version>1.0.0</version>
</parent>
<artifactId>iot-common-core</artifactId>
<description>
此模块为通用业务逻辑或工具类
</description>
<dependencies>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- JSON工具类 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
<!-- Spring框架基本的核心工具 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!--常用工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
</dependency>
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,45 @@
package cc.iotkit.common.api;
import cc.iotkit.common.utils.MapstructUtils;
import lombok.Data;
import java.util.Date;
/**
* Entity
*
* @author Lion Li
*/
@Data
public class BaseDto {
/**
*
*/
private Long createDept;
/**
*
*/
private Long createBy;
/**
*
*/
private Date createTime;
/**
*
*/
private Long updateBy;
/**
*
*/
private Date updateTime;
public <T> T to(Class<T> tClass) {
return MapstructUtils.convert(this, tClass);
}
}

View File

@ -0,0 +1,92 @@
package cc.iotkit.common.api;
import cc.iotkit.common.utils.MapstructUtils;
import cn.hutool.core.util.IdUtil;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import java.util.Map;
import lombok.*;
import java.io.Serializable;
import java.util.Objects;
/**
* @author: Longjun.Tu
* @description:
* @date:created in 2023/5/10 23:15
* @modificed by:
*/
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class PageRequest<T> extends Request<T> implements Serializable {
/**
*
*/
@Min(1)
@NotNull
private Integer pageSize;
/**
*
*/
@Min(1)
@Max(100)
@NotNull
private Integer pageNum;
/**
* key valuedescasc
*/
private Map<String, String> sortMap;
/**
*
*/
public static final int DEFAULT_PAGE_NUM = 1;
/**
*
*/
public static final int DEFAULT_PAGE_SIZE = 20;
public static <T> PageRequest<T> of(T data) {
PageRequest<T> pageRequest = new PageRequest<>();
pageRequest.setPageSize(DEFAULT_PAGE_SIZE);
pageRequest.setPageNum(DEFAULT_PAGE_NUM);
pageRequest.setData(data);
pageRequest.setRequestId(IdUtil.simpleUUID());
return pageRequest;
}
public <DTO> PageRequest<DTO> to(Class<DTO> dtoClass) {
PageRequest<DTO> pageRequest = new PageRequest<>();
if (Objects.nonNull(getData())) {
pageRequest.setData(MapstructUtils.convert(getData(), dtoClass));
}
pageRequest.setPageNum(this.getPageNum());
pageRequest.setPageSize(this.getPageSize());
pageRequest.setRequestId(this.getRequestId());
pageRequest.setSortMap(this.getSortMap());
return pageRequest;
}
public Integer getPageSize() {
return pageSize == null ? DEFAULT_PAGE_SIZE : pageSize;
}
public Integer getPageNum() {
return pageNum == null ? DEFAULT_PAGE_NUM : pageNum;
}
public Integer getOffset() {
return (getPageNum() - 1) * getPageSize();
}
}

View File

@ -0,0 +1,15 @@
package cc.iotkit.common.api;
import lombok.Data;
/**
* @author: Longjun.Tu
* @description:
* @date:created in 2023/5/10 23:16
* @modificed by:
*/
@Data
public class PageRequestEmpty {
private Integer pageNum = 1;
private Integer pageSize = 20;
}

View File

@ -0,0 +1,31 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.api;
import cc.iotkit.common.utils.MapstructUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Paging<T> {
private long total;
private List<T> rows;
public <VO> Paging<VO> to(Class<VO> voClass) {
return MapstructUtils.convert(this, voClass);
}
}

View File

@ -0,0 +1,29 @@
package cc.iotkit.common.api;
import cn.hutool.core.util.IdUtil;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serializable;
/**
* @author: Longjun.Tu
* @description:
* @date:created in 2023/5/10 23:14
* @modificed by:
*/
@Data
public class Request<T> extends RequestEmpty implements Serializable {
@Valid
@NotNull
private T data;
public static <T> Request<T> of(T data) {
Request<T> request = new Request<>();
request.setData(data);
request.setRequestId(IdUtil.simpleUUID());
return request;
}
}

View File

@ -0,0 +1,27 @@
package cc.iotkit.common.api;
import cn.hutool.core.util.IdUtil;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serializable;
/**
* @author: Longjun.Tu
* @description:
* @date:created in 2023/5/10 23:12
* @modificed by:
*/
@Data
public class RequestEmpty implements Serializable {
@NotBlank
private String requestId;
public static RequestEmpty of() {
RequestEmpty request = new RequestEmpty();
request.setRequestId(IdUtil.simpleUUID());
return request;
}
}

View File

@ -0,0 +1,15 @@
package cc.iotkit.common.api;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Response {
private Integer code;
private String message;
private Object data;
private String requestId;
}

View File

@ -0,0 +1,25 @@
package cc.iotkit.common.constant;
/**
* key
*
* @author Lion Li
*/
public interface CacheConstants {
/**
* 线 redis key
*/
String ONLINE_TOKEN_KEY = "online_tokens:";
/**
* cache key
*/
String SYS_CONFIG_KEY = "sys_config:";
/**
* cache key
*/
String SYS_DICT_KEY = "sys_dict:";
}

View File

@ -0,0 +1,63 @@
package cc.iotkit.common.constant;
/**
*
* <p>
* key cacheNames#ttl#maxIdleTime#maxSize
* <p>
* ttl 0 0
* maxIdleTime LRU 0 0
* maxSize LRU 0 0
* <p>
* : test#60stest#0#60stest#0#1m#1000test#1h#0#500
*
* @author Lion Li
*/
public interface CacheNames {
/**
*
*/
String DEMO_CACHE = "demo:cache#60s#10m#20";
/**
*
*/
String SYS_CONFIG = "sys_config";
/**
*
*/
String SYS_DICT = "sys_dict";
/**
*
*/
String SYS_TENANT = GlobalConstants.GLOBAL_REDIS_KEY + "sys_tenant#30d";
/**
*
*/
String SYS_USER_NAME = "sys_user_name#30d";
/**
*
*/
String SYS_DEPT = "sys_dept#30d";
/**
* OSS
*/
String SYS_OSS = "sys_oss#30d";
/**
* OSS
*/
String SYS_OSS_CONFIG = "sys_oss_config";
/**
* 线
*/
String ONLINE_TOKEN = "online_tokens";
}

View File

@ -0,0 +1,282 @@
package cc.iotkit.common.constant;
/**
*
*
* @author ruoyi
*/
public interface Constants {
/**
* UTF-8
*/
String UTF8 = "UTF-8";
/**
* GBK
*/
String GBK = "GBK";
/**
* www
*/
String WWW = "www.";
/**
* http
*/
String HTTP = "http://";
/**
* https
*/
String HTTPS = "https://";
/**
*
*/
String SUCCESS = "0";
/**
*
*/
String FAIL = "1";
/**
*
*/
String LOGIN_SUCCESS = "Success";
/**
*
*/
String LOGOUT = "Logout";
/**
*
*/
String REGISTER = "Register";
/**
*
*/
String LOGIN_FAIL = "Error";
/**
*
*/
Integer CAPTCHA_EXPIRATION = 2;
String ACCOUNT_SECRET = "3n1z33kzvpgz1foijpkepyd3e8tw84us";
String CACHE_PRODUCT = "product_cache";
String CACHE_DEVICE_INFO = "device_info_cache";
String CACHE_DEVICE_STATS = "device_stats_cache";
String CACHE_CATEGORY = "category_cache";
String CACHE_SPACE = "space_cache";
String CACHE_THING_MODEL = "thing_model_cache";
String CACHE_USER_INFO = "user_info_cache";
String CACHE_OAUTH_CLIENT = "oauth_client_cache";
String CACHE_PRODUCT_SCRIPT = "product_script_cache";
/**
*
*/
String ROLE_ADMIN = "iot_admin";
/**
*
*/
String ROLE_WRITE = "iot_write";
/**
*
*/
String ROLE_SYSTEM = "iot_system";
/**
* C
*/
String ROLE_CLIENT = "iot_client";
/**
* C
*/
String PWD_CLIENT_USER = "c123456";
/**
*
*/
String PWD_SYSTEM_USER = "s123456";
/**
* topic
*/
String THING_MODEL_MESSAGE_TOPIC = "device_thing";
/**
* topic
*/
String DEVICE_PROPERTY_REPORT_TOPIC = "device_property_report";
/**
* topic
*/
String DEVICE_CONFIG_TOPIC = "device_config";
/**
* httptopic
*/
String HTTP_CONSUMER_DEVICE_INFO_TOPIC = "device_info:";
/**
*
*/
String PERMISSION_WRITE = "write";
/**
* key
*/
String PROPERTY_CACHE_KEY = "str:iotkit:device:property:%s";
/**
*
*/
enum ThirdPlatform {
dueros("小度"),
aligenie("天猫精灵"),
miiot("小爱");
public String desc;
ThirdPlatform(String desc) {
this.desc = desc;
}
}
/**
* openUid
*/
enum ThirdOpenUid {
duerosOpenUid("小度OpenUid"),
aligenieOpenUid("天猫精灵OpenUid"),
miiotOpenUid("小爱OpenUid");
public String desc;
ThirdOpenUid(String desc) {
this.desc = desc;
}
}
interface API_DEVICE {
/**
* -
*/
String BASE = "/device";
/**
* -
*/
String LIST = "/list/{size}/{page}";
/**
* -
*/
String DETAIL = "/{deviceId}/detail";
/**
* -
*/
String SET_PROPERTIES = "/{deviceId}/service/property/set";
/**
* -
*/
String INVOKE_SERVICE = "/{deviceId}/service/{service}/invoke";
/**
* -
*/
String INVOKE_SERVICE_PROPERTY_GET = "/service/property/get";
/**
* OTA
*/
String OTA_UPGRADE_PACKAGE = "{deviceId}/ota/upgrade/package/";
/**
* OTA
*/
String OTA_UPGRADE_INFORM = "{deviceId}/ota/upgrade/inform/";
}
interface API_SPACE {
/**
* -
*/
String BASE = "/space";
/**
* 使
*/
String RECENT_DEVICES = "/myRecentDevices";
/**
*
*/
String GET_COLLECT_DEVICES = "/getCollectDevices";
/**
*
*/
String SPACE_DEVICES = "/myDevices/{spaceId}";
/**
*
*/
String FIND_DEVICE = "/findDevice";
/**
*
*/
String ADD_DEVICE = "/addDevice";
/**
*
*/
String REMOVE_DEVICE = "/removeDevice";
/**
*
*/
String SAVE_DEVICE = "/saveDevice";
/**
* /
*/
String COLLECT_DEVICE = "/collectDevice";
/**
*
*/
String GET_DEVICE = "/device/{deviceId}";
/**
* openUid
*/
String SET_OPEN_UID = "/setOpenUid";
}
}

View File

@ -0,0 +1,34 @@
package cc.iotkit.common.constant;
/**
* key (key)
*
* @author Lion Li
*/
public interface GlobalConstants {
/**
* redis key (key)
*/
String GLOBAL_REDIS_KEY = "global:";
/**
* redis key
*/
String CAPTCHA_CODE_KEY = GLOBAL_REDIS_KEY + "captcha_codes:";
/**
* redis key
*/
String REPEAT_SUBMIT_KEY = GLOBAL_REDIS_KEY + "repeat_submit:";
/**
* redis key
*/
String RATE_LIMIT_KEY = GLOBAL_REDIS_KEY + "rate_limit:";
/**
* redis key
*/
String PWD_ERR_CNT_KEY = GLOBAL_REDIS_KEY + "pwd_err_cnt:";
}

View File

@ -0,0 +1,93 @@
package cc.iotkit.common.constant;
/**
*
*
* @author Lion Li
*/
public interface HttpStatus {
/**
*
*/
int SUCCESS = 200;
/**
*
*/
int CREATED = 201;
/**
*
*/
int ACCEPTED = 202;
/**
*
*/
int NO_CONTENT = 204;
/**
*
*/
int MOVED_PERM = 301;
/**
*
*/
int SEE_OTHER = 303;
/**
*
*/
int NOT_MODIFIED = 304;
/**
*
*/
int BAD_REQUEST = 400;
/**
*
*/
int UNAUTHORIZED = 401;
/**
* 访
*/
int FORBIDDEN = 403;
/**
*
*/
int NOT_FOUND = 404;
/**
* http
*/
int BAD_METHOD = 405;
/**
*
*/
int CONFLICT = 409;
/**
*
*/
int UNSUPPORTED_TYPE = 415;
/**
*
*/
int ERROR = 500;
/**
*
*/
int NOT_IMPLEMENTED = 501;
/**
*
*/
int WARN = 601;
}

View File

@ -0,0 +1,45 @@
package cc.iotkit.common.constant;
/**
*
*
* @author Lion Li
*/
public interface TenantConstants {
/**
*
*/
String NORMAL = "0";
/**
*
*/
String DISABLE = "1";
/**
* ID
*/
Long SUPER_ADMIN_ID = 1L;
/**
* roleKey
*/
String SUPER_ADMIN_ROLE_KEY = "superadmin";
/**
* roleKey
*/
String TENANT_ADMIN_ROLE_KEY = "admin";
/**
*
*/
String TENANT_ADMIN_ROLE_NAME = "管理员";
/**
* ID
*/
String DEFAULT_TENANT_ID = "000000";
}

View File

@ -0,0 +1,132 @@
package cc.iotkit.common.constant;
/**
*
*
* @author ruoyi
*/
public interface UserConstants {
/**
*
*/
String SYS_USER = "SYS_USER";
/**
*
*/
String NORMAL = "0";
/**
*
*/
String EXCEPTION = "1";
/**
*
*/
String USER_NORMAL = "0";
/**
*
*/
String USER_DISABLE = "1";
/**
*
*/
String ROLE_NORMAL = "0";
/**
*
*/
String ROLE_DISABLE = "1";
/**
*
*/
String DEPT_NORMAL = "0";
/**
*
*/
String DEPT_DISABLE = "1";
/**
*
*/
String DICT_NORMAL = "0";
/**
*
*/
String YES = "Y";
/**
*
*/
String YES_FRAME = "0";
/**
*
*/
String NO_FRAME = "1";
/**
*
*/
String MENU_NORMAL = "0";
/**
*
*/
String MENU_DISABLE = "1";
/**
*
*/
String TYPE_DIR = "M";
/**
*
*/
String TYPE_MENU = "C";
/**
*
*/
String TYPE_BUTTON = "F";
/**
* Layout
*/
String LAYOUT = "Layout";
/**
* ParentView
*/
String PARENT_VIEW = "ParentView";
/**
* InnerLink
*/
String INNER_LINK = "InnerLink";
/**
*
*/
int USERNAME_MIN_LENGTH = 2;
int USERNAME_MAX_LENGTH = 20;
/**
*
*/
int PASSWORD_MIN_LENGTH = 5;
int PASSWORD_MAX_LENGTH = 20;
/**
* ID
*/
Long SUPER_ADMIN_ID = 1L;
}

View File

@ -0,0 +1,32 @@
package cc.iotkit.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
*
* @author Lion Li
*/
@Getter
@AllArgsConstructor
public enum DeviceType {
/**
* pc
*/
PC("pc"),
/**
* app
*/
APP("app"),
/**
*
*/
XCX("xcx");
private final String device;
}

View File

@ -0,0 +1,133 @@
package cc.iotkit.common.enums;
/**
* @author tfd
*
*/
public enum ErrCode implements IEnum {
/**
*
*/
PARAMS_EXCEPTION(10000001, "参数异常"),
SYSTEM_EXCEPTION(10000002, "系统异常"),
UNKNOWN_EXCEPTION(10000003, "未知异常"),
SYSTEM_ERROR(10000004, "服务器内部错误"),
METHOD_NOT_ALLOWED(10000005, "请求方法不支持"),
NOT_FOUND(10000006, "请求资源不存在"),
FORBIDDEN(10000007, "请求被拒绝"),
UNAUTHORIZED_EXCEPTION(10000008, "未授权访问"),
UNSUPPORTED_OPERATION_EXCEPTION(10000009, "方法未实现"),
DATA_NOT_EXIST(10000010, "数据不存在"),
/**
* openapi
*/
IDENTIFIER_ERROR(20000000, "签名验证失败"),
API_LOGIN_ERROR(20000000, "登录验证失败"),
/**
*
*/
GET_COMPONENT_INSTANCE_ERROR(30000001, "获取通讯组件实例失败"),
GET_COMPONENT_SCRIPT_ERROR(30000002, "获取通讯组件脚本失败"),
GET_CONVERT_ERROR(30000003, "获取转换器失败"),
GET_SPI_COMPONENT_ERROR(30000004, "获取组件CLASS失败"),
GET_SPI_CONVERT_ERROR(30000005, "获取转换器CLASS失败"),
COMPONENT_NOT_FOUND(30000006, "通讯组件不存在"),
SEND_DESTINATION_NOT_FOUND(30000007, "发送目标不存在"),
MSG_CONVERT_ERROR(30000008, "消息转换失败"),
DEVICE_REGISTER_ERROR(30000009, "设备注册失败"),
COMPONENT_ID_BLANK(30000010, "通讯组件ID为空"),
COMPONENT_JAR_NOT_FOUND(30000011, "通讯组件JAR包为空"),
COMPONENT_ALREADY(30000012, "通讯组件已经存在"),
SAVE_COMPONENT_SCRIPT_ERROR(30000013, "保存通讯组件脚本失败"),
SAVE_CONVERT_SCRIPT_ERROR(30000014, "保存转换器脚本失败"),
ADD_COMPONENT_ERROR(30000015, "添加通讯组件失败"),
ADD_CONVERT_ERROR(30000016, "添加转换器失败"),
CONVERT_NOT_FOUND(30000017, "转换器不存在"),
DELETE_CONVERT_ERROR(30000018, "删除转换器失败"),
DELETE_COMPONENT_ERROR(30000019, "删除通讯组件失败"),
PRODUCT_SECRET_ERROR(30000020, "产品密钥错误"),
COMPONENT_START_ERROR(30000021, "通讯组件启动失败"),
INIT_PRODUCER_ERROR(30000022, "初始化MQ生产者失败"),
SEND_MSG_ERROR(30000023, "发送消息失败"),
PLUGIN_ROUTER_NOT_FOUND(30000100, "未找到插件路由"),
PLUGIN_INSTANCE_NOT_FOUND(30000101, "插件实例未找到"),
PLUGIN_SERVICE_NOT_FOUND(30000102, "插件设备服务未找到"),
PLUGIN_INSTALL_FAILED(30000103, "插件安装失败"),
DEVICE_ACTION_FAILED(30000200, "设备动作执行失败"),
/**
*
*/
RESOURCE_FILE_NOT_FOUND(40000000, "资源包为空"),
BIG_SCREEN_NOT_FOUND(40000001, "大屏不存在"),
BIG_SCREEN_ALREADY(40000002, "大屏已存在"),
ADD_BIG_SCREEN_ERROR(40000003, "保存大屏失败"),
DELETE_BIG_SCREEN_ERROR(40000004, "删除大屏资源失败"),
SCREEN_API_NOT_FOUND(40000005, "大屏接口不存在"),
ADD_SCREEN_API_ERROR(40000006, "添加大屏接口失败"),
SCREEN_PUBLISH_ERROR(40000007, "大屏发布失败"),
API_LIST_BLANK(40000008, "接口列表为空"),
/**
*
*/
ID_BLANK(50000001, "ID为空"),
TASK_NOT_SUPPORT_RENEW(50000002, "任务不支持续订"),
GROUP_ALREADY(50000003, "分组已经存在"),
GROUP_NOT_FOUND(50000004, "分组不存在"),
PRODUCT_NOT_FOUND(50000005, "产品不存在"),
DEVICE_NOT_FOUND(50000006, "设备不存在"),
DEVICE_OFFLINE(50000007, "设备已离线"),
DEVICE_ALREADY(50000008, "设备已存在"),
MODEL_DEVICE_ALREADY(50000009, "设备DN已存在"),
DEVICE_HAS_ASSOCIATED(50000010, "设备已关联"),
MODEL_ALREADY(50000011, "型号已存在"),
MODEL_SCRIPT_NOT_FOUND(50000012, "产品型号脚本不存在"),
PRODUCT_MODEL_NOT_FOUND(50000013, "产品型号不存在"),
FILE_NOT_FOUND(50000014, "文件不存在"),
RULE_NOT_FOUND(50000015, "规则不存在"),
RULE_ALREADY_RUNNING(50000016, "规则已运行"),
SEND_REQUEST_ERROR(50000017, "发送请求失败"),
TASK_NOT_FOUND(50000018, "任务不存在"),
RENEW_TASK_ERROR(50000019, "重启任务失败"),
HOME_NOT_FOUND(50000020, "家庭不存在"),
CURRENT_HOME_NOT_FOUND(50000021, "当前家庭不存在"),
SPACE_NOT_FOUND(50000022, "空间不存在"),
SPACE_DEVICE_NOT_FOUND(50000023, "空间设备不存在"),
DATA_BLANK(50000024, "数据为空"),
DATA_LENGTH_ERROR(50000025, "数据长度错误"),
DATA_FORMAT_ERROR(50000026, "数据格式错误"),
USER_NOT_FOUND(50000027, "用户不存在"),
RESET_PWD_ERROR(50000028, "重置密码失败"),
UPDATE_PWD_ERROR(50000029, "修改密码失败"),
PWD_ERROR(50000030, "密码错误"),
STATE_ERROR(50000031, "状态错误"),
RECORD_NOT_FOUND(50000032, "记录不存在"),
ADD_PLATFORM_USER_ERROR(50000033, "添加平台用户失败"),
UPLOAD_FILE_ERROR(50000034, "上传文件失败"),
FILE_NAME_IS_NULL(50000035, "文件名为空,获取文件名失败");
private int code;
private String message;
ErrCode(int code, String message) {
this.code = code;
this.message = message;
}
@Override
public Integer getKey() {
return this.code;
}
@Override
public String getValue() {
return this.message;
}
}

View File

@ -0,0 +1,33 @@
package cc.iotkit.common.enums;
public interface IEnum {
/**
* key
*/
Integer getKey();
/**
*
*/
String getValue();
/**
*
*
* @param param
* @param clazz
*/
static <T extends Enum<T> & IEnum> T parse(Integer param, Class<T> clazz) {
if (param == null || clazz == null) {
return null;
}
T[] enums = clazz.getEnumConstants();
for (T t : enums) {
Integer key = t.getKey();
if (key.equals(param)) {
return t;
}
}
return null;
}
}

View File

@ -0,0 +1,44 @@
package cc.iotkit.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author Lion Li
*/
@Getter
@AllArgsConstructor
public enum LoginType {
/**
*
*/
PASSWORD("user.password.retry.limit.exceed", "user.password.retry.limit.count"),
/**
*
*/
SMS("sms.code.retry.limit.exceed", "sms.code.retry.limit.count"),
/**
*
*/
EMAIL("email.code.retry.limit.exceed", "email.code.retry.limit.count"),
/**
*
*/
XCX("", "");
/**
*
*/
final String retryLimitExceed;
/**
*
*/
final String retryLimitCount;
}

View File

@ -0,0 +1,30 @@
package cc.iotkit.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author ruoyi
*/
@Getter
@AllArgsConstructor
public enum UserStatus {
/**
*
*/
OK("0", "正常"),
/**
*
*/
DISABLE("1", "停用"),
/**
*
*/
DELETED("2", "删除");
private final String code;
private final String info;
}

View File

@ -0,0 +1,43 @@
package cc.iotkit.common.enums;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
*
* @author Lion Li
*/
@Getter
@AllArgsConstructor
public enum UserType {
/**
* pc
*/
SYS_USER("sys_user"),
/**
* api
*/
API_USER("api_user"),
/**
* app
*/
APP_USER("app_user");
private final String userType;
public static UserType getUserType(String str) {
for (UserType value : values()) {
if (StringUtils.contains(str, value.getUserType())) {
return value;
}
}
throw new BizException("'UserType' not found By " + str);
}
}

View File

@ -0,0 +1,80 @@
package cc.iotkit.common.exception;
import cc.iotkit.common.utils.MessageUtils;
import cc.iotkit.common.utils.StringUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
*
*
* @author ruoyi
*/
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class BaseException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
*
*/
private String module;
/**
*
*/
private String code;
/**
*
*/
private Object[] args;
/**
*
*/
private String message;
public BaseException(String module, String code, Object[] args, String message) {
this.module = module;
this.code = code;
this.args = args;
this.message = message;
}
public BaseException(String module, String code, String message) {
this(module, code, null, message);
}
public BaseException(String module, String message) {
this(module, null, null, message);
}
public BaseException(String code, Object[] args) {
this(null, code, args, null);
}
public BaseException(String message) {
this(null, null, null, message);
}
@Override
public String getMessage() {
String message = null;
if (!StringUtils.isEmpty(code)) {
message = MessageUtils.message(code, args);
}
if (message == null) {
message = message;
}
return message;
}
}

View File

@ -0,0 +1,74 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.exception;
import cc.iotkit.common.enums.ErrCode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BizException extends RuntimeException {
/**
*
*/
private String module;
/**
*
*/
private Integer code;
/**
*
*/
private String message;
public BizException(String message) {
super(message);
this.message = message;
this.code = ErrCode.SYSTEM_EXCEPTION.getKey();
}
/**
*
*
* @param errCode
*/
public BizException(ErrCode errCode) {
this.message = errCode.getValue();
this.code = errCode.getKey();
}
public BizException(ErrCode errCode, Throwable cause) {
super(cause);
this.code = errCode.getKey();
this.message = errCode.getValue();
}
public BizException(ErrCode errCode, String message) {
this.message = message;
this.code = errCode.getKey();
}
public BizException(String message, Throwable cause) {
super(message, cause);
}
public BizException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,41 @@
package cc.iotkit.common.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
*
* @author sjg
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class ViewException extends RuntimeException {
public static final int CODE_FAILED = 500;
public static final int CODE_WARN = 601;
private int code;
private String message;
private Object data;
public ViewException() {
}
public ViewException(String message) {
super(message);
this.message = message;
}
public ViewException(int code, String message) {
this.code = code;
this.message = message;
}
public ViewException(int code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
}

View File

@ -0,0 +1,47 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.exception.user;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserException extends BizException {
/**
*
*/
private String module;
/**
*
*/
private Integer code;
/**
*
*/
private String message;
public UserException(String message) {
super( message);
this.code = ErrCode.SYSTEM_EXCEPTION.getKey();
this.message = message;
}
}

View File

@ -0,0 +1,11 @@
package cc.iotkit.common.function;
/**
* @author huangwenl
* @date 2022-11-10
*/
@FunctionalInterface
public interface IfHandler {
void handler(Runnable tHandler, Runnable fHandler);
}

View File

@ -0,0 +1,18 @@
package cc.iotkit.common.service;
/**
*
*
* @author Lion Li
*/
public interface ConfigService {
/**
* key
*
* @param configKey key
* @return
*/
String getConfigValue(String configKey);
}

View File

@ -0,0 +1,18 @@
package cc.iotkit.common.service;
/**
*
*
* @author Lion Li
*/
public interface DeptService {
/**
* ID
*
* @param deptIds ID
* @return
*/
String selectDeptNameByIds(String deptIds);
}

View File

@ -0,0 +1,19 @@
package cc.iotkit.common.service;
import cc.iotkit.common.thing.ThingService;
/**
*
*
* @author sjg
*/
public interface DeviceService {
/**
*
*
* @param service
*/
void invoke(ThingService<?> service);
}

View File

@ -0,0 +1,57 @@
package cc.iotkit.common.service;
/**
*
*
* @author Lion Li
*/
public interface DictService {
/**
*
*/
String SEPARATOR = ",";
/**
*
*
* @param dictType
* @param dictValue
* @return
*/
default String getDictLabel(String dictType, String dictValue) {
return getDictLabel(dictType, dictValue, SEPARATOR);
}
/**
*
*
* @param dictType
* @param dictLabel
* @return
*/
default String getDictValue(String dictType, String dictLabel) {
return getDictValue(dictType, dictLabel, SEPARATOR);
}
/**
*
*
* @param dictType
* @param dictValue
* @param separator
* @return
*/
String getDictLabel(String dictType, String dictValue, String separator);
/**
*
*
* @param dictType
* @param dictLabel
* @param separator
* @return
*/
String getDictValue(String dictType, String dictLabel, String separator);
}

View File

@ -0,0 +1,18 @@
package cc.iotkit.common.service;
/**
* OSS
*
* @author Lion Li
*/
public interface OssService {
/**
* ossIdurl
*
* @param ossIds ossId
* @return url
*/
String selectUrlByIds(String ossIds);
}

View File

@ -0,0 +1,18 @@
package cc.iotkit.common.service;
/**
*
*
* @author Lion Li
*/
public interface UserService {
/**
* ID
*
* @param userId ID
* @return
*/
String selectUserNameById(Long userId);
}

View File

@ -0,0 +1,43 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.thing;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author sjg
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ThingService<T> {
public static final String TYPE_PROPERTY = "property";
public static final String TYPE_SERVICE = "service";
public static final String TYPE_OTA = "ota";
private String mid;
private String productKey;
private String deviceName;
private String type;
private String identifier;
private T params;
}

View File

@ -0,0 +1,35 @@
package cc.iotkit.common.undefined;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
*
*
* @author Lion Li
*/
@Data
public class EmailLoginBody {
/**
* ID
*/
@NotBlank(message = "{tenant.number.not.blank}")
private String tenantId;
/**
*
*/
@NotBlank(message = "{user.email.not.blank}")
@Email(message = "{user.email.not.valid}")
private String email;
/**
* code
*/
@NotBlank(message = "{email.code.not.blank}")
private String emailCode;
}

View File

@ -0,0 +1,43 @@
package cc.iotkit.common.undefined;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
*
*
* @author Lion Li
*/
@Data
public class LoginBody {
/**
* ID
*/
@NotBlank(message = "{tenant.number.not.blank}")
private String tenantId;
/**
*
*/
@NotBlank(message = "{user.username.not.blank}")
private String username;
/**
*
*/
@NotBlank(message = "{user.password.not.blank}")
private String password;
/**
*
*/
private String code;
/**
*
*/
private String uuid;
}

View File

@ -0,0 +1,143 @@
package cc.iotkit.common.undefined;
import cc.iotkit.common.utils.StringUtils;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
/**
*
*
* @author Lion Li
*/
@Data
@NoArgsConstructor
public class LoginUser implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
private String tenantId;
/**
* ID
*/
private Long userId;
/**
* ID
*/
private Long deptId;
/**
*
*/
private String deptName;
/**
*
*/
private String token;
/**
*
*/
private String userType;
/**
*
*/
private Long loginTime;
/**
*
*/
private Long expireTime;
/**
* IP
*/
private String ipaddr;
/**
*
*/
private String loginLocation;
/**
*
*/
private String browser;
/**
*
*/
private String os;
/**
*
*/
private Set<String> menuPermission;
/**
*
*/
private Set<String> rolePermission;
/**
*
*/
private String username;
/**
*
*/
private List<RoleDTO> roles;
/**
* ID
*/
private Long roleId;
/**
* id
*/
public String getLoginId() {
if (userType == null) {
throw new IllegalArgumentException("用户类型不能为空");
}
if (userId == null) {
throw new IllegalArgumentException("用户ID不能为空");
}
return userType + ":" + userId;
}
/**
* loginIdloginUser
*
* @param loginId id
* @return LoginUser
* @see LoginUser::getLoginId
*/
public static LoginUser from(String loginId) {
if (StringUtils.isBlank(loginId)) {
return null;
}
String[] split = loginId.split(":");
if (split.length < 2) {
return null;
}
LoginUser user = new LoginUser();
user.setUserType(split[0]);
user.setUserId(Long.parseLong(split[1]));
return user;
}
}

View File

@ -0,0 +1,17 @@
package cc.iotkit.common.undefined;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class RegisterBody extends LoginBody {
private String userType;
}

View File

@ -0,0 +1,38 @@
package cc.iotkit.common.undefined;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
*
*
* @author Lion Li
*/
@Data
@NoArgsConstructor
public class RoleDTO implements Serializable {
/**
* ID
*/
private Long id;
/**
*
*/
private String roleName;
/**
*
*/
private String roleKey;
/**
* 12345
*/
private String dataScope;
}

View File

@ -0,0 +1,33 @@
package cc.iotkit.common.undefined;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
*
*
* @author Lion Li
*/
@Data
public class SmsLoginBody {
/**
* ID
*/
@NotBlank(message = "{tenant.number.not.blank}")
private String tenantId;
/**
*
*/
@NotBlank(message = "{user.phonenumber.not.blank}")
private String phonenumber;
/**
* code
*/
@NotBlank(message = "{sms.code.not.blank}")
private String smsCode;
}

View File

@ -0,0 +1,60 @@
package cc.iotkit.common.undefined;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 线
*
* @author ruoyi
*/
@Data
@NoArgsConstructor
public class UserOnlineDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private String tokenId;
/**
*
*/
private String deptName;
/**
*
*/
private String userName;
/**
* IP
*/
private String ipaddr;
/**
*
*/
private String loginLocation;
/**
*
*/
private String browser;
/**
*
*/
private String os;
/**
*
*/
private Long loginTime;
}

View File

@ -0,0 +1,26 @@
package cc.iotkit.common.undefined;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
*
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class XcxLoginUser extends LoginUser {
private static final long serialVersionUID = 1L;
/**
* openid
*/
private String openid;
}

View File

@ -0,0 +1,115 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.utils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
public class CodecUtil {
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
/**
* base 64 encode
*
* @param bytes byte[]
* @return base 64 code
*/
private static String base64Encode(byte[] bytes) {
return Base64.encodeBase64String(bytes);
}
/**
* base 64 decode
*
* @param base64Code base 64 code
* @return byte[]
* @throws Exception
*/
private static byte[] base64Decode(String base64Code) {
return StringUtils.isEmpty(base64Code) ? null : new Base64().decode(base64Code);
}
/**
* AES
*
* @param content
* @param encryptKey
* @return byte[]
*/
private static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
return cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
}
/**
* AESbase 64 code
*
* @param content
* @param encryptKey
* @return base 64 code
*/
public static String aesEncrypt(String content, String encryptKey) throws Exception {
String result = base64Encode(aesEncryptToBytes(content, encryptKey));
return HexUtil.toHexString(result.getBytes());
}
/**
* AES
*
* @param encryptBytes byte[]
* @param decryptKey
* @return String
*/
private static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
/**
* base 64 code AES
*
* @param encryptStr base 64 code
* @param decryptKey
* @return string
*/
public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
encryptStr = new String(HexUtil.parseHex(encryptStr));
return StringUtils.isEmpty(encryptStr) ? "" : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
}
public static String aesDecryptHex(String encryptStr, String decryptKey) throws Exception {
encryptStr = new String(HexUtil.parseHex(encryptStr));
return StringUtils.isEmpty(encryptStr) ? "" : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
}
public static String md5Str(String content) {
return DigestUtils.md5Hex(content);
}
}

View File

@ -0,0 +1,103 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.utils;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class ComponentClassLoader {
private static final Map<String, URLClassLoader> classLoaders = new HashMap<>();
protected static <T> Class<T> findClass(String name, String clsName) throws ClassNotFoundException {
ClassLoader classLoader = classLoaders.get(name);
return (Class<T>) classLoader.loadClass(clsName);
}
private static String addUrl(String name, File jarPath) throws NoSuchMethodException, InvocationTargetException,
IllegalAccessException, IOException {
URLClassLoader classLoader = classLoaders.get(name);
if (classLoader != null) {
classLoader.close();
}
classLoader = URLClassLoader.newInstance(new URL[]{jarPath.toURI().toURL()},
Thread.currentThread().getContextClassLoader());
classLoaders.put(name, classLoader);
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
if (!method.canAccess(classLoader)) {
method.setAccessible(true);
}
URL url = jarPath.toURI().toURL();
method.invoke(classLoader, url);
InputStream is = classLoader.getResourceAsStream("component.spi");
if (is == null) {
return null;
}
//多行只取第1行并处理空格
String[] lines = IOUtils.toString(is, StandardCharsets.UTF_8).split("\\s");
if (lines.length == 0) {
return null;
}
return lines[0].trim();
}
public static <T> T getComponent(String name, File jarFile) throws Exception {
String className = addUrl(name, jarFile);
if (StringUtils.isBlank(className)) {
throw new BizException(ErrCode.GET_SPI_COMPONENT_ERROR);
}
Class<T> componentClass = findClass(name, className);
return componentClass.getDeclaredConstructor().newInstance();
}
public static <T> T getConverter(String name) throws Exception {
URLClassLoader classLoader = classLoaders.get(name);
InputStream is = classLoader.getResourceAsStream("convert.spi");
if (is == null) {
return null;
}
//多行只取第1行并处理空格
String[] lines = IOUtils.toString(is, StandardCharsets.UTF_8).split("\\s");
if (lines.length == 0) {
throw new BizException(ErrCode.GET_SPI_CONVERT_ERROR);
}
String className = lines[0].trim();
Class<T> converterClass = findClass(name, className);
return converterClass.getDeclaredConstructor().newInstance();
}
public static void closeClassLoader(String name) {
try {
URLClassLoader classLoader = classLoaders.get(name);
if (classLoader != null){
classLoader.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,164 @@
package cc.iotkit.common.utils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
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.Date;
/**
*
*
* @author ruoyi
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
public static final String YYYY = "yyyy";
public static final String YYYY_MM = "yyyy-MM";
public static final String YYYY_MM_DD = "yyyy-MM-dd";
public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static final String[] PARSE_PATTERNS = {
"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 String getTime() {
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
}
public static String dateTimeNow() {
return dateTimeNow(YYYYMMDDHHMMSS);
}
public static String dateTimeNow(final String format) {
return parseDateToStr(format, new Date());
}
public static String dateTime(final Date date) {
return parseDateToStr(YYYY_MM_DD, date);
}
public static String parseDateToStr(final String format, final Date date) {
return new SimpleDateFormat(format).format(date);
}
public static 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 String datePath() {
Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd");
}
/**
* // 20180808
*/
public static 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(), PARSE_PATTERNS);
} catch (ParseException e) {
return null;
}
}
/**
*
*/
public static Date getServerStartDate() {
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time);
}
/**
*
*/
public static int differentDaysByMillisecond(Date date1, Date date2) {
return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
}
/**
*
*/
public static String getDatePoor(Date endDate, Date nowDate) {
long nd = 1000 * 24 * 60 * 60L;
long nh = 1000 * 60 * 60L;
long nm = 1000 * 60L;
// 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 + "分钟";
}
/**
* 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());
}
}

View File

@ -0,0 +1,35 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.utils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
public class DeviceUtil {
/**
* 1-13
* 14-29 deviceNae16016mac1616
* 30-31 mac2
* 32 0-f
*/
public static String newDeviceId(String deviceNae) {
int maxDnLen = 16;
String dn = deviceNae.replaceAll("[^0-9A-Za-z]", "");
if (dn.length() > maxDnLen) {
dn = dn.substring(dn.length() - maxDnLen + 1);
} else {
dn = (dn + "00000000000000000000").substring(0, maxDnLen);
}
String len = StringUtils.leftPad(deviceNae.length() + "", 2, '0');
String rnd = Integer.toHexString(RandomUtils.nextInt(0, 16));
return (System.currentTimeMillis() + "0" + dn + len + rnd).toLowerCase();
}
}

View File

@ -0,0 +1,21 @@
package cc.iotkit.common.utils;
import cc.iotkit.common.function.IfHandler;
/**
* @author huangwenl
* @date 2022-11-10
*/
public class FIUtil {
public static IfHandler isTotF(boolean param) {
return (tHandler, fHandler) -> {
if (param) {
tHandler.run();
} else {
fHandler.run();
}
};
}
}

View File

@ -0,0 +1,328 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.utils;
import org.apache.commons.lang3.StringUtils;
import java.nio.ByteBuffer;
public class HexUtil {
private static final char[] CHARS_TABLES = "0123456789ABCDEF".toCharArray();
static final byte[] BYTES = new byte[128];
static {
for (int i = 0; i < 10; i++) {
BYTES['0' + i] = (byte) i;
BYTES['A' + i] = (byte) (10 + i);
BYTES['a' + i] = (byte) (10 + i);
}
}
public static String toHexString(byte[] aBytes) {
return toHexString(aBytes, 0, aBytes.length);
}
public static String toFormattedHexString(byte[] aBytes) {
return toFormattedHexString(aBytes, 0, aBytes.length);
}
public static String toHexString(byte[] aBytes, int aLength) {
return toHexString(aBytes, 0, aLength);
}
public static byte[] parseHex(String aHexString) {
char[] src = aHexString.replace("\n", "").replace(" ", "").toUpperCase().toCharArray();
byte[] dst = new byte[src.length / 2];
for (int si = 0, di = 0; di < dst.length; di++) {
byte high = BYTES[src[si++] & 0x7f];
byte low = BYTES[src[si++] & 0x7f];
dst[di] = (byte) ((high << 4) + low);
}
return dst;
}
public static String toFormattedHexString(byte[] aBytes, int aOffset, int aLength) {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append(aLength);
sb.append("] :");
for (int si = aOffset, di = 0; si < aOffset + aLength; si++, di++) {
byte b = aBytes[si];
if (di % 4 == 0) {
sb.append(" ");
} else {
sb.append(' ');
}
sb.append(CHARS_TABLES[(b & 0xf0) >>> 4]);
sb.append(CHARS_TABLES[(b & 0x0f)]);
}
return sb.toString();
}
public static String toHexString(byte[] aBytes, int aOffset, int aLength) {
char[] dst = new char[aLength * 2];
for (int si = aOffset, di = 0; si < aOffset + aLength; si++) {
byte b = aBytes[si];
dst[di++] = CHARS_TABLES[(b & 0xf0) >>> 4];
dst[di++] = CHARS_TABLES[(b & 0x0f)];
}
return new String(dst);
}
public static String unwrapCharString(String charStr) {
byte[] bytes = parseHex(charStr);
StringBuilder rawStr = new StringBuilder();
for (byte aByte : bytes) {
rawStr.append((char) aByte);
}
return rawStr.toString();
}
/**
* intbytes
*/
public static byte[] intToBytes(int x) {
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.putInt(0, x);
return buffer.array();
}
/**
* bytesint
*/
public static int bytesToInt(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.flip();
return buffer.getInt();
}
public static int checkSum(ByteBuffer buffer) {
buffer.flip();
byte sum = 0;
while (buffer.hasRemaining()) {
sum += buffer.get();
}
buffer.limit(buffer.capacity());
return sum % 256;
}
public static byte[] toLowerBytes(byte[] bytes) {
int len = bytes.length;
byte[] r = new byte[len];
for (int i = 0; i < len; i++) {
r[len - i - 1] = bytes[i];
}
return r;
}
public static int toLowerInt(byte[] bytes) {
int len = bytes.length;
byte[] r = new byte[len];
for (int i = 0; i < len; i++) {
r[len - i - 1] = (byte) (bytes[i] - 0x33);
}
return ByteBuffer.wrap(r).getInt();
}
public static byte[] shortToBytes(short x) {
ByteBuffer buffer = ByteBuffer.allocate(2);
buffer.putShort(0, x);
return buffer.array();
}
public static String readString(ByteBuffer buffer, int len) {
byte[] dest = new byte[len];
buffer.get(dest, 0, len);
return new String(dest);
}
// public static int readLowerInt(ByteBuffer buffer, int len) {
// int r = 0;
// for (int i = 0; i < len; i++) {
// byte b = buffer.get();
// r += (i == 0 ? b - 0x33 : ((b - 0x33) * Math.pow(10, i)));
// }
// return r;
// }
public static String readHexIntString(ByteBuffer buffer) {
int b = buffer.get();
String hex = Integer.toHexString(b - 0x33).replace("f", "");
return StringUtils.leftPad(hex, 2, "0");
}
public static byte[] add33Bytes(byte[] bytes) {
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) (bytes[i] + 0x33);
}
return bytes;
}
public static byte[] minus33Bytes(byte[] bytes) {
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) (bytes[i] - 0x33);
}
return bytes;
}
public static byte[] readBytes(ByteBuffer buffer, int len) {
byte[] data = new byte[len];
for (int i = 0; i < len; i++) {
data[i] = buffer.get();
}
return data;
}
public static byte[] readAndMinus33Bytes(ByteBuffer buffer, int len) {
byte[] data = new byte[len];
for (int i = 0; i < len; i++) {
data[i] = (byte) (buffer.get() - 0x33);
}
return data;
}
public static int bcdInt(String row) {
String bcd = bcdString(row);
bcd = bcd.replace("FF", "0");
return Integer.parseInt(bcd);
}
public static int bcdInt(ByteBuffer buffer, int len) {
byte[] bytes = readAndMinus33Bytes(buffer, len);
return bcdInt(HexUtil.toHexString(bytes));
}
public static String bcdString(String row) {
char[] chars = row.toCharArray();
int len = chars.length;
char[] newChars = new char[len];
for (int i = 0; i < len; i += 2) {
newChars[i] = chars[len - i - 2];
newChars[i + 1] = chars[len - i - 1];
}
return String.valueOf(newChars);
}
public static byte[] intBcdAdd33(int v, int len) {
String strV = String.valueOf(v);
strV = StringUtils.leftPad(strV, len * 2, '0');
return add33Bytes(HexUtil.parseHex(bcdString(strV)));
}
/**
* 16
*
* @param s 16
* @return byte[]
*/
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] b = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
// 两位一组,表示一个字节,把这样表示的16进制字符串还原成一个字节
b[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character
.digit(s.charAt(i + 1), 16));
}
return b;
}
/**
* CRC16
*
* @param data
* @param offset
* @param len
* @return CRC16
*/
public static int calcCrc16(byte[] data, int offset, int len) {
byte[] crc16_tab_h = {
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40
};
byte[] crc16_tab_l = {
(byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06,
(byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD,
(byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09,
(byte) 0x08, (byte) 0xC8, (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A,
(byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4,
(byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3,
(byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3,
(byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4,
(byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A,
(byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29,
(byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED,
(byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7, (byte) 0xE6, (byte) 0x26,
(byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60,
(byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67,
(byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F,
(byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68,
(byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E,
(byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74, (byte) 0x75, (byte) 0xB5,
(byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71,
(byte) 0x70, (byte) 0xB0, (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92,
(byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54, (byte) 0x9C, (byte) 0x5C,
(byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B,
(byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B,
(byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D, (byte) 0x4C, (byte) 0x8C,
(byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42,
(byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40
};
int pre = 0xffff;
int ucCRCHi = (pre & 0xff00) >> 8;
int ucCRCLo = pre & 0x00ff;
int iIndex;
for (int i = 0; i < len; ++i) {
iIndex = (ucCRCLo ^ data[offset + i]) & 0x00ff;
ucCRCLo = ucCRCHi ^ crc16_tab_h[iIndex];
ucCRCHi = crc16_tab_l[iIndex];
}
return ((ucCRCHi & 0x00ff) << 8) | (ucCRCLo & 0x00ff) & 0xffff;
}
}

View File

@ -0,0 +1,129 @@
package cc.iotkit.common.utils;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PrimitiveArrayUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* JSON
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class JsonUtils {
private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class);
public static ObjectMapper getObjectMapper() {
return OBJECT_MAPPER;
}
public static String toJsonString(Object object) {
if (ObjectUtil.isNull(object)) {
return null;
}
try {
return OBJECT_MAPPER.writeValueAsString(object);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static <T> T parse(String json, Class<T> cls) {
if (StringUtils.isBlank(json)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(json, cls);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static <T> T parseObject(String text, Class<T> clazz) {
if (StringUtils.isEmpty(text)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(text, clazz);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
if (PrimitiveArrayUtil.isEmpty(bytes)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(bytes, clazz);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> T parseObject(String text, TypeReference<T> typeReference) {
if (StringUtils.isBlank(text)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(text, typeReference);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static Dict parseMap(String text) {
if (StringUtils.isBlank(text)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class));
} catch (MismatchedInputException e) {
// 类型不匹配说明不是json
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static List<Dict> parseArrayMap(String text) {
if (StringUtils.isBlank(text)) {
return Collections.emptyList();
}
try {
return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> List<T> parseArray(String text, Class<T> clazz) {
if (StringUtils.isEmpty(text)) {
return new ArrayList<>();
}
try {
return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> T objectToJavaBean(Object obj, Class<T> clazz) {
if (Objects.isNull(obj)) {
return null;
}
return OBJECT_MAPPER.convertValue(obj, clazz);
}
}

View File

@ -0,0 +1,111 @@
package cc.iotkit.common.utils;
import cc.iotkit.common.api.Paging;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import io.github.linpeilie.Converter;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Mapstruct
* <p><a href="https://mapstruct.plus/guide/quick-start">mapstruct-plus</a></p>
*
* @author Michelle.Chung
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MapstructUtils {
private final static Converter CONVERTER = SpringUtils.getBean(Converter.class);
/**
* T desc
*
* @param source
* @param desc
* @return desc
*/
public static <T, V> V convert(T source, Class<V> desc) {
Assert.notNull(desc, "desc is null");
if (source == null) {
return null;
}
return CONVERTER.convert(source, desc);
}
/**
* T desc desc
*
* @param source
* @param desc
* @return desc
*/
public static <T, V> V convert(T source, V desc) {
if (ObjectUtil.isNull(source)) {
return null;
}
if (ObjectUtil.isNull(desc)) {
return null;
}
return CONVERTER.convert(source, desc);
}
/**
* T desc
*
* @param sourceList
* @param desc
* @return desc
*/
public static <T, V> List<V> convert(List<T> sourceList, Class<V> desc) {
if (ObjectUtil.isNull(sourceList)) {
return Collections.emptyList();
}
if (CollUtil.isEmpty(sourceList)) {
return CollUtil.newArrayList();
}
return CONVERTER.convert(sourceList, desc);
}
/**
* Map beanClass
*
* @param map
* @param beanClass bean
* @return bean
*/
public static <T> T convert(Map<String, Object> map, Class<T> beanClass) {
if (MapUtil.isEmpty(map)) {
return null;
}
if (ObjectUtil.isNull(beanClass)) {
return null;
}
return CONVERTER.convert(map, beanClass);
}
/**
*
*
* @param source
* @param desc
* @return desc
*/
public static <T, V> Paging<V> convert(Paging<T> source, Class<V> desc) {
if (ObjectUtil.isNull(source)) {
return null;
}
if (CollUtil.isEmpty(source.getRows())) {
return new Paging<>(0, new ArrayList<>());
}
return new Paging<>(source.getTotal(), CONVERTER.convert(source.getRows(), desc));
}
}

View File

@ -0,0 +1,34 @@
package cc.iotkit.common.utils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
/**
* i18n
*
* @author Lion Li
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MessageUtils {
private static final MessageSource MESSAGE_SOURCE = SpringUtils.getBean(MessageSource.class);
/**
* spring messageSource
*
* @param code
* @param args
* @return
*/
public static String message(String code, Object... args) {
// TODO: 国际化
try{
return MESSAGE_SOURCE.getMessage(code, args, LocaleContextHolder.getLocale());
} catch (Exception e) {
return code;
}
}
}

View File

@ -0,0 +1,54 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.utils;
import lombok.SneakyThrows;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.beanutils.BeanUtils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ReflectUtil {
@SneakyThrows
public static <T> T copyNoNulls(T from, T to, String... fields) {
List<String> fieldList = Arrays.asList(fields);
Map<String, Object> map = new HashMap<>();
new BeanMap(from).forEach((key, value) -> {
if (value == null) {
return;
}
String field = key.toString();
if (fields.length == 0 || fieldList.contains(field)) {
map.put(field, value);
}
});
BeanUtils.populate(to, map);
return to;
}
public static Map<String, ?> toMap(Object bean) {
Map<String, Object> map = new HashMap<>();
new BeanMap(bean).forEach((key, value) -> {
if (key.equals("class")) {
return;
}
String field = key.toString();
map.put(field, value);
});
return map;
}
}

View File

@ -0,0 +1,54 @@
package cc.iotkit.common.utils;
import cn.hutool.core.util.ReflectUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.lang.reflect.Method;
/**
* . getter/setter, 访, , Class, AOP.
*
* @author Lion Li
*/
@SuppressWarnings("rawtypes")
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ReflectUtils extends ReflectUtil {
private static final String SETTER_PREFIX = "set";
private static final String GETTER_PREFIX = "get";
/**
* Getter.
* ..
*/
@SuppressWarnings("unchecked")
public static <E> E invokeGetter(Object obj, String propertyName) {
Object object = obj;
for (String name : StringUtils.split(propertyName, ".")) {
String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
object = invoke(object, getterMethodName);
}
return (E) object;
}
/**
* Setter,
* ..
*/
public static <E> void invokeSetter(Object obj, String propertyName, E value) {
Object object = obj;
String[] names = StringUtils.split(propertyName, ".");
for (int i = 0; i < names.length; i++) {
if (i < names.length - 1) {
String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
object = invoke(object, getterMethodName);
} else {
String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
Method method = getMethodByName(object.getClass(), setterMethodName);
invoke(object, method, value);
}
}
}
}

View File

@ -0,0 +1,62 @@
package cc.iotkit.common.utils;
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
/**
* spring
*
* @author Lion Li
*/
@Component
public final class SpringUtils extends SpringUtil {
/**
* BeanFactorybeantrue
*/
public static boolean containsBean(String name) {
return getBeanFactory().containsBean(name);
}
/**
* beansingletonprototype
* beanNoSuchBeanDefinitionException
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().isSingleton(name);
}
/**
* @return Class
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().getType(name);
}
/**
* beanbean
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().getAliases(name);
}
/**
* aop
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker) {
return (T) AopContext.currentProxy();
}
/**
* spring
*/
public static ApplicationContext context() {
return getApplicationContext();
}
}

View File

@ -0,0 +1,254 @@
package cc.iotkit.common.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* stream
*
* @author Lion Li
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class StreamUtils {
/**
* collection
*
* @param collection
* @param function
* @return list
*/
public static <E> List<E> filter(Collection<E> collection, Predicate<E> function) {
if (CollUtil.isEmpty(collection)) {
return CollUtil.newArrayList();
}
// 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
return collection.stream().filter(function).collect(Collectors.toList());
}
/**
* collection
*
* @param collection
* @param function
* @return list
*/
public static <E> String join(Collection<E> collection, Function<E, String> function) {
return join(collection, function, StringUtils.SEPARATOR);
}
/**
* collection
*
* @param collection
* @param function
* @param delimiter
* @return list
*/
public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) {
if (CollUtil.isEmpty(collection)) {
return StringUtils.EMPTY;
}
return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
}
/**
* collection
*
* @param collection
* @param comparing
* @return list
*/
public static <E> List<E> sorted(Collection<E> collection, Comparator<E> comparing) {
if (CollUtil.isEmpty(collection)) {
return CollUtil.newArrayList();
}
// 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
return collection.stream().sorted(comparing).collect(Collectors.toList());
}
/**
* collectionmap<br>
* <B>{@code Collection<V> ----> Map<K,V>}</B>
*
* @param collection
* @param key VKlambda
* @param <V> collection
* @param <K> mapkey
* @return map
*/
public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) {
if (CollUtil.isEmpty(collection)) {
return MapUtil.newHashMap();
}
return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l));
}
/**
* Collectionmap(valuecollection)<br>
* <B>{@code Collection<E> -----> Map<K,V> }</B>
*
* @param collection
* @param key EKlambda
* @param value EVlambda
* @param <E> collection
* @param <K> mapkey
* @param <V> mapvalue
* @return map
*/
public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) {
if (CollUtil.isEmpty(collection)) {
return MapUtil.newHashMap();
}
return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l));
}
/**
* collection(id)map<br>
* <B>{@code Collection<E> -------> Map<K,List<E>> } </B>
*
* @param collection
* @param key
* @param <E> collection
* @param <K> mapkey
* @return map
*/
public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) {
if (CollUtil.isEmpty(collection)) {
return MapUtil.newHashMap();
}
return collection
.stream()
.collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
}
/**
* collection(id,id)map<br>
* <B>{@code Collection<E> ---> Map<T,Map<U,List<E>>> } </B>
*
* @param collection
* @param key1
* @param key2
* @param <E>
* @param <K> mapkey
* @param <U> mapkey
* @return map
*/
public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1, Function<E, U> key2) {
if (CollUtil.isEmpty(collection)) {
return MapUtil.newHashMap();
}
return collection
.stream()
.collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList())));
}
/**
* collection(id,id)map<br>
* <B>{@code Collection<E> ---> Map<T,Map<U,E>> } </B>
*
* @param collection
* @param key1
* @param key2
* @param <T> mapkey
* @param <U> mapkey
* @param <E> collection
* @return map
*/
public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) {
if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) {
return MapUtil.newHashMap();
}
return collection
.stream()
.collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l)));
}
/**
* collectionList<br>
* <B>{@code Collection<E> ------> List<T> } </B>
*
* @param collection
* @param function collectionlistlambda
* @param <E> collection
* @param <T> List
* @return list
*/
public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) {
if (CollUtil.isEmpty(collection)) {
return CollUtil.newArrayList();
}
return collection
.stream()
.map(function)
.filter(Objects::nonNull)
// 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
.collect(Collectors.toList());
}
/**
* collectionSet<br>
* <B>{@code Collection<E> ------> Set<T> } </B>
*
* @param collection
* @param function collectionsetlambda
* @param <E> collection
* @param <T> Set
* @return Set
*/
public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) {
if (CollUtil.isEmpty(collection) || function == null) {
return CollUtil.newHashSet();
}
return collection
.stream()
.map(function)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}
/**
* keymap
*
* @param map1 map
* @param map2 map
* @param merge lambdakey value1 value2,value
* @param <K> mapkey
* @param <X> mapvalue
* @param <Y> mapvalue
* @param <V> mapvalue
* @return map
*/
public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) {
if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) {
return MapUtil.newHashMap();
} else if (MapUtil.isEmpty(map1)) {
map1 = MapUtil.newHashMap();
} else if (MapUtil.isEmpty(map2)) {
map2 = MapUtil.newHashMap();
}
Set<K> key = new HashSet<>();
key.addAll(map1.keySet());
key.addAll(map2.keySet());
Map<K, V> map = new HashMap<>();
for (K t : key) {
X x = map1.get(t);
Y y = map2.get(t);
V z = merge.apply(x, y);
if (z != null) {
map.put(t, z);
}
}
return map;
}
}

View File

@ -0,0 +1,321 @@
package cc.iotkit.common.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.util.AntPathMatcher;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
*
* @author Lion Li
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class StringUtils extends org.apache.commons.lang3.StringUtils {
public static final String SEPARATOR = ",";
/**
*
*
* @param str defaultValue value
* @return value
*/
public static String blankToDefault(String str, String defaultValue) {
return StrUtil.blankToDefault(str, defaultValue);
}
/**
* *
*
* @param str String
* @return true false
*/
public static boolean isEmpty(String str) {
return StrUtil.isEmpty(str);
}
/**
* *
*
* @param str String
* @return true false
*/
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
/**
*
*/
public static String trim(String str) {
return StrUtil.trim(str);
}
/**
*
*
* @param str
* @param start
* @return
*/
public static String substring(final String str, int start) {
return substring(str, start, str.length());
}
/**
*
*
* @param str
* @param start
* @param end
* @return
*/
public static String substring(final String str, int start, int end) {
return StrUtil.sub(str, start, 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 template {}
* @param params
* @return
*/
public static String format(String template, Object... params) {
return StrUtil.format(template, params);
}
/**
* http(s)://开头
*
* @param link
* @return
*/
public static boolean ishttp(String link) {
return Validator.isUrl(link);
}
/**
* set
*
* @param str
* @param sep
* @return set
*/
public static Set<String> str2Set(String str, String sep) {
return new HashSet<>(str2List(str, sep, true, false));
}
/**
* list
*
* @param str
* @param sep
* @param filterBlank
* @param trim
* @return list
*/
public static List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) {
List<String> list = new ArrayList<>();
if (isEmpty(str)) {
return list;
}
// 过滤空白字符串
if (filterBlank && isBlank(str)) {
return list;
}
String[] split = str.split(sep);
for (String string : split) {
if (filterBlank && isBlank(string)) {
continue;
}
if (trim) {
string = trim(string);
}
list.add(string);
}
return list;
}
/**
*
*
* @param cs
* @param searchCharSequences
* @return
*/
public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) {
return StrUtil.containsAnyIgnoreCase(cs, searchCharSequences);
}
/**
* 线
*/
public static String toUnderScoreCase(String str) {
return StrUtil.toUnderlineCase(str);
}
/**
*
*
* @param str
* @param strs
* @return true
*/
public static boolean inStringIgnoreCase(String str, String... strs) {
return StrUtil.equalsAnyIgnoreCase(str, strs);
}
/**
* 线线 HELLO_WORLD->HelloWorld
*
* @param name 线
* @return
*/
public static String convertToCamelCase(String name) {
return StrUtil.upperFirst(StrUtil.toCamelCase(name));
}
/**
* user_name->userName
*/
public static String toCamelCase(String s) {
return StrUtil.toCamelCase(s);
}
/**
*
*
* @param str
* @param strs
* @return
*/
public static boolean matches(String str, List<String> strs) {
if (isEmpty(str) || CollUtil.isEmpty(strs)) {
return false;
}
for (String pattern : strs) {
if (isMatch(pattern, str)) {
return true;
}
}
return false;
}
/**
* url:
* ? ;
* * ;
* ** ;
*
* @param pattern
* @param url url
*/
public static boolean isMatch(String pattern, String url) {
AntPathMatcher matcher = new AntPathMatcher();
return matcher.match(pattern, url);
}
/**
* 0使size size
*
* @param num
* @param size
* @return
*/
public static String padl(final Number num, final int size) {
return padl(num.toString(), size, '0');
}
/**
* ssizesize
*
* @param s
* @param size
* @param c
* @return
*/
public static 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) {
sb.append(String.valueOf(c).repeat(size - len));
sb.append(s);
} else {
return s.substring(len - size, len);
}
} else {
sb.append(String.valueOf(c).repeat(Math.max(0, size)));
}
return sb.toString();
}
/**
* ()
*
* @param str
* @return
*/
public static List<String> splitList(String str) {
return splitTo(str, Convert::toStr);
}
/**
*
*
* @param str
* @param separator
* @return
*/
public static List<String> splitList(String str, String separator) {
return splitTo(str, separator, Convert::toStr);
}
/**
* ()
*
* @param str
* @param mapper
* @return
*/
public static <T> List<T> splitTo(String str, Function<? super Object, T> mapper) {
return splitTo(str, SEPARATOR, mapper);
}
/**
*
*
* @param str
* @param separator
* @param mapper
* @return
*/
public static <T> List<T> splitTo(String str, String separator, Function<? super Object, T> mapper) {
if (isBlank(str)) {
return new ArrayList<>(0);
}
return StrUtil.split(str, separator)
.stream()
.filter(Objects::nonNull)
.map(mapper)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,34 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.utils;
import java.util.concurrent.ScheduledThreadPoolExecutor;
public class ThreadUtil {
public static ScheduledThreadPoolExecutor newScheduled(int poolSize, String threadName) {
return new ScheduledThreadPoolExecutor(poolSize, (Runnable r) -> {
SecurityManager s = System.getSecurityManager();
ThreadGroup group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
Thread t = new Thread(group, r,
threadName,
0);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
});
}
}

View File

@ -0,0 +1,35 @@
package cc.iotkit.common.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.lang.tree.parser.NodeParser;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.List;
/**
* hutool TreeUtil
*
* @author Lion Li
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TreeBuildUtils extends TreeUtil {
/**
*
*/
public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("label");
public static <T, K> List<Tree<K>> build(List<T> list, NodeParser<T, K> nodeParser) {
if (CollUtil.isEmpty(list)) {
return Collections.emptyList();
}
K k = ReflectUtils.invokeGetter(list.get(0), "parentId");
return TreeUtil.build(list, k, DEFAULT_CONFIG, nodeParser);
}
}

View File

@ -0,0 +1,37 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common.utils;
import org.apache.commons.lang3.RandomUtils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.atomic.AtomicInteger;
public final class UniqueIdUtil {
private static final int MACHINE_ID = RandomUtils.nextInt(10, 99);
private static final AtomicInteger SEQUENCE = new AtomicInteger(1000);
public static String newRequestId() {
return newUniqueId("RID");
}
public static String newUniqueId(String prefix) {
int id = SEQUENCE.getAndIncrement();
if (id >= 5000) {
SEQUENCE.set(1000);
}
return prefix + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + id + MACHINE_ID;
}
}

View File

@ -0,0 +1,28 @@
package cc.iotkit.common.utils;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validator;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.Set;
/**
* Validator
*
* @author Lion Li
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ValidatorUtils {
private static final Validator VALID = SpringUtils.getBean(Validator.class);
public static <T> void validate(T object, Class<?>... groups) {
Set<ConstraintViolation<T>> validate = VALID.validate(object, groups);
if (!validate.isEmpty()) {
throw new ConstraintViolationException("参数校验异常", validate);
}
}
}

View File

@ -0,0 +1,16 @@
package cc.iotkit.common.utils.file;
import cn.hutool.core.io.FileUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
/**
*
*
* @author Lion Li
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FileUtils extends FileUtil {
}

View File

@ -0,0 +1,40 @@
package cc.iotkit.common.utils.file;
/**
*
*
* @author ruoyi
*/
public class MimeTypeUtils {
public static final String IMAGE_PNG = "image/png";
public static final String IMAGE_JPG = "image/jpg";
public static final String IMAGE_JPEG = "image/jpeg";
public static final String IMAGE_BMP = "image/bmp";
public static final String IMAGE_GIF = "image/gif";
public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};
public static final String[] FLASH_EXTENSION = {"swf", "flv"};
public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
"asf", "rm", "rmvb"};
public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};
public static final String[] DEFAULT_ALLOWED_EXTENSION = {
// 图片
"bmp", "gif", "jpg", "jpeg", "png",
// word excel powerpoint
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
// 压缩文件
"rar", "zip", "gz", "bz2",
// 视频格式
"mp4", "avi", "rmvb",
// pdf
"pdf"};
}

View File

@ -0,0 +1,33 @@
package cc.iotkit.common.utils.ip;
import cc.iotkit.common.utils.StringUtils;
import cn.hutool.core.net.NetUtil;
import cn.hutool.http.HtmlUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
*
*
* @author Lion Li
*/
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class AddressUtils {
// 未知地址
public static final String UNKNOWN = "XX XX";
public static String getRealAddressByIP(String ip) {
if (StringUtils.isBlank(ip)) {
return UNKNOWN;
}
// 内网不查询
ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
if (NetUtil.isInnerIP(ip)) {
return "内网IP";
}
return RegionUtils.getCityInfo(ip);
}
}

View File

@ -0,0 +1,67 @@
package cc.iotkit.common.utils.ip;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.file.FileUtils;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import java.io.File;
/**
* ip线
* <a href="https://gitee.com/lionsoul/ip2region/tree/master/binding/java"> ip2region 线IP</a>
*
* @author lishuyan
*/
@Slf4j
public class RegionUtils {
private static final Searcher SEARCHER;
static {
String fileName = "/ip2region.xdb";
File existFile = FileUtils.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
if (!FileUtils.exist(existFile)) {
ClassPathResource fileStream = new ClassPathResource(fileName);
if (ObjectUtil.isEmpty(fileStream.getStream())) {
throw new BizException("RegionUtils初始化失败原因IP地址库数据不存在");
}
FileUtils.writeFromStream(fileStream.getStream(), existFile);
}
String dbPath = existFile.getPath();
// 1、从 dbPath 加载整个 xdb 到内存。
byte[] cBuff;
try {
cBuff = Searcher.loadContentFromFile(dbPath);
} catch (Exception e) {
throw new BizException("RegionUtils初始化失败原因从ip2region.xdb文件加载内容失败" + e.getMessage());
}
// 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
try {
SEARCHER = Searcher.newWithBuffer(cBuff);
} catch (Exception e) {
throw new BizException("RegionUtils初始化失败原因" + e.getMessage());
}
}
/**
* IP线
*/
public static String getCityInfo(String ip) {
try {
ip = ip.trim();
// 3、执行查询
String region = SEARCHER.search(ip);
return region.replace("0|", "").replace("|0", "");
} catch (Exception e) {
log.error("IP地址离线获取城市异常 {}", ip);
return "未知";
}
}
}

View File

@ -0,0 +1,9 @@
package cc.iotkit.common.validate;
/**
* add
*
* @author Lion Li
*/
public interface AddGroup {
}

View File

@ -0,0 +1,9 @@
package cc.iotkit.common.validate;
/**
* delete
*
* @author Lion Li
*/
public interface DeleteGroup {
}

View File

@ -0,0 +1,9 @@
package cc.iotkit.common.validate;
/**
* edit
*
* @author Lion Li
*/
public interface EditGroup {
}

View File

@ -0,0 +1,9 @@
package cc.iotkit.common.validate;
/**
* query
*
* @author Lion Li
*/
public interface QueryGroup {
}

54
iot-common-doc/pom.xml Executable file
View File

@ -0,0 +1,54 @@
<?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>iot-iita-core</artifactId>
<groupId>cc.iotkit</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-common-doc</artifactId>
<dependencies>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,15 @@
package cc.iotkit.swagger.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Author:
* @Date: 2023/5/6 22:03
* @Description:
*/
@Configuration
@ComponentScan(basePackages = {"cc.iotkit.swagger"})
public class SwaggerAutoConfiguration {
}

View File

@ -0,0 +1,130 @@
package cc.iotkit.swagger.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
import java.lang.reflect.Field;
import java.util.List;
/**
* @Author:
* @Date: 2023/5/4 20:12
* @Description:
*/
@Component
@EnableSwagger2WebMvc
public class SwaggerConfig {
@Value("${spring.application.name:Swagger API}")
private String applicationName;
@Bean(value = "defaultApi2")
public Docket defaultApi2() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName(applicationName)
.enable(true)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(applicationName)
.description("Swagger API Doc")
.build();
}
// 解决springboot升级到2.6.x之后knife4j报错
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
if (bean instanceof WebMvcRequestHandlerProvider ) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
mappings.removeIf(mapping -> mapping.getPatternParser() != null);
}
@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
// /**
// * 解决springboot升级到2.6.x之后knife4j报错
// *
// * @param webEndpointsSupplier the web endpoints supplier
// * @param servletEndpointsSupplier the servlet endpoints supplier
// * @param controllerEndpointsSupplier the controller endpoints supplier
// * @param endpointMediaTypes the endpoint media types
// * @param corsProperties the cors properties
// * @param webEndpointProperties the web endpoint properties
// * @param environment the environment
// * @return the web mvc endpoint handler mapping
// */
// @Bean
// public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(
// WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier,
// ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes,
// CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties,
// Environment environment) {
// List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
// Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
// allEndpoints.addAll(webEndpoints);
// allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
// allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
// String basePath = webEndpointProperties.getBasePath();
// EndpointMapping endpointMapping = new EndpointMapping(basePath);
// boolean shouldRegisterLinksMapping = shouldRegisterLinksMapping(webEndpointProperties,
// environment, basePath);
// return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes,
// corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath),
// shouldRegisterLinksMapping, null);
// }
//
// /**
// * shouldRegisterLinksMapping
// * @param webEndpointProperties webEndpointProperties
// * @param environment environment
// * @param basePath /
// * @return boolean
// */
// private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties,
// Environment environment, String basePath) {
// return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath)
// || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
// }
}

View File

@ -0,0 +1,60 @@
package cc.iotkit.swagger.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @Author:
* @Date: 2023/5/6 22:26
* @Description:
*/
@Data
@Component
@ConfigurationProperties(prefix = "swagger")
public class SwaggerProperties {
private Boolean enabled;
private String title; //标题
private String group; //自定义组名
private String description = "在线文档"; //描述
private String version = "1.0"; //版本
private Contact contact = new Contact(); //联系人
private String basePackage = "com.example"; //swagger会解析的包路径
private List<String> basePath = new ArrayList<>(); //swagger会解析的url规则
private List<String> excludePath = new ArrayList<>();//在basePath基础上需要排除的url规则
private Map<String, DocketInfo> docket = new LinkedHashMap<>(); //分组文档
public String getGroup() {
if (group == null || "".equals(group)) {
return title;
}
return group;
}
@Data
public static class DocketInfo {
private String title = "在线文档"; //标题
private String group = ""; //自定义组名
private String description = "在线文档"; //描述
private String version = "1.0"; //版本
private Contact contact = new Contact(); //联系人
private String basePackage = "com.example"; //swagger会解析的包路径
private List<String> basePath = new ArrayList<>(); //swagger会解析的url规则
private List<String> excludePath = new ArrayList<>();//在basePath基础上需要排除的url
public String getGroup() {
if (group == null || "".equals(group)) {
return title;
}
return group;
}
}
@Data
public static class Contact {
private String name = ""; //联系人
private String url = ""; //联系人url
private String email = ""; //联系人email
}
}

View File

@ -0,0 +1,20 @@
package cc.iotkit.swagger.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Author:
* @Date: 2023/5/6 22:03
* @Description:
*/
@Configuration
public class SwaggerWebConfiguration implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html", "doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}

View File

@ -0,0 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cc.iotkit.swagger.config.SwaggerAutoConfiguration,\
cc.iotkit.swagger.config.SwaggerWebConfiguration

48
iot-common-excel/pom.xml Executable file
View File

@ -0,0 +1,48 @@
<?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>iot-iita-core</artifactId>
<groupId>cc.iotkit</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-common-excel</artifactId>
<dependencies>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-web</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-core</artifactId>
</dependency>
<!--====================第三方库===================-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,25 @@
package cc.iotkit.common.excel.annotation;
import cc.iotkit.common.excel.core.CellMergeStrategy;
import java.lang.annotation.*;
/**
* excel ()
*
* {@link CellMergeStrategy} 使
*
* @author Lion Li
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface CellMerge {
/**
* col index
*/
int index() default -1;
}

View File

@ -0,0 +1,33 @@
package cc.iotkit.common.excel.annotation;
import cc.iotkit.common.utils.StringUtils;
import java.lang.annotation.*;
/**
*
*
* @author Lion Li
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ExcelDictFormat {
/**
* type (: sys_user_sex)
*/
String dictType() default "";
/**
* (: 0=,1=,2=)
*/
String readConverterExp() default "";
/**
*
*/
String separator() default StringUtils.SEPARATOR;
}

View File

@ -0,0 +1,30 @@
package cc.iotkit.common.excel.annotation;
import java.lang.annotation.*;
/**
*
*
* @author Liang
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ExcelEnumFormat {
/**
*
*/
Class<? extends Enum<?>> enumClass();
/**
* codecode
*/
String codeField() default "code";
/**
* texttext
*/
String textField() default "text";
}

View File

@ -0,0 +1,52 @@
package cc.iotkit.common.excel.convert;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
/**
*
* Excel 15 15
*
* @author Lion Li
*/
@Slf4j
public class ExcelBigNumberConvert implements Converter<Long> {
@Override
public Class<Long> supportJavaTypeKey() {
return Long.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
return Convert.toLong(cellData.getData());
}
@Override
public WriteCellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (ObjectUtil.isNotNull(object)) {
String str = Convert.toStr(object);
if (str.length() > 15) {
return new WriteCellData<>(str);
}
}
WriteCellData<Object> cellData = new WriteCellData<>(new BigDecimal(object));
cellData.setType(CellDataTypeEnum.NUMBER);
return cellData;
}
}

View File

@ -0,0 +1,73 @@
package cc.iotkit.common.excel.convert;
import cc.iotkit.common.excel.annotation.ExcelDictFormat;
import cc.iotkit.common.excel.utils.ExcelUtil;
import cc.iotkit.common.service.DictService;
import cc.iotkit.common.utils.SpringUtils;
import cc.iotkit.common.utils.StringUtils;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
/**
*
*
* @author Lion Li
*/
@Slf4j
public class ExcelDictConvert implements Converter<Object> {
@Override
public Class<Object> supportJavaTypeKey() {
return Object.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return null;
}
@Override
public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
ExcelDictFormat anno = getAnnotation(contentProperty.getField());
String type = anno.dictType();
String label = cellData.getStringValue();
String value;
if (StringUtils.isBlank(type)) {
value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator());
} else {
value = SpringUtils.getBean(DictService.class).getDictValue(type, label, anno.separator());
}
return Convert.convert(contentProperty.getField().getType(), value);
}
@Override
public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (ObjectUtil.isNull(object)) {
return new WriteCellData<>("");
}
ExcelDictFormat anno = getAnnotation(contentProperty.getField());
String type = anno.dictType();
String value = Convert.toStr(object);
String label;
if (StringUtils.isBlank(type)) {
label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator());
} else {
label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator());
}
return new WriteCellData<>(label);
}
private ExcelDictFormat getAnnotation(Field field) {
return AnnotationUtil.getAnnotation(field, ExcelDictFormat.class);
}
}

View File

@ -0,0 +1,75 @@
package cc.iotkit.common.excel.convert;
import cc.iotkit.common.excel.annotation.ExcelEnumFormat;
import cc.iotkit.common.utils.ReflectUtils;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
*
*
* @author Liang
*/
@Slf4j
public class ExcelEnumConvert implements Converter<Object> {
@Override
public Class<Object> supportJavaTypeKey() {
return Object.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return null;
}
@Override
public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
Object codeValue = cellData.getData();
// 如果是空值
if (ObjectUtil.isNull(codeValue)) {
return null;
}
Map<Object, String> enumValueMap = beforeConvert(contentProperty);
String textValue = enumValueMap.get(codeValue);
return Convert.convert(contentProperty.getField().getType(), textValue);
}
@Override
public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (ObjectUtil.isNull(object)) {
return new WriteCellData<>("");
}
Map<Object, String> enumValueMap = beforeConvert(contentProperty);
String value = Convert.toStr(enumValueMap.get(object), "");
return new WriteCellData<>(value);
}
private Map<Object, String> beforeConvert(ExcelContentProperty contentProperty) {
ExcelEnumFormat anno = getAnnotation(contentProperty.getField());
Map<Object, String> enumValueMap = new HashMap<>();
Enum<?>[] enumConstants = anno.enumClass().getEnumConstants();
for (Enum<?> enumConstant : enumConstants) {
Object codeValue = ReflectUtils.invokeGetter(enumConstant, anno.codeField());
String textValue = ReflectUtils.invokeGetter(enumConstant, anno.textField());
enumValueMap.put(codeValue, textValue);
}
return enumValueMap;
}
private ExcelEnumFormat getAnnotation(Field field) {
return AnnotationUtil.getAnnotation(field, ExcelEnumFormat.class);
}
}

View File

@ -0,0 +1,118 @@
package cc.iotkit.common.excel.core;
import cc.iotkit.common.excel.annotation.CellMerge;
import cc.iotkit.common.utils.ReflectUtils;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
* @author Lion Li
*/
@Slf4j
public class CellMergeStrategy extends AbstractMergeStrategy {
private final List<?> list;
private final boolean hasTitle;
private int rowIndex;
public CellMergeStrategy(List<?> list, boolean hasTitle) {
this.list = list;
this.hasTitle = hasTitle;
// 行合并开始下标
this.rowIndex = hasTitle ? 1 : 0;
}
@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
List<CellRangeAddress> cellList = handle(list, hasTitle);
// the judge is necessary
if (CollUtil.isNotEmpty(cellList) && cell.getRowIndex() == rowIndex && cell.getColumnIndex() == 0) {
for (CellRangeAddress item : cellList) {
sheet.addMergedRegion(item);
}
}
}
@SneakyThrows
private List<CellRangeAddress> handle(List<?> list, boolean hasTitle) {
List<CellRangeAddress> cellList = new ArrayList<>();
if (CollUtil.isEmpty(list)) {
return cellList;
}
Field[] fields = ReflectUtils.getFields(list.get(0).getClass(), field -> !"serialVersionUID".equals(field.getName()));
// 有注解的字段
List<Field> mergeFields = new ArrayList<>();
List<Integer> mergeFieldsIndex = new ArrayList<>();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
if (field.isAnnotationPresent(CellMerge.class)) {
CellMerge cm = field.getAnnotation(CellMerge.class);
mergeFields.add(field);
mergeFieldsIndex.add(cm.index() == -1 ? i : cm.index());
if (hasTitle) {
ExcelProperty property = field.getAnnotation(ExcelProperty.class);
rowIndex = Math.max(rowIndex, property.value().length);
}
}
}
Map<Field, RepeatCell> map = new HashMap<>();
// 生成两两合并单元格
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < mergeFields.size(); j++) {
Field field = mergeFields.get(j);
Object val = ReflectUtils.invokeGetter(list.get(i), field.getName());
int colNum = mergeFieldsIndex.get(j);
if (!map.containsKey(field)) {
map.put(field, new RepeatCell(val, i));
} else {
RepeatCell repeatCell = map.get(field);
Object cellValue = repeatCell.getValue();
if (cellValue == null || "".equals(cellValue)) {
// 空值跳过不合并
continue;
}
if (!cellValue.equals(val)) {
if (i - repeatCell.getCurrent() > 1) {
cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
}
map.put(field, new RepeatCell(val, i));
} else if ((i == list.size() - 1) && (i > repeatCell.getCurrent())) {
cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
}
}
}
}
return cellList;
}
@Data
@AllArgsConstructor
static class RepeatCell {
private Object value;
private int current;
}
}

View File

@ -0,0 +1,106 @@
package cc.iotkit.common.excel.core;
import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.common.utils.StreamUtils;
import cc.iotkit.common.utils.ValidatorUtils;
import cn.hutool.core.text.CharSequenceUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelDataConvertException;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.Set;
/**
* Excel
*
* @author Yjoioooo
* @author Lion Li
*/
@Slf4j
@NoArgsConstructor
public class DefaultExcelListener<T> extends AnalysisEventListener<T> implements ExcelListener<T> {
/**
* Validator
*/
private Boolean isValidate = Boolean.TRUE;
/**
* excel
*/
private Map<Integer, String> headMap;
/**
*
*/
private ExcelResult<T> excelResult;
public DefaultExcelListener(boolean isValidate) {
this.excelResult = new DefaultExcelResult<>();
this.isValidate = isValidate;
}
/**
*
*
* @param exception ExcelDataConvertException
* @param context Excel
*/
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
String errMsg = null;
if (exception instanceof ExcelDataConvertException) {
ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
// 如果是某一个单元格的转换异常 能获取到具体行号
Integer rowIndex = excelDataConvertException.getRowIndex();
Integer columnIndex = excelDataConvertException.getColumnIndex();
errMsg = CharSequenceUtil.format("第{}行-第{}列-表头{}: 解析异常<br/>",
rowIndex + 1, columnIndex + 1, headMap.get(columnIndex));
if (log.isDebugEnabled()) {
log.error(errMsg);
}
}
if (exception instanceof ConstraintViolationException) {
ConstraintViolationException constraintViolationException = (ConstraintViolationException) exception;
Set<ConstraintViolation<?>> constraintViolations = constraintViolationException.getConstraintViolations();
String constraintViolationsMsg = StreamUtils.join(constraintViolations, ConstraintViolation::getMessage, ", ");
errMsg = CharSequenceUtil.format("第{}行数据校验异常: {}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg);
if (log.isDebugEnabled()) {
log.error(errMsg);
}
}
excelResult.getErrorList().add(errMsg);
throw new ExcelAnalysisException(errMsg);
}
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
this.headMap = headMap;
log.debug("解析到一条表头数据: {}", JsonUtils.toJsonString(headMap));
}
@Override
public void invoke(T data, AnalysisContext context) {
if (Boolean.TRUE.equals(isValidate)) {
ValidatorUtils.validate(data);
}
excelResult.getList().add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.debug("所有数据解析完成!");
}
@Override
public ExcelResult<T> getExcelResult() {
return excelResult;
}
}

View File

@ -0,0 +1,73 @@
package cc.iotkit.common.excel.core;
import cn.hutool.core.text.CharSequenceUtil;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
/**
* excel
*
* @author Yjoioooo
* @author Lion Li
*/
public class DefaultExcelResult<T> implements ExcelResult<T> {
/**
* list
*/
@Setter
private List<T> list;
/**
*
*/
@Setter
private List<String> errorList;
public DefaultExcelResult() {
this.list = new ArrayList<>();
this.errorList = new ArrayList<>();
}
public DefaultExcelResult(List<T> list, List<String> errorList) {
this.list = list;
this.errorList = errorList;
}
public DefaultExcelResult(ExcelResult<T> excelResult) {
this.list = excelResult.getList();
this.errorList = excelResult.getErrorList();
}
@Override
public List<T> getList() {
return list;
}
@Override
public List<String> getErrorList() {
return errorList;
}
/**
*
*
* @return
*/
@Override
public String getAnalysis() {
int successCount = list.size();
int errorCount = errorList.size();
if (successCount == 0) {
return "读取失败,未解析到数据";
} else {
if (errorCount == 0) {
return CharSequenceUtil.format("恭喜您,全部读取成功!共{}条", successCount);
} else {
return "";
}
}
}
}

View File

@ -0,0 +1,14 @@
package cc.iotkit.common.excel.core;
import com.alibaba.excel.read.listener.ReadListener;
/**
* Excel
*
* @author Lion Li
*/
public interface ExcelListener<T> extends ReadListener<T> {
ExcelResult<T> getExcelResult();
}

View File

@ -0,0 +1,26 @@
package cc.iotkit.common.excel.core;
import java.util.List;
/**
* excel
*
* @author Lion Li
*/
public interface ExcelResult<T> {
/**
*
*/
List<T> getList();
/**
*
*/
List<String> getErrorList();
/**
*
*/
String getAnalysis();
}

View File

@ -0,0 +1,327 @@
package cc.iotkit.common.excel.utils;
import cc.iotkit.common.excel.convert.ExcelBigNumberConvert;
import cc.iotkit.common.excel.core.CellMergeStrategy;
import cc.iotkit.common.excel.core.DefaultExcelListener;
import cc.iotkit.common.excel.core.ExcelListener;
import cc.iotkit.common.excel.core.ExcelResult;
import cc.iotkit.common.utils.StringUtils;
import cc.iotkit.common.web.utils.ServletUtils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* Excel
*
* @author Lion Li
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ExcelUtil {
/**
* ()
*
* @param is
* @return
*/
public static <T> List<T> importExcel(InputStream is, Class<T> clazz) {
return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync();
}
/**
* 使
*
* @param is
* @param clazz
* @param isValidate Validator
* @return
*/
public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, boolean isValidate) {
DefaultExcelListener<T> listener = new DefaultExcelListener<>(isValidate);
EasyExcel.read(is, clazz, listener).sheet().doRead();
return listener.getExcelResult();
}
/**
* 使
*
* @param is
* @param clazz
* @param listener
* @return
*/
public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, ExcelListener<T> listener) {
EasyExcel.read(is, clazz, listener).sheet().doRead();
return listener.getExcelResult();
}
/**
* excel
*
* @param list
* @param sheetName
* @param clazz
* @param response
*/
public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) {
try {
resetResponse(sheetName, response);
ServletOutputStream os = response.getOutputStream();
exportExcel(list, sheetName, clazz, false, os);
} catch (IOException e) {
throw new RuntimeException("导出Excel异常");
}
}
/**
* excel
*
* @param list
* @param sheetName
* @param clazz
* @param merge
* @param response
*/
public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, boolean merge, HttpServletResponse response) {
try {
resetResponse(sheetName, response);
ServletOutputStream os = response.getOutputStream();
exportExcel(list, sheetName, clazz, merge, os);
} catch (IOException e) {
throw new RuntimeException("导出Excel异常");
}
}
/**
* excel
*
* @param list
* @param sheetName
* @param clazz
* @param os
*/
public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, OutputStream os) {
exportExcel(list, sheetName, clazz, false, os);
}
/**
* excel
*
* @param list
* @param sheetName
* @param clazz
* @param merge
* @param os
*/
public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, boolean merge, OutputStream os) {
ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz)
.autoCloseStream(false)
// 自动适配
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
// 大数值自动转换 防止失真
.registerConverter(new ExcelBigNumberConvert())
.sheet(sheetName);
if (merge) {
// 合并处理器
builder.registerWriteHandler(new CellMergeStrategy(list, true));
}
builder.doWrite(list);
}
/**
* {.}
*
* @param filename
* @param templatePath resource
* : excel/temp.xlsx
* : resource
* @param data
* @param response
*/
public static void exportTemplate(List<Object> data, String filename, String templatePath, HttpServletResponse response) {
try {
resetResponse(filename, response);
ServletOutputStream os = response.getOutputStream();
exportTemplate(data, templatePath, os);
} catch (IOException e) {
throw new RuntimeException("导出Excel异常");
}
}
/**
* {.}
*
* @param templatePath resource
* : excel/temp.xlsx
* : resource
* @param data
* @param os
*/
public static void exportTemplate(List<Object> data, String templatePath, OutputStream os) {
ClassPathResource templateResource = new ClassPathResource(templatePath);
ExcelWriter excelWriter = EasyExcel.write(os)
.withTemplate(templateResource.getStream())
.autoCloseStream(false)
// 大数值自动转换 防止失真
.registerConverter(new ExcelBigNumberConvert())
.build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
if (CollUtil.isEmpty(data)) {
throw new IllegalArgumentException("数据为空");
}
// 单表多数据导出 模板格式为 {.属性}
for (Object d : data) {
excelWriter.fill(d, writeSheet);
}
excelWriter.finish();
}
/**
* {key.}
*
* @param filename
* @param templatePath resource
* : excel/temp.xlsx
* : resource
* @param data
* @param response
*/
public static void exportTemplateMultiList(Map<String, Object> data, String filename, String templatePath, HttpServletResponse response) {
try {
resetResponse(filename, response);
ServletOutputStream os = response.getOutputStream();
exportTemplateMultiList(data, templatePath, os);
} catch (IOException e) {
throw new RuntimeException("导出Excel异常");
}
}
/**
* {key.}
*
* @param templatePath resource
* : excel/temp.xlsx
* : resource
* @param data
* @param os
*/
public static void exportTemplateMultiList(Map<String, Object> data, String templatePath, OutputStream os) {
ClassPathResource templateResource = new ClassPathResource(templatePath);
ExcelWriter excelWriter = EasyExcel.write(os)
.withTemplate(templateResource.getStream())
.autoCloseStream(false)
// 大数值自动转换 防止失真
.registerConverter(new ExcelBigNumberConvert())
.build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
if (CollUtil.isEmpty(data)) {
throw new IllegalArgumentException("数据为空");
}
for (Map.Entry<String, Object> map : data.entrySet()) {
// 设置列表后续还有数据
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
if (map.getValue() instanceof Collection) {
// 多表导出必须使用 FillWrapper
excelWriter.fill(new FillWrapper(map.getKey(), (Collection<?>) map.getValue()), fillConfig, writeSheet);
} else {
excelWriter.fill(map.getValue(), writeSheet);
}
}
excelWriter.finish();
}
/**
*
*/
private static void resetResponse(String sheetName, HttpServletResponse response) {
String filename = encodingFilename(sheetName);
ServletUtils.setAttachmentResponseHeader(response, filename);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
}
/**
* 0=,1=,2=
*
* @param propertyValue
* @param converterExp
* @param separator
* @return
*/
public static String convertByExp(String propertyValue, String converterExp, String separator) {
StringBuilder propertyString = new StringBuilder();
String[] convertSource = converterExp.split(StringUtils.SEPARATOR);
for (String item : convertSource) {
String[] itemArray = item.split("=");
if (StringUtils.containsAny(propertyValue, separator)) {
for (String value : propertyValue.split(separator)) {
if (itemArray[0].equals(value)) {
propertyString.append(itemArray[1]).append(separator);
break;
}
}
} else {
if (itemArray[0].equals(propertyValue)) {
return itemArray[1];
}
}
}
return StringUtils.stripEnd(propertyString.toString(), separator);
}
/**
* =0,=1,=2
*
* @param propertyValue
* @param converterExp
* @param separator
* @return
*/
public static String reverseByExp(String propertyValue, String converterExp, String separator) {
StringBuilder propertyString = new StringBuilder();
String[] convertSource = converterExp.split(StringUtils.SEPARATOR);
for (String item : convertSource) {
String[] itemArray = item.split("=");
if (StringUtils.containsAny(propertyValue, separator)) {
for (String value : propertyValue.split(separator)) {
if (itemArray[1].equals(value)) {
propertyString.append(itemArray[0]).append(separator);
break;
}
}
} else {
if (itemArray[1].equals(propertyValue)) {
return itemArray[0];
}
}
}
return StringUtils.stripEnd(propertyString.toString(), separator);
}
/**
*
*/
public static String encodingFilename(String filename) {
return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
}
}

69
iot-common-log/pom.xml Executable file
View File

@ -0,0 +1,69 @@
<?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>iot-iita-core</artifactId>
<groupId>cc.iotkit</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-common-log</artifactId>
<dependencies>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-core</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-web</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-satoken</artifactId>
</dependency>
<!--====================第三方库===================-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1 @@
cc.iotkit.common.log.aspect.LogAspect

46
iot-common-oss/pom.xml Executable file
View File

@ -0,0 +1,46 @@
<?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>iot-iita-core</artifactId>
<groupId>cc.iotkit</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-common-oss</artifactId>
<dependencies>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-redis</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-core</artifactId>
</dependency>
<!--====================第三方库===================-->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,38 @@
package cc.iotkit.common.oss.constant;
import java.util.Arrays;
import java.util.List;
/**
*
*
* @author Lion Li
*/
public interface OssConstant {
/**
* KEY
*/
String DEFAULT_CONFIG_KEY = "sys_oss:default_config";
/**
* Key
*/
String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource";
/**
* ids
*/
List<Long> SYSTEM_DATA_IDS = Arrays.asList(1L, 2L, 3L, 4L);
/**
*
*/
String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"};
/**
* https
*/
String IS_HTTPS = "Y";
}

View File

@ -0,0 +1,260 @@
package cc.iotkit.common.oss.core;
import cc.iotkit.common.oss.constant.OssConstant;
import cc.iotkit.common.oss.entity.UploadResult;
import cc.iotkit.common.oss.enumd.AccessPolicyType;
import cc.iotkit.common.oss.enumd.PolicyType;
import cc.iotkit.common.oss.exception.OssException;
import cc.iotkit.common.oss.properties.OssProperties;
import cc.iotkit.common.utils.DateUtils;
import cc.iotkit.common.utils.StringUtils;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.HttpMethod;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
/**
* S3 S3
* minio
*
* @author Lion Li
*/
public class OssClient {
private final String configKey;
private final OssProperties properties;
private final AmazonS3 client;
public OssClient(String configKey, OssProperties ossProperties) {
this.configKey = configKey;
this.properties = ossProperties;
try {
AwsClientBuilder.EndpointConfiguration endpointConfig =
new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion());
AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey());
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
ClientConfiguration clientConfig = new ClientConfiguration();
if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) {
clientConfig.setProtocol(Protocol.HTTPS);
} else {
clientConfig.setProtocol(Protocol.HTTP);
}
AmazonS3ClientBuilder build = AmazonS3Client.builder()
.withEndpointConfiguration(endpointConfig)
.withClientConfiguration(clientConfig)
.withCredentials(credentialsProvider)
.disableChunkedEncoding();
if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) {
// minio 使用https限制使用域名访问 需要此配置 站点填域名
build.enablePathStyleAccess();
}
this.client = build.build();
createBucket();
} catch (Exception e) {
if (e instanceof OssException) {
throw e;
}
throw new OssException("配置错误! 请检查系统配置:[" + e.getMessage() + "]");
}
}
public void createBucket() {
try {
String bucketName = properties.getBucketName();
if (client.doesBucketExistV2(bucketName)) {
return;
}
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
AccessPolicyType accessPolicy = getAccessPolicy();
createBucketRequest.setCannedAcl(accessPolicy.getAcl());
client.createBucket(createBucketRequest);
client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType()));
} catch (Exception e) {
throw new OssException("创建Bucket失败, 请核对配置信息:[" + e.getMessage() + "]");
}
}
public UploadResult upload(byte[] data, String path, String contentType) {
return upload(new ByteArrayInputStream(data), path, contentType);
}
public UploadResult upload(InputStream inputStream, String path, String contentType) {
if (!(inputStream instanceof ByteArrayInputStream)) {
inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream));
}
try {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(contentType);
metadata.setContentLength(inputStream.available());
PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata);
// 设置上传对象的 Acl 为公共读
putObjectRequest.setCannedAcl(getAccessPolicy().getAcl());
client.putObject(putObjectRequest);
} catch (Exception e) {
throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
}
return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
}
public void delete(String path) {
path = path.replace(getUrl() + "/", "");
try {
client.deleteObject(properties.getBucketName(), path);
} catch (Exception e) {
throw new OssException("删除文件失败,请检查配置信息:[" + e.getMessage() + "]");
}
}
public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
return upload(data, getPath(properties.getPrefix(), suffix), contentType);
}
public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
}
/**
*
*
* @param path
*/
public ObjectMetadata getObjectMetadata(String path) {
path = path.replace(getUrl() + "/", "");
S3Object object = client.getObject(properties.getBucketName(), path);
return object.getObjectMetadata();
}
public InputStream getObjectContent(String path) {
path = path.replace(getUrl() + "/", "");
S3Object object = client.getObject(properties.getBucketName(), path);
return object.getObjectContent();
}
public String getUrl() {
String domain = properties.getDomain();
String endpoint = properties.getEndpoint();
String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://";
// 云服务商直接返回
if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) {
if (StringUtils.isNotBlank(domain)) {
return header + domain;
}
return header + properties.getBucketName() + "." + endpoint;
}
// minio 单独处理
if (StringUtils.isNotBlank(domain)) {
return header + domain + "/" + properties.getBucketName();
}
return header + endpoint + "/" + properties.getBucketName();
}
public String getPath(String prefix, String suffix) {
// 生成uuid
String uuid = IdUtil.fastSimpleUUID();
// 文件路径
String path = DateUtils.datePath() + "/" + uuid;
if (StringUtils.isNotBlank(prefix)) {
path = prefix + "/" + path;
}
return path + suffix;
}
public String getConfigKey() {
return configKey;
}
/**
* URL
*
* @param objectKey KEY
* @param second
*/
public String getPrivateUrl(String objectKey, Integer second) {
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
.withMethod(HttpMethod.GET)
.withExpiration(new Date(System.currentTimeMillis() + 1000L * second));
URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}
/**
*
*/
public boolean checkPropertiesSame(OssProperties properties) {
return this.properties.equals(properties);
}
/**
*
*
* @return code
*/
public AccessPolicyType getAccessPolicy() {
return AccessPolicyType.getByType(properties.getAccessPolicy());
}
private static String getPolicy(String bucketName, PolicyType policyType) {
String location = "";
switch (policyType) {
case WRITE:
location = "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n";
break;
case READ_WRITE:
location = "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n";
break;
default:
location = "\"s3:GetBucketLocation\"\n";
}
StringBuilder builder = new StringBuilder();
builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
builder.append(location);
builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
builder.append(bucketName);
builder.append("\"\n},\n");
if (policyType == PolicyType.READ) {
builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
builder.append(bucketName);
builder.append("\"\n},\n");
}
String action = "";
switch (policyType) {
case WRITE:
action = "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
break;
case READ_WRITE:
action = "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
break;
default:
action = "\"s3:GetObject\",\n";
}
builder.append("{\n\"Action\": ");
builder.append(action);
builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
builder.append(bucketName);
builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
return builder.toString();
}
}

View File

@ -0,0 +1,24 @@
package cc.iotkit.common.oss.entity;
import lombok.Builder;
import lombok.Data;
/**
*
*
* @author Lion Li
*/
@Data
@Builder
public class UploadResult {
/**
*
*/
private String url;
/**
*
*/
private String filename;
}

View File

@ -0,0 +1,56 @@
package cc.iotkit.common.oss.enumd;
import cc.iotkit.common.exception.BizException;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 访
*
* @author
*/
@Getter
@AllArgsConstructor
public enum AccessPolicyType {
/**
* private
*/
PRIVATE("0", CannedAccessControlList.Private, PolicyType.WRITE),
/**
* public
*/
PUBLIC("1", CannedAccessControlList.PublicRead, PolicyType.READ),
/**
* custom
*/
CUSTOM("2",CannedAccessControlList.PublicRead, PolicyType.READ);
/**
*
*/
private final String type;
/**
*
*/
private final CannedAccessControlList acl;
/**
*
*/
private final PolicyType policyType;
public static AccessPolicyType getByType(String type) {
for (AccessPolicyType value : values()) {
if (value.getType().equals(type)) {
return value;
}
}
throw new BizException("'type' not found By " + type);
}
}

View File

@ -0,0 +1,35 @@
package cc.iotkit.common.oss.enumd;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* minio
*
* @author Lion Li
*/
@Getter
@AllArgsConstructor
public enum PolicyType {
/**
*
*/
READ("read-only"),
/**
*
*/
WRITE("write-only"),
/**
*
*/
READ_WRITE("read-write");
/**
*
*/
private final String type;
}

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