1.新建openapi模块,并添加了获取token和获取设备详情接口(未测试)

2.添加设备时新增判断,同产品下不可重复deviceName
V0.5.x
dsy 2023-07-25 11:54:04 +08:00
parent 01a1894f14
commit ff0685994d
14 changed files with 467 additions and 1 deletions

View File

@ -19,6 +19,13 @@ public enum ErrCode implements IEnum {
UNSUPPORTED_OPERATION_EXCEPTION(10000009, "方法未实现"), UNSUPPORTED_OPERATION_EXCEPTION(10000009, "方法未实现"),
DATA_NOT_EXIST(10000010, "数据不存在"), DATA_NOT_EXIST(10000010, "数据不存在"),
/**
* openapi
*/
IDENTIFIER_ERROR(00000000, "签名验证失败"),
API_LOGIN_ERROR(00000000, "登录验证失败"),
/** /**
* *
*/ */
@ -70,6 +77,7 @@ public enum ErrCode implements IEnum {
DEVICE_NOT_FOUND(00000000, "设备不存在"), DEVICE_NOT_FOUND(00000000, "设备不存在"),
DEVICE_OFFLINE(00000000, "设备已离线"), DEVICE_OFFLINE(00000000, "设备已离线"),
DEVICE_ALREADY(00000000, "设备已存在"), DEVICE_ALREADY(00000000, "设备已存在"),
MODEL_DEVICE_ALREADY(00000000, "设备DN已存在"),
DEVICE_HAS_ASSOCIATED(00000000, "设备已关联"), DEVICE_HAS_ASSOCIATED(00000000, "设备已关联"),
MODEL_ALREADY(00000000, "型号已存在"), MODEL_ALREADY(00000000, "型号已存在"),
@ -99,6 +107,7 @@ public enum ErrCode implements IEnum {
FILE_NAME_IS_NULL(00000000, "文件名为空,获取文件名失败"); FILE_NAME_IS_NULL(00000000, "文件名为空,获取文件名失败");
private int code; private int code;
private String message; private String message;

View File

@ -20,6 +20,11 @@ public enum UserType {
*/ */
SYS_USER("sys_user"), SYS_USER("sys_user"),
/**
* api
*/
API_USER("api_user"),
/** /**
* app * app
*/ */

View File

@ -120,7 +120,11 @@ public class DeviceServiceImpl implements IDeviceService {
if (product == null) { if (product == null) {
throw new BizException(ErrCode.PRODUCT_NOT_FOUND); throw new BizException(ErrCode.PRODUCT_NOT_FOUND);
} }
//同产品不可重复设备名
DeviceInfo deviceRepetition = deviceInfoData.findByProductKeyAndDeviceName(productKey, deviceName);
if (deviceRepetition != null) {
throw new BizException(ErrCode.MODEL_DEVICE_ALREADY);
}
//生成设备密钥 //生成设备密钥
String chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"; String chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
int maxPos = chars.length(); int maxPos = chars.length();

View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>iot-module</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.4.5-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-openapi</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>embedded-redis</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-simple</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-model</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-core</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-rule-engine</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-screen</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-component-server</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-component-converter</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-virtual-device</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-message-core</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-oss</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-temporal-service</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-data-serviceImpl-rdb</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-data-serviceImpl-cache</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-web</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-doc</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-satoken</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-excel</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-log</artifactId>
</dependency>
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-system</artifactId>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>

View File

@ -0,0 +1,34 @@
package cc.iotkit.openapi.controller;
import cc.iotkit.common.api.Request;
import cc.iotkit.model.InvokeResult;
import cc.iotkit.openapi.dto.bo.TokenVerifyBo;
import cc.iotkit.openapi.service.OpenBaseService;
import cc.iotkit.openapi.service.OpenDeviceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = {"openapi-基础"})
@Slf4j
@RestController
@RequestMapping("/openapi")
public class OpenBaseController {
@Autowired
private OpenBaseService openBaseService;
@ApiOperation(value = "token获取", notes = "token获取", httpMethod = "POST")
@PostMapping("/v1/getToken")
public InvokeResult OpenApiGetToken(@RequestBody @Validated Request<TokenVerifyBo> request) {
return new InvokeResult(openBaseService.getToken(request.getData()));
}
}

View File

@ -0,0 +1,36 @@
package cc.iotkit.openapi.controller;
import cc.iotkit.common.api.Request;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.openapi.dto.bo.device.OpenapiDeviceBo;
import cc.iotkit.openapi.service.OpenBaseService;
import cc.iotkit.openapi.service.OpenDeviceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = {"openapi-设备"})
@Slf4j
@RestController
@RequestMapping("/openapi/v1/device")
public class OpenDeviceController {
@Autowired
private OpenBaseService openBaseService;
@Autowired
private OpenDeviceService openDeviceService;
@ApiOperation("获取设备详情")
@PostMapping("/detail")
public DeviceInfo getDetail(@RequestBody @Validated Request<OpenapiDeviceBo> request) {
return openDeviceService.getDetail(request.getData());
}
}

View File

@ -0,0 +1,30 @@
package cc.iotkit.openapi.dto.bo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@ApiModel(value = "DeviceConsumerBo")
@Data
public class TokenVerifyBo {
private static final long serialVersionUID = -1L;
@NotBlank(message = "appid不能为空")
@ApiModelProperty(value = "appid")
private String appid;
@NotBlank(message = "timeStamp不能为空")
@ApiModelProperty(value = "时间戳")
private String timeStamp;
@NotBlank(message = "identifier不能为空")
@ApiModelProperty(value = "标识符")
private String identifier;
@NotBlank(message = "{tenant.number.not.blank}")
@ApiModelProperty(value = "租户ID")
private String tenantId;
}

View File

@ -0,0 +1,20 @@
package cc.iotkit.openapi.dto.bo.device;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@ApiModel(value = "OpenapiDeviceBo")
@Data
public class OpenapiDeviceBo {
private static final long serialVersionUID = -1L;
@NotBlank(message = "deviceName不能为空")
@ApiModelProperty(value = "产品名称")
private String deviceName;
@NotBlank(message = "productKey不能为空")
@ApiModelProperty(value = "产品key")
private String productKey;
}

View File

@ -0,0 +1,14 @@
package cc.iotkit.openapi.service;
import cc.iotkit.openapi.dto.bo.TokenVerifyBo;
/**
* @Author: dsy
* @Date: 2023/7/24 11:30
* @Version: V1.0
* @Description: openapi
*/
public interface OpenBaseService {
String getToken(TokenVerifyBo bo);
}

View File

@ -0,0 +1,14 @@
package cc.iotkit.openapi.service;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.openapi.dto.bo.device.OpenapiDeviceBo;
/**
* @Author: dsy
* @Date: 2023/7/24 11:05
* @Version: V1.0
* @Description: openapi
*/
public interface OpenDeviceService {
DeviceInfo getDetail(OpenapiDeviceBo bo);
}

View File

@ -0,0 +1,125 @@
package cc.iotkit.openapi.service.impl;
import cc.iotkit.common.constant.Constants;
import cc.iotkit.common.enums.DeviceType;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.enums.LoginType;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.log.event.LogininforEvent;
import cc.iotkit.common.satoken.utils.LoginHelper;
import cc.iotkit.common.undefined.LoginUser;
import cc.iotkit.common.undefined.RoleDTO;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.common.utils.DateUtils;
import cc.iotkit.common.utils.MessageUtils;
import cc.iotkit.common.utils.SpringUtils;
import cc.iotkit.common.web.utils.ServletUtils;
import cc.iotkit.data.system.ISysUserData;
import cc.iotkit.model.system.SysUser;
import cc.iotkit.openapi.dto.bo.TokenVerifyBo;
import cc.iotkit.openapi.service.OpenBaseService;
import cc.iotkit.system.service.ISysPermissionService;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class OpenBaseServiceImpl implements OpenBaseService {
@Value("${openapi.appid}")
private String appid;
@Value("${openapi.password}")
private String password;
@Autowired
private ISysUserData userData;
@Autowired
private ISysPermissionService permissionService;
@Override
public String getToken(TokenVerifyBo bo) {
String boAppid = bo.getAppid();
String boIdentifier = bo.getIdentifier();
String boTimeStamp = bo.getTimeStamp();
// 校验租户
checkTenant(bo.getTenantId());
if (!CodecUtil.md5Str(boAppid + password + boTimeStamp).equals(boIdentifier)){
throw new BizException(ErrCode.IDENTIFIER_ERROR);
}
if (!boAppid.equals(appid)){
throw new BizException(ErrCode.API_LOGIN_ERROR);
}
SysUser sysUser = userData.selectUserByUserName(appid);
if (sysUser == null){
//用户不存在是否新建?
}
LoginUser loginUser = buildLoginUser(sysUser);
// 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
recordLoginInfo(loginUser.getTenantId(), bo.getAppid(), Constants.LOGIN_SUCCESS, MessageUtils.message("openapi.login.success"));
recordLoginInfo(sysUser.getId());
return StpUtil.getTokenValue();
}
private void checkTenant(String tenantId) {
}
/**
*
*/
private LoginUser buildLoginUser(SysUser user) {
LoginUser loginUser = new LoginUser();
loginUser.setTenantId(user.getTenantId());
loginUser.setUserId(user.getId());
loginUser.setDeptId(user.getDeptId());
loginUser.setUsername(user.getUserName());
loginUser.setUserType(user.getUserType());
loginUser.setMenuPermission(permissionService.getMenuPermission(user.getId()));
loginUser.setRolePermission(permissionService.getRolePermission(user.getId()));
loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName());
List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class);
loginUser.setRoles(roles);
return loginUser;
}
/**
*
*
* @param tenantId ID
* @param username
* @param status
* @param message
*/
private void recordLoginInfo(String tenantId, String username, String status, String message) {
LogininforEvent logininforEvent = new LogininforEvent();
logininforEvent.setTenantId(tenantId);
logininforEvent.setUsername(username);
logininforEvent.setStatus(status);
logininforEvent.setMessage(message);
logininforEvent.setRequest(ServletUtils.getRequest());
SpringUtils.context().publishEvent(logininforEvent);
}
/**
*
*
* @param userId ID
*/
public void recordLoginInfo(Long userId) {
SysUser sysUser = userData.findById(userId);
sysUser.setLoginIp(ServletUtils.getClientIP());
sysUser.setLoginDate(DateUtils.getNowDate());
sysUser.setUpdateBy(userId);
userData.save(sysUser);
}
}

View File

@ -0,0 +1,24 @@
package cc.iotkit.openapi.service.impl;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.openapi.dto.bo.device.OpenapiDeviceBo;
import cc.iotkit.openapi.service.OpenDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class OpenDeviceServiceImpl implements OpenDeviceService {
@Autowired
@Qualifier("deviceInfoDataCache")
private IDeviceInfoData deviceInfoData;
@Override
public DeviceInfo getDetail(OpenapiDeviceBo data) {
DeviceInfo deviceInfo = deviceInfoData.findByProductKeyAndDeviceName(data.getProductKey(), data.getDeviceName());
deviceInfo.setProperty(deviceInfoData.getProperties(deviceInfo.getDeviceId()));
return deviceInfo;
}
}

View File

@ -20,6 +20,7 @@
<module>iot-generator</module> <module>iot-generator</module>
<module>iot-screen</module> <module>iot-screen</module>
<module>iot-contribution</module> <module>iot-contribution</module>
<module>iot-openapi</module>
</modules> </modules>

View File

@ -184,6 +184,12 @@ user:
# 密码锁定时间默认10分钟 # 密码锁定时间默认10分钟
lockTime: 10 lockTime: 10
# openapi配置
openapi:
appid: 123456789
password: 123456
oss: oss:
region: xxxxx region: xxxxx
endpoint: xxxxx endpoint: xxxxx