Merge branch 'dev-V0.4.5' of https://gitee.com/iotkit-open-source/iotkit-parent into dev-V0.4.5

V0.5.x
荭琪枫 2023-05-29 09:58:50 +08:00
commit 488c526055
820 changed files with 27418 additions and 4194 deletions

1
.gitignore vendored
View File

@ -23,7 +23,6 @@ hs_err_pid*
.idea
target
*.iml
log
data/elasticsearch
.init
*.db

View File

@ -79,19 +79,19 @@ Vertx event-bus内置、RocketMQ通过扩展模块可接入其它任意
##### 关系数据库切换为mysql方法其它数据库同理
1、将iot-rdb-data-service/pom.xml中的mysql驱动注释放开
1、将iot-data-serviceImpl-rdb/pom.xml中的mysql驱动注释放开
2、启动时指定active: --spring.profiles.active=mysql
##### 时序数据库切换为TDengein方法
1、注释掉iot-standalone/pom.xml中的 iot-es-temporal-service并打开iot-td-temporal-service的注释
1、注释掉iot-standalone/pom.xml中的 iot-temporal-serviceImpl-es并打开iot-td-temporal-service的注释
2、application.xml中注释掉elasticsearch配置并打开td-datasource配置
##### 消息总线切换为RocketMq方法
1、注释掉iot-standalone/pom.xml中的 iot-vertx-event-bus并打开iot-message-rocketmq的注释
1、注释掉iot-standalone/pom.xml中的 iot-message-event-bus并打开iot-message-rocketmq的注释
2、application.xml中打开rocketmq配置

Binary file not shown.

View File

@ -1,7 +1,5 @@
var mid=1;
var access_token="";
function getMid(){
mid++;
if(mid>10000){
@ -9,58 +7,94 @@ function getMid(){
}
return mid;
};
function getPingData(data){
var ping={
productKey:"",
deviceName:"",
content:{
id:getMid(),
type:data
}
};
function getPkDn(deviceKey){
var arr=deviceKey.split("_");
return {
type:"action",
data:{
productKey:"",
deviceName:"",
state:""
},
action:{
type:"ack",
content:JSON.stringify(ping)
pk:arr[1],
dn:deviceKey
};
}
function register(data){
var device=getPkDn(data.data.deviceName)
var subDevicesList=data.data.subDevices
var subDevices=[]
if(subDevicesList!=undefined&&subDevicesList.length>0){
apiTool.log("device:"+subDevicesList);
for (var i = 0; i < subDevicesList.length; i++) {
var deviceKey=subDevicesList[i]
var subDevice=getPkDn(deviceKey)
subDevices.push({
productKey:subDevice.pk,
deviceName:subDevice.dn,
model:''
})
}
}
};
var reply=
{
productKey:device.pk,
deviceName:device.dn,
mid:"0",
content:{
id:data.id,
type:data.type,
result:'success'
}
};
var data={
productKey:device.pk,
deviceName:device.dn
}
if(subDevices.length>0){
data['subDevices']=subDevices
}
apiTool.log("subDevices:"+JSON.stringify(data));
return {
type:"register",
data:data,
action:{
type:"ack",
content:JSON.stringify(reply)
}
};
}
function online(data){
apiTool.log("data:"+JSON.stringify(data));
var device=getPkDn(data.data.deviceName)
return {
type:"state",
data:{
productKey:device.pk,
deviceName:device.dn,
state:data.type
}
};
}
function offline(data){
var device=getPkDn(data.deviceKey)
return {
type:"state",
data:{
productKey:device.pk,
deviceName:device.dn,
state:data.type
}
};
}
//必须提供onReceive方法
this.onReceive=function(head,type,payload){
var data=JSON.parse(payload)
if(data.type=="auth_required"){
var auth={
productKey:"",
deviceName:"",
content:{
type:"auth",
access_token:access_token
}
};
return {
type:"action",
data:{
productKey:"",
deviceName:"",
state:""
},
action:{
type:"ack",
content:JSON.stringify(auth)
}
}
}else if(data.type=="auth_ok"){
return getPingData(data.heartBeatData);
}else if(data.type=="pong"){
apiTool.log("receive pong!");
}else if("ping"==type){
return getPingData(data.heartBeatData);
if(data.type=="register"){
apiTool.log("data:"+payload);
return register(data)
}else if(data.type=="online"){
return online(data);
}else if(data.type=="offline"){
return offline(data);
}
return {
productKey:"",
@ -70,3 +104,7 @@ this.onReceive=function(head,type,payload){
}
}
};
this.onRegistered=function (data,status) {
apiTool.log("onRegistered调用");
}

View File

@ -1,7 +1,7 @@
var mid=1;
var gatewayPk="BRD3x4fkKxkaxXFt"
var smartMeterPk="PjmkANSTDt85bZPj"
var smartMeterPk="PwMfpXmp4ZWkGahn"
function getMid(){
mid++;

View File

@ -1,74 +0,0 @@
var pidPkMap={
"H5Z31yKBmy":"3ptfx2dRescPAwTn",
"xOCy76jn6k":"jzC6eQGRse6hDZPB"
}
this.onReceive=function(method,path,header,params,body){
var type=header["Content-Type"];
if(type=="application/json"){
var msg=JSON.parse(body.msg);
var productId=msg.productId;
var deviceName=msg.deviceName;
var messageType=msg.messageType;
var data=msg.data;
var pk=pidPkMap[productId];
if(!pk){
return {
url:"",
header:{
contentType:"application/json"
},
content:"error"
}
}
if(messageType=="lifeCycle"){
//登录、登出
var online=data.status=="online";
deviceBehaviour.deviceStateChange(pk,deviceName,online);
}else if(messageType=="notify"){
//设备消息
//消息类型
var notifyType=msg.notifyType;
if(notifyType=="property"){
//属性上报
var propertyData={};
for(var p in data.params){
propertyData[p]=data.params[p].value;
}
deviceBehaviour.reportMessage(JSON.stringify({
mid:data.id,
productKey:pk,
deviceName:deviceName,
type:"property",
identifier:"report",
data:propertyData
}));
}else if(notifyType=="event"){
//事件上报
var identifier="";
var paramData={};
for(var p in data.params){
identifier=p;
paramData=data.params[p];
}
deviceBehaviour.reportMessage(JSON.stringify({
mid:data.id,
productKey:pk,
deviceName:deviceName,
type:"event",
identifier:identifier,
data:paramData.value
}));
}
}
}
return {
url:"",
header:{
contentType:"application/json"
},
content:JSON.stringify(params.msg)
}
};

View File

@ -43,5 +43,10 @@
"id": "FreshAir",
"name": "新风",
"createAt": 1681444312184
},
{
"id": "SmartMeter",
"name": "智能电表",
"createAt": 1681444312184
}
]

23
data/init/channel.json Normal file
View File

@ -0,0 +1,23 @@
[
{
"id": "fa1c5eaa-de6e-48b6-805e-8f091c7bb831",
"code": "DingTalk",
"title": "钉钉",
"icon": "http://www.baidu.com",
"createAt": 1683816661690
},
{
"id": "fa1c5eaa-de6e-48b6-805e-8f091c7bb832",
"code": "QyWechat",
"title": "企业微信",
"icon": "http://www.baidu.com",
"createAt": 1683816661690
},
{
"id": "fa1c5eaa-de6e-48b6-805e-8f091c7bb833",
"code": "Email",
"title": "邮箱",
"icon": "http://www.baidu.com",
"createAt": 1683816661690
}
]

View File

@ -984,8 +984,8 @@
}
},
{
"id": "a5fnnx3ksu7n2n0f",
"productKey": "a5fnnx3ksu7n2n0f",
"id": "bGdZt8ffBETtsirm",
"productKey": "bGdZt8ffBETtsirm",
"model": {
"properties": [
{
@ -1115,8 +1115,8 @@
}
},
{
"id": "PjmkANSTDt85bZPj",
"productKey": "PjmkANSTDt85bZPj",
"id": "PwMfpXmp4ZWkGahn",
"productKey": "PwMfpXmp4ZWkGahn",
"model": {
"properties": [
{

77
git规范.md Normal file
View File

@ -0,0 +1,77 @@
# **提交规范**
## **例子**
```
feat(miniprogram):新增自开奖页面
新增活动页面,但是产品还有需求遗漏,待完善
- 新增内容1
- 新增内容2
```
```
fix(miniprogram):活动页面设置渠道后,自动添加渠道文字类型判断错误
```
## **Commit message 格式**
为了方便使用,我们避免了过于复杂的规定,格式较为简单且不限制中英文:
```
<type>(<scope>): <subject>
// 空一行
<body>
// 空一行
// 注意冒号 : 后有空格
// 如 feat(miniprogram): 增加了小程序模板消息相关功能
```
大致分为两个个部分:
1. 标题行: 包括` <type>(<scope>): <subject>`
2. 主题内容: 描述了为什么修改,做了什么修改,以及开发思路等
| | 说明 | 必填 |
| ------- | ---------------------- | ------ |
| type | 修改类型 | 必填 |
| scope | 作用范围 | 非必填 |
| subject | 对commit的简单描述 | 必填 |
| body | 本次 commit 的详细描述 | 非必填 |
### **1.type**
```
feat新功能feature
fix修补bug
docs文档documentation
style 格式(不影响代码运行的变动)
refactor重构即不是新增功能也不是修改bug的代码变动
test增加测试
chore构建过程或辅助工具的变动
```
如果type为feat和fix则该 commit 将肯定出现在 Change log 之中。其他情况docs、chore、style、refactor、test由你决定要不要放入 Change log建议是不要。
### **2.scope**
scope用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。
### **3. subject**
subject是 commit 目的的简短描述不超过50个字符。
```
以动词开头使用第一人称现在时比如change而不是changed或changes
第一个字母小写
结尾不加句号(.
```
### **4. body**
Body 部分是对本次 commit 的详细描述,可以分成多行。描述为什么修改, 做了什么样的修改, 以及开发的思路等等

View File

@ -1,59 +0,0 @@
<?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>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.4.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-auth-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-oauth2</artifactId>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis-jackson</artifactId>
</dependency>
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>okhttps</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-data-service</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1 +0,0 @@
此模块为认证服务提供oauth2认证界面和接口

View File

@ -1,138 +0,0 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.oauth.controller;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.data.IOauthClientData;
import cc.iotkit.data.IUserInfoData;
import cc.iotkit.model.OauthClient;
import cc.iotkit.model.UserInfo;
import cc.iotkit.oauth.vo.UserInfoVo;
import cc.iotkit.utils.SoMap;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.ejlchina.okhttps.OkHttps;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/oauth2")
public class AuthClientController {
@Value("${oauth2.auth-server-url}")
private String serverUrl;
@Autowired
@Qualifier("oauthClientDataCache")
private IOauthClientData oauthClientData;
@Autowired
@Qualifier("userInfoDataCache")
private IUserInfoData userInfoData;
/**
* Code Access-Token
*/
@RequestMapping("/codeLogin")
public SaResult codeLogin(String code, String clientId) {
OauthClient oauthClient = oauthClientData.findByClientId(clientId);
if (oauthClient == null) {
return SaResult.error("clientId does not exist");
}
String clientSecret = oauthClient.getClientSecret();
// 调用Server端接口获取 Access-Token 以及其他信息
String str = OkHttps.sync(serverUrl + "/oauth2/token")
.addBodyPara("grant_type", "authorization_code")
.addBodyPara("code", code)
.addBodyPara("client_id", clientId)
.addBodyPara("client_secret", clientSecret)
.post()
.getBody()
.toString();
SoMap so = SoMap.getSoMap().setJsonString(str);
log.info("get token by code result:{}", so);
// 存在code,不是token结构
if (so.getInt("code") != 0) {
return SaResult.error(so.getString("msg"));
}
// 根据openid获取其对应的userId
String uid = getUserIdByOpenid(so.getString("openid"));
String access_token = so.getString("access_token");
UserInfoVo userVo = getUserInfo(uid);
BeanMap beanMap = BeanMap.create(userVo);
Map<String, Object> data = new HashMap<>();
beanMap.forEach((key, value) -> {
data.put(key.toString(), value);
});
data.put("access_token", access_token);
// 返回相关参数
StpUtil.login(uid, SaLoginConfig.setToken(access_token));
return SaResult.data(data);
}
/**
*
*/
@RequestMapping("/logout")
public RedirectView logout(String accessToken, String redirect_uri) {
//先注销client中cookie的token
StpUtil.logout();
//再注销web页面使用的token
StpUtil.logoutByTokenValue(accessToken);
return new RedirectView(redirect_uri);
}
/**
*
*/
@GetMapping("/checkLogin")
public SaResult checkLogin() {
try {
String uid = StpUtil.getLoginId().toString();
UserInfoVo userVo = getUserInfo(uid);
return SaResult.ok().setData(userVo);
} catch (Throwable e) {
return SaResult.error("no login");
}
}
@SneakyThrows
private String getUserIdByOpenid(String openid) {
String clientIdLoginId = CodecUtil.aesDecrypt(openid, Constants.ACCOUNT_SECRET);
return clientIdLoginId.split(":")[1];
}
private UserInfoVo getUserInfo(String uid) {
UserInfo userInfo = userInfoData.findById(uid);
UserInfoVo userVo = new UserInfoVo();
ReflectUtil.copyNoNulls(userInfo, userVo);
return userVo;
}
}

View File

@ -1,99 +0,0 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.oauth.controller;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.data.IUserInfoData;
import cc.iotkit.model.UserInfo;
import cc.iotkit.oauth.service.TokenRequestHandler;
import cc.iotkit.utils.AuthUtil;
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@RestController
public class AuthServerController {
@Autowired
private IUserInfoData userInfoData;
/**
* OAuth
*/
@RequestMapping("/oauth2/*")
public Object request(HttpServletRequest request) {
Object result = TokenRequestHandler.serverRequest();
log.info("oauth path:{},result:{}", request.getRequestURI(), JsonUtil.toJsonString(result));
return result;
}
/**
* Sa-OAuth2
*/
@Autowired
public void setSaOAuth2Config(SaOAuth2Config cfg) {
cfg.
// 未登录的视图
setNotLoginView(() -> new ModelAndView("login.html")).
// 登录处理函数
setDoLoginHandle((name, pwd) -> {
try {
UserInfo userInfo = userInfoData.findByUid(name);
if (userInfo != null) {
String secret = userInfo.getSecret();
if (AuthUtil.checkPwd(pwd, secret)) {
StpUtil.login(userInfo.getId(), "PC");
return SaResult.ok();
}
}
} catch (Throwable e) {
return SaResult.error("账号名或密码错误");
}
return SaResult.error("账号名或密码错误");
}).
// 授权确认视图
setConfirmView((clientId, scope) -> {
Map<String, Object> map = new HashMap<>();
map.put("clientId", clientId);
map.put("scope", scope);
return new ModelAndView("confirm.html", map);
})
;
//开启密码授权、刷新token和client授权模式
cfg.setIsPassword(true);
cfg.setIsNewRefresh(true);
cfg.setIsClient(true);
}
// 全局异常拦截
@ExceptionHandler
public SaResult handlerException(Exception e) {
e.printStackTrace();
return SaResult.error(e.getMessage());
}
@RequestMapping("/oauth2/userinfo")
public SaResult userinfo() {
return SaResult.ok();
}
}

View File

@ -1,61 +0,0 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.oauth.service;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.data.IOauthClientData;
import cc.iotkit.model.OauthClient;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Template;
import cn.dev33.satoken.oauth2.model.SaClientModel;
import cn.dev33.satoken.stp.StpUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
public class SaOAuth2TemplateImpl extends SaOAuth2Template {
@Autowired
@Qualifier("oauthClientDataCache")
private IOauthClientData oauthClientData;
// 根据 id 获取 Client 信息
@Override
public SaClientModel getClientModel(String clientId) {
OauthClient client = oauthClientData.findByClientId(clientId);
if (client == null) {
return null;
}
return new SaClientModel()
.setClientId(client.getClientId())
.setClientSecret(client.getClientSecret())
.setAllowUrl(client.getAllowUrl())
.setContractScope("userinfo")
.setIsAutoMode(true);
}
// 根据ClientId 和 LoginId 获取openid
@SneakyThrows
@Override
public String getOpenid(String clientId, Object loginId) {
// 此为模拟数据,真实环境需要从数据库查询
return CodecUtil.aesEncrypt(clientId + ":" + loginId, Constants.ACCOUNT_SECRET);
}
@Override
public String randomAccessToken(String clientId, Object loginId, String scope) {
return StpUtil.createLoginSession(loginId);
}
}

View File

@ -1,46 +0,0 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.oauth.service;
import cc.iotkit.data.IUserInfoData;
import cc.iotkit.model.UserInfo;
import cn.dev33.satoken.stp.StpInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class StpInterfaceImpl implements StpInterface {
@Autowired
@Qualifier("userInfoDataCache")
private IUserInfoData userInfoData;
/**
*
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
UserInfo userInfo = userInfoData.findById(loginId.toString());
return userInfo.getPermissions();
}
/**
* ()
*/
@Override
public List<String> getRoleList(Object loginId, String loginType) {
UserInfo userInfo = userInfoData.findById(loginId.toString());
return userInfo.getRoles();
}
}

View File

@ -1,124 +0,0 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.oauth.service;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Handle;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
import cn.dev33.satoken.oauth2.model.SaClientModel;
import cn.dev33.satoken.stp.StpUtil;
public class TokenRequestHandler {
public static Object serverRequest() {
SaRequest req = SaHolder.getRequest();
SaResponse res = SaHolder.getResponse();
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
SaClientModel cm;
if (req.isPath(SaOAuth2Consts.Api.authorize) && req.isParam(SaOAuth2Consts.Param.response_type, SaOAuth2Consts.ResponseType.code)) {
cm = SaOAuth2Handle.currClientModel();
if (!cfg.getIsCode() || !cm.isCode && !cm.isAutoMode) {
throw new SaOAuth2Exception("暂未开放的授权模式");
} else {
return SaOAuth2Handle.authorize(req, res, cfg);
}
} else if (req.isPath(SaOAuth2Consts.Api.token) && req.isParam(SaOAuth2Consts.Param.grant_type, SaOAuth2Consts.GrantType.authorization_code)) {
return token(req, res, cfg);
} else if (req.isPath(SaOAuth2Consts.Api.token) && req.isParam(SaOAuth2Consts.Param.grant_type, SaOAuth2Consts.GrantType.refresh_token)) {
return refreshToken(req);
} else if (req.isPath(SaOAuth2Consts.Api.revoke)) {
return SaOAuth2Handle.revokeToken(req);
} else if (req.isPath(SaOAuth2Consts.Api.doLogin)) {
return SaOAuth2Handle.doLogin(req, res, cfg);
} else if (req.isPath(SaOAuth2Consts.Api.doConfirm)) {
return SaOAuth2Handle.doConfirm(req);
} else if (req.isPath(SaOAuth2Consts.Api.authorize) && req.isParam(SaOAuth2Consts.Param.response_type, SaOAuth2Consts.ResponseType.token)) {
cm = SaOAuth2Handle.currClientModel();
if (!cfg.getIsImplicit() || !cm.isImplicit && !cm.isAutoMode) {
throw new SaOAuth2Exception("暂未开放的授权模式");
} else {
return SaOAuth2Handle.authorize(req, res, cfg);
}
} else if (req.isPath(SaOAuth2Consts.Api.token) && req.isParam(SaOAuth2Consts.Param.grant_type, SaOAuth2Consts.GrantType.password)) {
cm = SaOAuth2Handle.currClientModel();
if (!cfg.getIsPassword() || !cm.isPassword && !cm.isAutoMode) {
throw new SaOAuth2Exception("暂未开放的授权模式");
} else {
return password(req, res, cfg);
}
} else if (req.isPath(SaOAuth2Consts.Api.token) && req.isParam(SaOAuth2Consts.Param.grant_type, SaOAuth2Consts.GrantType.client_credentials)) {
cm = SaOAuth2Handle.currClientModel();
if (!cfg.getIsClient() || !cm.isClient && !cm.isAutoMode) {
throw new SaOAuth2Exception("暂未开放的授权模式");
} else {
return clientToken(req, res, cfg);
}
} else {
return "{\"msg\": \"not handle\"}";
}
}
public static Object token(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
String code = req.getParamNotNull(SaOAuth2Consts.Param.code);
String clientId = req.getParamNotNull(SaOAuth2Consts.Param.client_id);
String clientSecret = req.getParamNotNull(SaOAuth2Consts.Param.client_secret);
String redirectUri = req.getParam(SaOAuth2Consts.Param.redirect_uri);
SaOAuth2Util.checkGainTokenParam(code, clientId, clientSecret, redirectUri);
AccessTokenModel token = SaOAuth2Util.generateAccessToken(code);
return token.toLineMap();
}
public static Object refreshToken(SaRequest req) {
String clientId = req.getParamNotNull(SaOAuth2Consts.Param.client_id);
String clientSecret = req.getParamNotNull(SaOAuth2Consts.Param.client_secret);
String refreshToken = req.getParamNotNull(SaOAuth2Consts.Param.refresh_token);
SaOAuth2Util.checkRefreshTokenParam(clientId, clientSecret, refreshToken);
return SaOAuth2Util.refreshAccessToken(refreshToken).toLineMap();
}
public static Object password(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
String username = req.getParamNotNull(SaOAuth2Consts.Param.username);
String password = req.getParamNotNull(SaOAuth2Consts.Param.password);
String clientId = req.getParamNotNull(SaOAuth2Consts.Param.client_id);
String scope = req.getParam(SaOAuth2Consts.Param.scope, "");
SaOAuth2Util.checkContract(clientId, scope);
SaHolder.getStorage().set(StpUtil.stpLogic.splicingKeyJustCreatedSave(), "no-token");
Object retObj = cfg.getDoLoginHandle().apply(username, password);
if (!StpUtil.isLogin()) {
return retObj;
} else {
RequestAuthModel ra = new RequestAuthModel();
ra.clientId = clientId;
ra.loginId = StpUtil.getLoginId();
ra.scope = scope;
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true);
return at.toLineMap();
}
}
public static Object clientToken(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
String clientId = req.getParamNotNull(SaOAuth2Consts.Param.client_id);
String clientSecret = req.getParamNotNull(SaOAuth2Consts.Param.client_secret);
String scope = req.getParam(SaOAuth2Consts.Param.scope);
SaOAuth2Util.checkContract(clientId, scope);
SaOAuth2Util.checkClientSecret(clientId, clientSecret);
ClientTokenModel ct = SaOAuth2Util.generateClientToken(clientId, scope);
return ct.toLineMap();
}
}

View File

@ -1,79 +0,0 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.oauth.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserInfoVo {
/**
*
*/
private String uid;
/**
*
*/
private String nickName;
/**
* 0- 1-male,2-female
*/
private Integer gender;
/**
*
*/
private String avatarUrl;
private String email;
private String address;
/**
* Id
*/
private String currHomeId;
/**
*
* 0:
* 1:
*/
private Integer type;
/**
*
*/
private List<String> roles = new ArrayList<>();
/**
*
*/
private List<String> permissions = new ArrayList<>();
/**
* 使
* :Constants.THIRD_PLATFORM
*/
private List<String> usePlatforms = new ArrayList<>();
}

View File

@ -1,837 +0,0 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import cc.iotkit.common.utils.JsonUtil;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* Map< String, Object> Map
* <p>MapMap使
* <p>2020-12-10
*
* @author kong
*/
public class SoMap extends LinkedHashMap<String, Object> {
private static final long serialVersionUID = 1L;
public SoMap() {
}
/**
* isNullNull
*/
public static final Object[] NULL_ELEMENT_ARRAY = {null, ""};
public static final List<Object> NULL_ELEMENT_LIST;
static {
NULL_ELEMENT_LIST = Arrays.asList(NULL_ELEMENT_ARRAY);
}
// ============================= 读值 =============================
/**
*
*/
@Override
public Object get(Object key) {
if ("this".equals(key)) {
return this;
}
return super.get(key);
}
/**
*
*/
public Object get(Object key, Object defaultValue) {
Object value = get(key);
if (valueIsNull(value)) {
return defaultValue;
}
return value;
}
/**
* String
*/
public String getString(String key) {
Object value = get(key);
if (value == null) {
return null;
}
return String.valueOf(value);
}
/**
*
*/
public String getString(String key, String defaultValue) {
Object value = get(key);
if (valueIsNull(value)) {
return defaultValue;
}
return String.valueOf(value);
}
/**
* int
*/
public int getInt(String key) {
Object value = get(key);
if (valueIsNull(value)) {
return 0;
}
return Integer.parseInt(String.valueOf(value));
}
/**
* int
*/
public int getInt(String key, int defaultValue) {
Object value = get(key);
if (valueIsNull(value)) {
return defaultValue;
}
return Integer.parseInt(String.valueOf(value));
}
/**
* long
*/
public long getLong(String key) {
Object value = get(key);
if (valueIsNull(value)) {
return 0;
}
return Long.parseLong(String.valueOf(value));
}
/**
* double
*/
public double getDouble(String key) {
Object value = get(key);
if (valueIsNull(value)) {
return 0.0;
}
return Double.parseDouble(String.valueOf(value));
}
/**
* boolean
*/
public boolean getBoolean(String key) {
Object value = get(key);
if (valueIsNull(value)) {
return false;
}
return Boolean.parseBoolean(String.valueOf(value));
}
/**
* Date
*/
public Date getDateByFormat(String key, String format) {
try {
return new SimpleDateFormat(format).parse(getString(key));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Date yyyy-MM-dd
*/
public Date getDate(String key) {
return getDateByFormat(key, "yyyy-MM-dd");
}
/**
* Date yyyy-MM-dd HH:mm:ss
*/
public Date getDateTime(String key) {
return getDateByFormat(key, "yyyy-MM-dd HH:mm:ss");
}
/**
* Map
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public SoMap getMap(String key) {
Object value = get(key);
if (value == null) {
return SoMap.getSoMap();
}
if (value instanceof Map) {
return SoMap.getSoMap((Map) value);
}
if (value instanceof String) {
return SoMap.getSoMap().setJsonString((String) value);
}
throw new RuntimeException("值无法转化为SoMap: " + value);
}
/**
* ()
*/
@SuppressWarnings("unchecked")
public List<Object> getList(String key) {
Object value = get(key);
List<Object> list;
if (value == null || value.equals("")) {
list = new ArrayList<>();
} else if (value instanceof List) {
list = (List<Object>) value;
} else {
list = new ArrayList<>();
list.add(value);
}
return list;
}
/**
* ()
*/
public <T> List<T> getList(String key, Class<T> cs) {
List<Object> list = getList(key);
List<T> list2 = new ArrayList<T>();
for (Object obj : list) {
T objC = getValueByClass(obj, cs);
list2.add(objC);
}
return list2;
}
/**
* ()()
*/
public <T> List<T> getListByComma(String key, Class<T> cs) {
String listStr = getString(key);
if (listStr == null || listStr.equals("")) {
return new ArrayList<>();
}
// 开始转化
String[] arr = listStr.split(",");
List<T> list = new ArrayList<T>();
for (String str : arr) {
if (cs == int.class || cs == Integer.class || cs == long.class || cs == Long.class) {
str = str.trim();
}
T objC = getValueByClass(str, cs);
list.add(objC);
}
return list;
}
/**
* map
*/
public <T> T getModel(Class<T> cs) {
try {
return getModelByObject(cs.newInstance());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* map
*/
public <T> T getModelByObject(T obj) {
// 获取类型
Class<?> cs = obj.getClass();
// 循环复制
for (Field field : cs.getDeclaredFields()) {
try {
// 获取对象
Object value = this.get(field.getName());
if (value == null) {
continue;
}
field.setAccessible(true);
Object valueConvert = getValueByClass(value, field.getType());
field.set(obj, valueConvert);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("属性取值出错:" + field.getName(), e);
}
}
return obj;
}
/**
*
*
* @param obj
* @param cs
* @param <T>
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getValueByClass(Object obj, Class<T> cs) {
String obj2 = String.valueOf(obj);
Object obj3;
if (cs.equals(String.class)) {
obj3 = obj2;
} else if (cs.equals(int.class) || cs.equals(Integer.class)) {
obj3 = Integer.valueOf(obj2);
} else if (cs.equals(long.class) || cs.equals(Long.class)) {
obj3 = Long.valueOf(obj2);
} else if (cs.equals(short.class) || cs.equals(Short.class)) {
obj3 = Short.valueOf(obj2);
} else if (cs.equals(byte.class) || cs.equals(Byte.class)) {
obj3 = Byte.valueOf(obj2);
} else if (cs.equals(float.class) || cs.equals(Float.class)) {
obj3 = Float.valueOf(obj2);
} else if (cs.equals(double.class) || cs.equals(Double.class)) {
obj3 = Double.valueOf(obj2);
} else if (cs.equals(boolean.class) || cs.equals(Boolean.class)) {
obj3 = Boolean.valueOf(obj2);
} else {
obj3 = (T) obj;
}
return (T) obj3;
}
// ============================= 写值 =============================
/**
* keykeyset
*/
public void setDefaultValue(String key, Object defaultValue) {
if (isNull(key)) {
set(key, defaultValue);
}
}
/**
* set
*/
public SoMap set(String key, Object value) {
// 防止敏感key
if (key.toLowerCase().equals("this")) {
return this;
}
put(key, value);
return this;
}
/**
* MapSoMap
*/
public SoMap setMap(Map<String, ?> map) {
if (map != null) {
for (String key : map.keySet()) {
this.set(key, map.get(key));
}
}
return this;
}
/**
* SoMap
*/
public SoMap setModel(Object model) {
if (model == null) {
return this;
}
Field[] fields = model.getClass().getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
boolean isStatic = Modifier.isStatic(field.getModifiers());
if (!isStatic) {
this.set(field.getName(), field.get(model));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return this;
}
/**
* jsonSoMap
*/
public SoMap setJsonString(String jsonString) {
return this.setMap(JsonUtil.parse(jsonString, Map.class));
}
// ============================= 删值 =============================
/**
* delete
*/
public SoMap delete(String key) {
remove(key);
return this;
}
/**
* valuenull
*/
public SoMap clearNull() {
Iterator<String> iterator = this.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
if (this.isNull(key)) {
iterator.remove();
this.remove(key);
}
}
return this;
}
/**
* key
*/
public SoMap clearIn(String... keys) {
List<String> keys2 = Arrays.asList(keys);
Iterator<String> iterator = this.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
if (keys2.contains(key)) {
iterator.remove();
this.remove(key);
}
}
return this;
}
/**
* key
*/
public SoMap clearNotIn(String... keys) {
List<String> keys2 = Arrays.asList(keys);
Iterator<String> iterator = this.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
if (!keys2.contains(key)) {
iterator.remove();
this.remove(key);
}
}
return this;
}
/**
* key
*/
public SoMap clearAll() {
clear();
return this;
}
// ============================= 快速构建 =============================
/**
* SoMap
*/
public static SoMap getSoMap() {
return new SoMap();
}
/**
* SoMap
*/
public static SoMap getSoMap(String key, Object value) {
return new SoMap().set(key, value);
}
/**
* SoMap
*/
public static SoMap getSoMap(Map<String, ?> map) {
return new SoMap().setMap(map);
}
/**
* SoMap
*/
public static SoMap getSoMapByModel(Object model) {
return SoMap.getSoMap().setModel(model);
}
/**
* SoMap
*/
public static List<SoMap> getSoMapByList(List<?> list) {
List<SoMap> listMap = new ArrayList<>();
for (Object model : list) {
listMap.add(getSoMapByModel(model));
}
return listMap;
}
/**
* keySoMap
*/
public SoMap cloneKeys(String... keys) {
SoMap so = new SoMap();
for (String key : keys) {
so.set(key, this.get(key));
}
return so;
}
/**
* keySoMap
*/
public SoMap cloneSoMap() {
SoMap so = new SoMap();
for (String key : this.keySet()) {
so.set(key, this.get(key));
}
return so;
}
/**
* key
*/
public SoMap toUpperCase() {
SoMap so = new SoMap();
for (String key : this.keySet()) {
so.set(key.toUpperCase(), this.get(key));
}
this.clearAll().setMap(so);
return this;
}
/**
* key
*/
public SoMap toLowerCase() {
SoMap so = new SoMap();
for (String key : this.keySet()) {
so.set(key.toLowerCase(), this.get(key));
}
this.clearAll().setMap(so);
return this;
}
/**
* key线线 (kebab-case)
*/
public SoMap toKebabCase() {
SoMap so = new SoMap();
for (String key : this.keySet()) {
so.set(wordEachKebabCase(key), this.get(key));
}
this.clearAll().setMap(so);
return this;
}
/**
* key线
*/
public SoMap toHumpCase() {
SoMap so = new SoMap();
for (String key : this.keySet()) {
so.set(wordEachBigFs(key), this.get(key));
}
this.clearAll().setMap(so);
return this;
}
/**
* key线
*/
public SoMap humpToLineCase() {
SoMap so = new SoMap();
for (String key : this.keySet()) {
so.set(wordHumpToLine(key), this.get(key));
}
this.clearAll().setMap(so);
return this;
}
// ============================= 辅助方法 =============================
/**
* keynull NULL_ELEMENT_ARRAY
*/
public boolean isNull(String key) {
return valueIsNull(get(key));
}
/**
* keyvaluenullnulltrue
*/
public boolean isContainNull(String... keys) {
for (String key : keys) {
if (this.isNull(key)) {
return true;
}
}
return false;
}
/**
* isNull()
*/
public boolean isNotNull(String key) {
return !isNull(key);
}
/**
* keyvaluenullisNotNull()
*/
public boolean has(String key) {
return !isNull(key);
}
/**
* valueSoMapnull
*/
public boolean valueIsNull(Object value) {
return NULL_ELEMENT_LIST.contains(value);
}
/**
* key
*/
public SoMap checkNull(String... keys) {
for (String key : keys) {
if (this.isNull(key)) {
throw new RuntimeException("参数" + key + "不能为空");
}
}
return this;
}
static Pattern patternNumber = Pattern.compile("[0-9]*");
/**
* key
*/
public boolean isNumber(String key) {
String value = getString(key);
if (value == null) {
return false;
}
return patternNumber.matcher(value).matches();
}
/**
* JSON
*/
public String toJsonString() {
return JsonUtil.toJsonString(this);
}
// ============================= web辅助 =============================
/**
* request
*
* @return
*/
public static SoMap getRequestSoMap() {
// 大善人SpringMVC提供的封装
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (servletRequestAttributes == null) {
throw new RuntimeException("当前线程非JavaWeb环境");
}
// 当前request
HttpServletRequest request = servletRequestAttributes.getRequest();
if (request.getAttribute("currentSoMap") == null || !(request.getAttribute("currentSoMap") instanceof SoMap)) {
initRequestSoMap(request);
}
return (SoMap) request.getAttribute("currentSoMap");
}
/**
* request SoMap
*/
private static void initRequestSoMap(HttpServletRequest request) {
SoMap soMap = new SoMap();
Map<String, String[]> parameterMap = request.getParameterMap(); // 获取所有参数
for (String key : parameterMap.keySet()) {
try {
String[] values = parameterMap.get(key); // 获得values
if (values.length == 1) {
soMap.set(key, values[0]);
} else {
soMap.set(key, Arrays.asList(values));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
request.setAttribute("currentSoMap", soMap);
}
/**
* 线JavaWeb
*
* @return
*/
public static boolean isJavaWeb() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 大善人SpringMVC提供的封装
if (servletRequestAttributes == null) {
return false;
}
return true;
}
// ============================= 常见key 以下key经常用所以封装以下方便写代码 =============================
/**
* get
*/
public int getKeyPageNo() {
int pageNo = getInt("pageNo", 1);
if (pageNo <= 0) {
pageNo = 1;
}
return pageNo;
}
/**
* get
*/
public int getKeyPageSize() {
int pageSize = getInt("pageSize", 10);
if (pageSize <= 0 || pageSize > 1000) {
pageSize = 10;
}
return pageSize;
}
/**
* get
*/
public int getKeySortType() {
return getInt("sortType");
}
// ============================= 工具方法 =============================
/**
*
*
* @param list
* @param idKey idkey
* @param parentIdKey idkey
* @param childListKey key
* @return tree
*/
public static List<SoMap> listToTree(List<SoMap> list, String idKey, String parentIdKey, String childListKey) {
// 声明新的集合存储tree形数据
List<SoMap> newTreeList = new ArrayList<>();
// 声明hash-Map方便查找数据
SoMap hash = new SoMap();
// 将数组转为Object的形式key为数组中的id
for (SoMap json : list) {
hash.put(json.getString(idKey), json);
}
// 遍历结果集
for (SoMap soMap : list) {
// 单条记录
// 在hash中取出key为单条记录中pid的值
SoMap hashVp = (SoMap) hash.get(soMap.get(parentIdKey, "").toString());
// 如果记录的pid存在则说明它有父节点将她添加到孩子节点的集合中
if (hashVp != null) {
// 检查是否有child属性有则添加没有则新建
if (hashVp.get(childListKey) != null) {
@SuppressWarnings("unchecked")
List<SoMap> ch = (List<SoMap>) hashVp.get(childListKey);
ch.add(soMap);
hashVp.put(childListKey, ch);
} else {
List<SoMap> ch = new ArrayList<SoMap>();
ch.add(soMap);
hashVp.put(childListKey, ch);
}
} else {
newTreeList.add(soMap);
}
}
return newTreeList;
}
/**
* 线
*/
private static String wordEachBig(String str) {
StringBuilder newStr = new StringBuilder();
for (String s : str.split("_")) {
newStr.append(wordFirstBig(s));
}
return newStr.toString();
}
/**
* 线
*/
private static String wordEachBigFs(String str) {
return wordFirstSmall(wordEachBig(str));
}
/**
*
*/
private static String wordFirstBig(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
/**
*
*/
private static String wordFirstSmall(String str) {
return str.substring(0, 1).toLowerCase() + str.substring(1);
}
/**
* 线线
*/
private static String wordEachKebabCase(String str) {
return str.replaceAll("_", "-");
}
/**
* 线
*/
private static String wordHumpToLine(String str) {
return str.replaceAll("[A-Z]", "_$0").toLowerCase();
}
}

View File

@ -1,149 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>奇特物联认证授权</title>
<style type="text/css">
body{
min-height: 500px;
background: linear-gradient( 270deg, rgb(46 124 255) 0%, rgb(52 3 65) 100% );
}
.bgimg{
position:absolute;
width:100%;
height:100%;
}
.bgimg::before {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 60%;
overflow: hidden;
height: 80%;
-webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='1200' height='770' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M58.4 47.77C104.6 59.51 135.26 67.37 162.11 78.04C188.97 88.72 226.33 102.69 265.92 123.55C305.51 144.4 366.96 167.09 441.43 121.52C515.9 75.95 546.48 61.01 577.69 46.27C608.9 31.53 625.86 23.69 680.26 12.28C734.65 0.87 837.29 10.7 867.29 21.8C897.29 32.9 935.51 51.9 962.21 95.45C988.9 139.01 972.91 177.36 951.37 221.39C929.83 265.43 883.49 306 890.44 337.33C897.4 368.66 974.73 412.18 974.73 411.47C974.73 412.18 1066.36 457.62 1106.36 491.06C1146.36 524.5 1178.8 563.36 1184.03 579.63C1189.26 595.9 1200.4 622.49 1181.55 676.88C1162.71 731.26 1127.16 764.32 1115.31 778.64C1103.45 792.96 5.34 783.61 4.32 784.63C3.3 785.65 -172.34 2.38 1.13 35.04L58.4 47.77L58.4 47.77Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
background: #2e72f08f;
transition: all .3s ease;
}
.bgimg::after {
content: "";
width: 150px;
height: 300px;
position: absolute;
right: 0;
top: 0;
-webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='150' height='300' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M-0.56 -0.28C41.94 36.17 67.73 18.94 93.33 33.96C118.93 48.98 107.58 73.56 101.94 89.76C96.29 105.96 50.09 217.83 47.87 231.18C45.64 244.52 46.02 255.2 64.4 270.05C82.79 284.91 121.99 292.31 111.98 289.81C101.97 287.32 153.96 301.48 151.83 299.9C149.69 298.32 149.98 -1.36 149.71 -1.18C149.98 -1.36 -43.06 -36.74 -0.56 -0.28L-0.56 -0.28Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
background: #330b4e8c;
transition: all .3s ease;
}
*{margin: 0px; padding: 0px;}
.login-box{
position: absolute;
right: 100px;
width: 400px;
height: 400px;
margin: 20vh auto;
padding: 30px 50px;
background-color: #fff;
overflow: inherit;
border-radius: 10px;
}
.login-box .title{color:#333;font-size:22px;text-align:center;margin:20px 20px}
.login-box button{padding: 5px 15px; cursor: pointer; }
#loginImg{
-webkit-animation:bounce 3s 1s infinite linear normal;
-moz-animation:bounce 3s 1s infinite linear normal;}
@-webkit-keyframes bounce{
40%{-webkit-transform:translateY(-20px)}
60%{-webkit-transform:translateY(-10px)}
}
}
</style>
</head>
<body>
<div class="bgimg">
<div style="position:absolute;top:40px;left:100px;font-size:30px;color:#FFF">©奇特物联</div>
<img id="loginImg" src="http://iotkit-img.oss-cn-shenzhen.aliyuncs.com/product/KdJYpTp5ywNhmrmC/cover.png?Expires=1970997977&OSSAccessKeyId=LTAI5t8UFEH5eGrBUS5zSiof&Signature=0YV5y27iIYYL5XQ2qMeBV%2FloYFU%3D" style="position: absolute;left:100px;bottom: -20px;"/>
</div>
<div class="login-box">
<div class="title">授权确认</div> <br>
<div>
正在确认授权...
</div>
<div id="divFailed"></div>
</div>
<script src="https://unpkg.zhimg.com/jquery@3.4.1/dist/jquery.min.js"></script>
<script>window.jQuery || alert('当前页面CDN服务商已宕机请将所有js包更换为本地依赖')</script>
<script type="text/javascript">
// 同意授权
function yes() {
$.ajax({
url: '/oauth2/doConfirm',
data: {
client_id: getParam('client_id'),
scope: getParam('scope')
},
dataType: 'json',
success: function(res) {
if(res.code == 200) {
location.reload(true);
} else {
// 重定向至授权失败URL
$("#divFailed").text('授权失败!');
}
},
error: function(e) {
console.log('error');
}
});
}
// 拒绝授权
function no() {
var url = joinParam(getParam('redirect_uri'), "handle=refuse&msg=用户拒绝了授权");
location.href = url;
}
// 从url中查询到指定名称的参数值
function getParam(name, defaultValue){
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == name){return pair[1];}
}
return(defaultValue == undefined ? null : defaultValue);
}
// 在url上拼接上kv参数并返回
function joinParam(url, parameStr) {
if(parameStr == null || parameStr.length == 0) {
return url;
}
var index = url.indexOf('?');
// ? 不存在
if(index == -1) {
return url + '?' + parameStr;
}
// ? 是最后一位
if(index == url.length - 1) {
return url + parameStr;
}
// ? 是其中一位
if(index > -1 && index < url.length - 1) {
// 如果最后一位是 不是&, 且 parameStr 第一位不是 &, 就增送一个 &
if(url.lastIndexOf('&') != url.length - 1 && parameStrindexOf('&') != 0) {
return url + '&' + parameStr;
} else {
return url + parameStr;
}
}
}
yes();
</script>
</body>
</html>

View File

@ -1,154 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>奇特物联登录授权</title>
<style type="text/css">
body{
min-height: 500px;
background: linear-gradient( 270deg, rgb(46 124 255) 0%, rgb(52 3 65) 100% );
}
.bgimg{
position:absolute;
width:100%;
height:100%;
}
.bgimg::before {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 60%;
overflow: hidden;
height: 80%;
-webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='1200' height='770' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M58.4 47.77C104.6 59.51 135.26 67.37 162.11 78.04C188.97 88.72 226.33 102.69 265.92 123.55C305.51 144.4 366.96 167.09 441.43 121.52C515.9 75.95 546.48 61.01 577.69 46.27C608.9 31.53 625.86 23.69 680.26 12.28C734.65 0.87 837.29 10.7 867.29 21.8C897.29 32.9 935.51 51.9 962.21 95.45C988.9 139.01 972.91 177.36 951.37 221.39C929.83 265.43 883.49 306 890.44 337.33C897.4 368.66 974.73 412.18 974.73 411.47C974.73 412.18 1066.36 457.62 1106.36 491.06C1146.36 524.5 1178.8 563.36 1184.03 579.63C1189.26 595.9 1200.4 622.49 1181.55 676.88C1162.71 731.26 1127.16 764.32 1115.31 778.64C1103.45 792.96 5.34 783.61 4.32 784.63C3.3 785.65 -172.34 2.38 1.13 35.04L58.4 47.77L58.4 47.77Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
background: #2e72f08f;
transition: all .3s ease;
}
.bgimg::after {
content: "";
width: 150px;
height: 300px;
position: absolute;
right: 0;
top: 0;
-webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='150' height='300' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M-0.56 -0.28C41.94 36.17 67.73 18.94 93.33 33.96C118.93 48.98 107.58 73.56 101.94 89.76C96.29 105.96 50.09 217.83 47.87 231.18C45.64 244.52 46.02 255.2 64.4 270.05C82.79 284.91 121.99 292.31 111.98 289.81C101.97 287.32 153.96 301.48 151.83 299.9C149.69 298.32 149.98 -1.36 149.71 -1.18C149.98 -1.36 -43.06 -36.74 -0.56 -0.28L-0.56 -0.28Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
background: #330b4e8c;
transition: all .3s ease;
}
*{margin: 0px; padding: 0px;}
.login-box{
position: absolute;
right: 100px;
width: 400px;
height: 400px;
margin: 20vh auto;
padding: 30px 50px;
background-color: #fff;
overflow: inherit;
border-radius: 10px;
}
.login-box .title{color:#333;font-size:22px;text-align:center;margin:20px 20px}
.login-box .form{list-style:none; padding:20px 20px;}
.login-box li{
padding:10px 10px;
line-height:30px;
text-align:center;
}
.login-box input{
width:100%;
line-height: 30px;
margin-bottom: 10px;
border-radius: 5px;
border: 1px solid #999;
padding:5px 10px;
}
.login-box button{
padding: 5px 15px;
cursor: pointer;
width: 100%;
line-height:30px;
border: 1px solid #5e77ff;
background-color: #5e77ff;
color: #fff;
border-radius: 5px;
}
.login-box button:hover{
background-color: #2746f1;
}
.login-box .tip{
margin-top:20px;
color:#666;
}
.tip.error{
color:red;
}
#loginImg{
-webkit-animation:bounce 3s 1s infinite linear normal;
-moz-animation:bounce 3s 1s infinite linear normal;}
@-webkit-keyframes bounce{
40%{-webkit-transform:translateY(-20px)}
60%{-webkit-transform:translateY(-10px)}
}
}
</style>
</head>
<body>
<div class="bgimg">
<div style="position:absolute;top:40px;left:100px;font-size:30px;color:#FFF">©奇特物联</div>
<img id="loginImg" src="http://iotkit-img.oss-cn-shenzhen.aliyuncs.com/product/KdJYpTp5ywNhmrmC/cover.png?Expires=1970997977&OSSAccessKeyId=LTAI5t8UFEH5eGrBUS5zSiof&Signature=0YV5y27iIYYL5XQ2qMeBV%2FloYFU%3D" style="position: absolute;left:100px;bottom: -20px;"/>
</div>
<div class="login-box">
<div class="title">登录授权</div>
<ul class="form">
<li>
<input name="name" placeholder="请输入账号"/>
</li>
<li>
<input name="pwd" type="password" placeholder="请输入密码" /> <br>
</li>
<li>
<button onclick="doLogin()">登录</button>
</li>
<li class="tip" id="liTip"></li>
<li style="color:#aaa;">
Copyright © 2021 2022 奇特物联
</li>
</ul>
</div>
<script src="https://unpkg.zhimg.com/jquery@3.4.1/dist/jquery.min.js"></script>
<script>window.jQuery || alert('当前页面CDN服务商已宕机请将所有js包更换为本地依赖')</script>
<script type="text/javascript">
// 登录方法
function doLogin() {
var name=$.trim($('[name=name]').val());
var pwd=$.trim($('[name=pwd]').val());
if(!name || !pwd){
$("#liTip").addClass("error").text("账号或密码不能为空!");
}
$.ajax({
url: '/oauth2/doLogin',
data: {
name: name,
pwd: pwd
},
dataType: 'json',
success: function(res) {
if(res.code == 200) {
$("#liTip").removeClass("error").text("登录成功!");
setTimeout(function() {
location.reload(true);
}, 800);
} else {
$("#liTip").addClass("error").text(res.msg);
}
},
error: function(e) {
console.log('error');
}
});
}
</script>
</body>
</html>

View File

@ -1,13 +0,0 @@
import cc.iotkit.utils.AuthUtil;
import org.junit.Test;
public class GenPwdSecret {
@Test
public void gen() throws Exception {
//生成密码加密内容
String secret = AuthUtil.enCryptPwd("iotkitadmin");
System.out.println(secret);
System.out.println(AuthUtil.checkPwd("guest123", secret));
}
}

View File

@ -0,0 +1,123 @@
<?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-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</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>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</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>cn.hutool</groupId>
<artifactId>hutool-json</artifactId>
<scope>provided</scope>
</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>
</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,90 @@
package cc.iotkit.common.api;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.common.utils.SnowflakeIdGeneratorUtil;
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;
/**
* @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(String.valueOf(SnowflakeIdGeneratorUtil.getInstanceSnowflake().nextId()));
return pageRequest;
}
public static <DTO> PageRequest<DTO> request2PageRequest(Request<DTO> request) {
PageRequest<DTO> pageRequest = new PageRequest<>();
pageRequest.setData(request.getData());
pageRequest.setPageNum(DEFAULT_PAGE_NUM);
pageRequest.setPageSize(DEFAULT_PAGE_SIZE);
pageRequest.setRequestId(request.getRequestId());
return pageRequest;
}
public <DTO> PageRequest<DTO> to(Class<DTO> dtoClass) {
DTO dto = MapstructUtils.convert(getData(), dtoClass);
PageRequest<DTO> pageRequest = new PageRequest<>();
pageRequest.setData(dto);
pageRequest.setPageNum(this.getPageNum());
pageRequest.setPageSize(this.getPageSize());
pageRequest.setRequestId(this.getRequestId());
pageRequest.setSortMap(this.getSortMap());
return pageRequest;
}
}

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

@ -7,8 +7,9 @@
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.model;
package cc.iotkit.common.api;
import cc.iotkit.common.utils.MapstructUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -24,4 +25,7 @@ public class Paging<T> {
private List<T> data;
public <VO> Paging<VO> to(Class<VO> voClass) {
return MapstructUtils.convert(this, voClass);
}
}

View File

@ -0,0 +1,30 @@
package cc.iotkit.common.api;
import cc.iotkit.common.utils.SnowflakeIdGeneratorUtil;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serializable;
import java.util.UUID;
/**
* @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(String.valueOf(SnowflakeIdGeneratorUtil.getInstanceSnowflake().nextId()));
return request;
}
}

View File

@ -0,0 +1,29 @@
package cc.iotkit.common.api;
import cc.iotkit.common.utils.SnowflakeIdGeneratorUtil;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serializable;
import java.util.UUID;
/**
* @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(String.valueOf(SnowflakeIdGeneratorUtil.getInstanceSnowflake().nextId()));
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 int code;
private String message;
private Object data;
private long timestamp;
}

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

@ -1,16 +1,83 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common;
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 TOKEN = "token";
/**
* id
*/
Long TOP_PARENT_ID = 0L;
String PRODUCT_SECRET = "xdkKUymrEGSCYWswqCvSPyRSFvH5j7CU";
String ACCOUNT_SECRET = "3n1z33kzvpgz1foijpkepyd3e8tw84us";
@ -224,3 +291,4 @@ public interface Constants {
String DEVICE_SUBSCRIBE_TOPIC = "^/sys/.+/.+/c/#$";
}
}

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,103 @@
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, "数据不存在"),
/**
*
*/
GET_COMPONENT_INSTANCE_ERROR(00000000, "获取通讯组件实例失败"),
GET_COMPONENT_SCRIPT_ERROR(00000000, "获取通讯组件脚本失败"),
GET_CONVERT_ERROR(00000000, "获取转换器失败"),
GET_SPI_COMPONENT_ERROR(00000000, "获取组件CLASS失败"),
GET_SPI_CONVERT_ERROR(00000000, "获取转换器CLASS失败"),
COMPONENT_NOT_FOUND(00000000, "通讯组件不存在"),
SEND_DESTINATION_NOT_FOUND(00000000, "发送目标不存在"),
MSG_CONVERT_ERROR(00000000, "消息转换失败"),
DEVICE_REGISTER_ERROR(00000000, "设备注册失败"),
COMPONENT_ID_BLANK(00000000, "通讯组件ID为空"),
COMPONENT_JAR_NOT_FOUND(00000000, "通讯组件JAR包为空"),
COMPONENT_ALREADY(00000000, "通讯组件已经存在"),
SAVE_COMPONENT_SCRIPT_ERROR(00000000, "保存通讯组件脚本失败"),
SAVE_CONVERT_SCRIPT_ERROR(00000000, "保存转换器脚本失败"),
ADD_COMPONENT_ERROR(00000000, "添加通讯组件失败"),
ADD_CONVERT_ERROR(00000000, "添加转换器失败"),
CONVERT_NOT_FOUND(00000000, "转换器不存在"),
DELETE_CONVERT_ERROR(00000000, "删除转换器失败"),
DELETE_COMPONENT_ERROR(00000000, "删除通讯组件失败"),
PRODUCT_SECRET_ERROR(00000000, "产品密钥错误"),
COMPONENT_START_ERROR(00000000, "通讯组件启动失败"),
INIT_PRODUCER_ERROR(00000000, "初始化MQ生产者失败"),
SEND_MSG_ERROR(00000000, "发送消息失败"),
/**
*
*/
TASK_NOT_SUPPORT_RENEW(00000000, "任务不支持续订"),
GROUP_ALREADY(00000000, "分组已经存在"),
GROUP_NOT_FOUND(00000000, "分组不存在"),
PRODUCT_NOT_FOUND(00000000, "产品不存在"),
DEVICE_NOT_FOUND(00000000, "设备不存在"),
DEVICE_OFFLINE(00000000, "设备已离线"),
DEVICE_ALREADY(00000000, "设备已存在"),
MODEL_ALREADY(00000000, "型号已存在"),
MODEL_SCRIPT_NOT_FOUND(00000000, "产品型号脚本不存在"),
PRODUCT_MODEL_NOT_FOUND(00000000, "产品型号不存在"),
FILE_NOT_FOUND(00000000, "文件不存在"),
RULE_NOT_FOUND(00000000, "规则不存在"),
RULE_ALREADY_RUNNING(00000000, "规则已运行"),
SEND_REQUEST_ERROR(00000000, "发送请求失败"),
TASK_NOT_FOUND(00000000, "任务不存在"),
RENEW_TASK_ERROR(00000000, "重启任务失败"),
HOME_NOT_FOUND(00000000, "家庭不存在"),
CURRENT_HOME_NOT_FOUND(00000000, "当前家庭不存在"),
SPACE_NOT_FOUND(00000000, "空间不存在"),
SPACE_DEVICE_NOT_FOUND(00000000, "空间设备不存在"),
DATA_BLANK(00000000, "数据为空"),
DATA_LENGTH_ERROR(00000000, "数据长度错误"),
DATA_FORMAT_ERROR(00000000, "数据格式错误"),
USER_NOT_FOUND(00000000, "用户不存在"),
RESET_PWD_ERROR(00000000, "重置密码失败"),
UPDATE_PWD_ERROR(00000000, "修改密码失败"),
PWD_ERROR(00000000, "密码错误"),
STATE_ERROR(00000000, "状态错误"),
RECORD_NOT_FOUND(00000000, "记录不存在"),
ADD_PLATFORM_USER_ERROR(00000000, "添加平台用户失败"),
UPLOAD_FILE_ERROR(00000000, "上传文件失败");
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,37 @@
package cc.iotkit.common.enums;
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"),
/**
* 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 RuntimeException("'UserType' not found By " + str);
}
}

View File

@ -0,0 +1,72 @@
/*
* +----------------------------------------------------------------------
* | 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.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.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,40 @@
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 = 0;
public static final int CODE_WARN = 1;
private int code;
private String message;
private Object data;
public ViewException() {
}
public ViewException(String message) {
super(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,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,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 @@
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,120 @@
package cc.iotkit.common.undefined;
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;
}
}

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 roleId;
/**
*
*/
private String roleName;
/**
*
*/
private String roleKey;
/**
* 12345
*/
private String dataScope;
}

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

@ -7,8 +7,10 @@
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.common;
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;
@ -65,13 +67,13 @@ public class ComponentClassLoader {
public static <T> T getComponent(String name, File jarFile) throws Exception {
String className = addUrl(name, jarFile);
if (StringUtils.isBlank(className)) {
throw new RuntimeException("component class does not exist");
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, File jarFile) throws Exception {
public static <T> T getConverter(String name) throws Exception {
URLClassLoader classLoader = classLoaders.get(name);
InputStream is = classLoader.getResourceAsStream("convert.spi");
if (is == null) {
@ -81,7 +83,7 @@ public class ComponentClassLoader {
//多行只取第1行并处理空格
String[] lines = IOUtils.toString(is, StandardCharsets.UTF_8).split("\\s");
if (lines.length == 0) {
throw new RuntimeException("convert class does not exist");
throw new BizException(ErrCode.GET_SPI_CONVERT_ERROR);
}
String className = lines[0].trim();
Class<T> converterClass = findClass(name, className);

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 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "天" + hour + "小时" + min + "分钟";
}
/**
* 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,109 @@
package cc.iotkit.common.utils;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
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.List;
/**
* 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 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 (ArrayUtil.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 null;
}
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);
}
}
}

View File

@ -0,0 +1,108 @@
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.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(source, "source is null");
Assert.notNull(desc, "desc is 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 null;
}
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.getData())) {
return new Paging<>(0, new ArrayList<>());
}
return new Paging<>(source.getTotal(), CONVERTER.convert(source.getData(), desc));
}
}

View File

@ -0,0 +1,55 @@
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,183 @@
package cc.iotkit.common.utils;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
/**
* @author: Longjun.Tu
* @description:
* @date:created in 2023/5/18 10:20
* @modificed by:
*/
public class SnowflakeIdGeneratorUtil {
/**
*
*/
private final static long START_STMP = 1577808000000L;
/**
*
*/
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
private final static long MACHINE_BIT = 5; //机器标识占用的位数
private final static long DATACENTER_BIT = 5;//数据中心占用的位数
/**
*
*/
private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
/**
*
*/
private final static long MACHINE_LEFT = SEQUENCE_BIT;
private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
private long datacenterId; //数据中心
private long machineId; //机器标识
private long sequence = 0L; //序列号
private long lastStmp = -1L;//上一次时间戳
private static volatile SnowflakeIdGeneratorUtil snowflake = null;
private static Object lock = new Object();
public SnowflakeIdGeneratorUtil(long datacenterId, long machineId) {
if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
}
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
/**
*
*
* @return
*/
public static SnowflakeIdGeneratorUtil getInstanceSnowflake() {
if (snowflake == null) {
synchronized (lock) {
if(snowflake == null){
long workerId;
long dataCenterId = getRandom();
try {
//第一次使用获取mac地址的
workerId = getWorkerId();
} catch (Exception e) {
workerId = getRandom();
}
snowflake = new SnowflakeIdGeneratorUtil(dataCenterId, workerId);
}
}
}
return snowflake;
}
/**
* ID
*
* @return
*/
public synchronized long nextId() {
long currStmp = getNewstmp();
if (currStmp < lastStmp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
if (currStmp == lastStmp) {
//相同毫秒内,序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE;
//同一毫秒的序列数已经达到最大
if (sequence == 0L) {
currStmp = getNextMill();
}
} else {
//不同毫秒内序列号置为0
sequence = 0L;
}
lastStmp = currStmp;
return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
| datacenterId << DATACENTER_LEFT //数据中心部分
| machineId << MACHINE_LEFT //机器标识部分
| sequence; //序列号部分
}
private long getNextMill() {
long mill = getNewstmp();
while (mill <= lastStmp) {
mill = getNewstmp();
}
return mill;
}
private long getNewstmp() {
return System.currentTimeMillis();
}
/**
* 1-31
*
* @return
*/
private static long getRandom() {
int max = (int) (MAX_MACHINE_NUM);
int min = 1;
Random random = new Random();
long result = random.nextInt(max - min) + min;
return result;
}
private static long getWorkerId() throws SocketException, UnknownHostException, NullPointerException {
@SuppressWarnings("unused")
InetAddress ip = InetAddress.getLocalHost();
NetworkInterface network = null;
Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
while (en.hasMoreElements()) {
NetworkInterface nint = en.nextElement();
if (!nint.isLoopback() && nint.getHardwareAddress() != null) {
network = nint;
break;
}
}
if (network == null) {
throw new NullPointerException("network is null");
}
@SuppressWarnings("ConstantConditions")
byte[] mac = network.getHardwareAddress();
long id = ((0x000000FF & (long) mac[mac.length - 1]) | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 11;
if (id > MAX_MACHINE_NUM) {
return getRandom();
}
return id;
}
public static void main(String[] args) {
Set<Long> idList = new HashSet<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
long id = SnowflakeIdGeneratorUtil.getInstanceSnowflake().nextId();
idList.add(id);
// System.out.println("id="+id);
}
// System.out.println(idList.size());
// System.out.println(System.currentTimeMillis() - start);
}
}

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 @@
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.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 null;
}
K k = ReflectUtils.invokeGetter(list.get(0), "parentId");
return TreeUtil.build(list, k, DEFAULT_CONFIG, nodeParser);
}
}

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

@ -7,12 +7,11 @@
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.manager.utils;
package cc.iotkit.common.utils;
import cn.hutool.core.codec.Base64;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
@ -26,6 +25,7 @@ import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.Security;
import java.util.Arrays;
/**
*

View File

@ -0,0 +1,20 @@
package cc.iotkit.common.utils.file;
import cn.hutool.core.io.FileUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
*
*
* @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 {
}

View File

@ -3,14 +3,14 @@
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-data</artifactId>
<artifactId>iot-common-dao</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.4.3-SNAPSHOT</version>
<version>${revision}</version>
</parent>
<version>0.4.3-SNAPSHOT</version>
<version>${revision}</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-model</artifactId>
<artifactId>iot-common-model</artifactId>
<dependencies>
@ -27,8 +27,22 @@
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common</artifactId>
<artifactId>iot-common-core</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,47 @@
package cc.iotkit.model;
import cc.iotkit.common.utils.MapstructUtils;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* Entity
*
* @author Lion Li
*/
@Data
public class BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
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,20 @@
package cc.iotkit.model;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
*
* @author Michelle.Chung
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class TenantModel extends BaseModel {
/**
*
*/
private String tenantId;
}

View File

@ -23,8 +23,6 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
public class AlertConfig implements Owned<String> {
public static final String TYPE_EMAIL="email";
public static final String TYPE_DINGDING_ROBOT="dingding_robot";
private String id;
@ -34,30 +32,38 @@ public class AlertConfig implements Owned<String> {
private String uid;
/**
*
*
*/
private String type;
private String name;
/**
*
*
*/
private String title;
private String level;
/**
*
* ID
*/
private String config;
private String ruleInfoId;
/**
*
* ID
*/
private String template;
private String messageTemplateId;
/**
*
*/
private String description;
/**
*
*/
private boolean enable;
private Boolean enable;
/**
*
*/
private Long createAt;
}

View File

@ -0,0 +1,61 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.model.alert;
import cc.iotkit.model.Owned;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AlertRecord implements Owned<String> {
private String id;
/**
*
*/
private String uid;
/**
*
*/
private String name;
/**
* 1-5
*/
private String level;
/**
*
*/
private Long alertTime;
/**
*
*/
private String details;
/**
*
*/
private Boolean read;
}

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