From 8c41ecd9a6b2f299fb4bc4c4e6ce3cc5bf26e4a2 Mon Sep 17 00:00:00 2001
From: xuhy <3313886187@qq.com>
Date: 星期二, 20 八月 2024 19:12:09 +0800
Subject: [PATCH] 产品管理,设备管理,文件上传

---
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/api/IotInterfaceUtil.java        |  261 +++++++++++++++++++++
 ruoyi-service/ruoyi-integration/pom.xml                                                                          |   20 +
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/constant/IotConstant.java              |   25 ++
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/builder/IotBuilder.java                |   57 ++++
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/config/IotAccountConfig.java           |   27 ++
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/FileController.java             |  142 +++++++++++
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/produce/IotMessageProduce.java   |   13 +
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserAddressController.java            |   12 +
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/config/IotDAConfig.java                |   35 ++
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/config/FileUploadConfig.java               |   21 +
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/token/IotTokenUtil.java          |   72 ++++++
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java |   13 +
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/time/UtcToSeconds.java           |   19 +
 13 files changed, 716 insertions(+), 1 deletions(-)

diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserAddressController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserAddressController.java
index 6b4046f..8969c5b 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserAddressController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserAddressController.java
@@ -45,6 +45,18 @@
         return AjaxResult.ok(appUserAddressService.list(Wrappers.<TAppUserAddress>lambdaQuery().eq(TAppUserAddress::getAppUserId, userId)));
     }
 
+    /**
+     * 查询用户默认地址列表
+     */
+    @ApiOperation(tags = {"小程序-用户地址"},value = "查询用户默认地址列表")
+    @GetMapping(value = "/queryDefaultAddress")
+    public AjaxResult<TAppUserAddress> queryDefaultAddress() {
+        // 用户id
+        Long userId = tokenService.getLoginUserApplet().getUserId();
+        return AjaxResult.ok(appUserAddressService.getOne(Wrappers.<TAppUserAddress>lambdaQuery().eq(TAppUserAddress::getAppUserId, userId)
+                .eq(TAppUserAddress::getDefaultAddress,1)));
+    }
+
 
     /**
      * 添加用户地址管理
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/config/FileUploadConfig.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/config/FileUploadConfig.java
new file mode 100644
index 0000000..5d9cd57
--- /dev/null
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/config/FileUploadConfig.java
@@ -0,0 +1,21 @@
+package com.ruoyi.chargingPile.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * <p>文件上传配置</p>
+ *
+ * @author mouseyCat
+ * @date 2020/10/13 16:10
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "file.upload")
+public class FileUploadConfig {
+    private String accessPath;
+    private String allowExt;
+    private String location;
+    private String qrLocation;
+}
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/FileController.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/FileController.java
new file mode 100644
index 0000000..bd3dd68
--- /dev/null
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/FileController.java
@@ -0,0 +1,142 @@
+package com.ruoyi.chargingPile.controller;
+
+import com.ruoyi.chargingPile.config.FileUploadConfig;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 文件上传控制类
+ *
+ * @author junelee
+ * @date 2020/3/20 20:21
+ */
+@Api(tags = "服务器文件上传")
+@RestController
+@CrossOrigin
+@RequestMapping("/file/")
+public class FileController {
+
+    @Autowired
+    private FileUploadConfig fileUploadConfig;
+
+
+
+    @ApiOperation(value = "单文件上传", notes = "单文件上传,rename 默认不重命名")
+    @PostMapping(value = "upload", headers = "content-type=multipart/form-data")
+    public AjaxResult uploadImageMany(@RequestParam(value = "file") MultipartFile mf) throws IOException {
+        if (mf.isEmpty()) {
+            return AjaxResult.error("请传入文件!");
+        }
+        String TimeDir =new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+        String realPath = fileUploadConfig.getLocation() + TimeDir;
+//        String realPath = "D:\\file\\" + TimeDir;
+        File file = new File(realPath);
+        // 没有目录就创建
+        if (!file.exists()) {
+            file.mkdirs();
+        }
+        // 获取文件名称
+        String filename = mf.getOriginalFilename();
+        // 获取文件后缀
+        String ext = filename.substring(filename.lastIndexOf("."), filename.length());
+        // 检查文件类型
+        if (!fileUploadConfig.getAllowExt().contains(ext)) {
+            return AjaxResult.error("上传文件格式不正确,仅支持" + fileUploadConfig.getAllowExt());
+        }
+        File targetFile = new File(realPath, filename);//目标文件
+        //开始从源文件拷贝到目标文件
+        //传图片一步到位
+        mf.transferTo(targetFile);
+        //拼接数据
+        String imgstr = fileUploadConfig.getAccessPath() + TimeDir +"/"+ filename;
+//        String imgstr = TimeDir +"/"+ filename;
+        return AjaxResult.success(imgstr);
+    }
+
+
+//    @ApiOperation(value = "单文件上传", notes = "单文件上传,rename 默认不重命名")
+//    @PostMapping(value = "strUpload", headers = "content-type=multipart/form-data")
+//    public String strUpload(@RequestParam(value = "file") MultipartFile mf,@RequestParam(value = "fileName")String fileName) throws IOException {
+//        if (mf.isEmpty()) {
+//            return "请传入文件!";
+//        }
+//        String TimeDir =new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+//        String realPath = fileUploadConfig.getQrLocation() + TimeDir;
+//        File file = new File(realPath);
+//        // 没有目录就创建
+//        if (!file.exists()) {
+//            file.mkdirs();
+//        }
+//        File targetFile = new File(realPath, fileName);//目标文件
+//        //开始从源文件拷贝到目标文件
+//        //传图片一步到位
+//        mf.transferTo(targetFile);
+//        //拼接数据
+//        return fileUploadConfig.getQrLocation() + TimeDir +"\\"+ fileName;
+//    }
+
+    @ApiOperation(value = "单文件上传", notes = "单文件上传,rename 默认不重命名")
+    @PostMapping(value = "strUpload", headers = "content-type=multipart/form-data")
+    public String strUpload(@RequestParam(value = "file") MultipartFile mf,@RequestParam(value = "fileName")String fileName) throws IOException {
+        if (mf.isEmpty()) {
+            return "请传入文件!";
+        }
+        String TimeDir =new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+//        String realPath = "D:\\file\\" + TimeDir;
+        String realPath = fileUploadConfig.getLocation() + TimeDir;
+        File file = new File(realPath);
+        // 没有目录就创建
+        if (!file.exists()) {
+            file.mkdirs();
+        }
+        File targetFile = new File(realPath, fileName);//目标文件
+        //开始从源文件拷贝到目标文件
+        //传图片一步到位
+        mf.transferTo(targetFile);
+        String imgstr = fileUploadConfig.getAccessPath() + TimeDir +"/"+ fileName;
+        //拼接数据
+//        return TimeDir +"/"+ fileName;
+        return imgstr;
+    }
+
+    @ApiOperation(value = "单文件上传(覆盖服务器原文件)", notes = "单文件上传,rename 默认不重命名")
+    @PostMapping(value = "test/upload", headers = "content-type=multipart/form-data")
+    public AjaxResult uploadTest(@RequestParam(value = "file") MultipartFile mf) throws IOException {
+        if (mf.isEmpty()) {
+            return AjaxResult.error("请传入文件!");
+        }
+        String TimeDir = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+        String realPath = fileUploadConfig.getLocation() + "2021-11-17";
+        File file = new File(realPath);
+        // 没有目录就创建
+        if (!file.exists()) {
+            file.mkdirs();
+        }
+        // 判断文件大小
+        String filename = "6u2mGlqHkeE75e2ab51b4a03c6982ff7d68f4c024d43.jpg";
+        // 获取文件后缀
+        String ext = filename.substring(filename.lastIndexOf("."), filename.length());
+        // 检查文件类型
+        if (!fileUploadConfig.getAllowExt().contains(ext)) {
+            return AjaxResult.error("上传文件格式不正确,仅支持" + fileUploadConfig.getAllowExt());
+        }
+        File targetFile = new File(realPath, filename);//目标文件
+        //开始从源文件拷贝到目标文件
+        //传图片一步到位
+        mf.transferTo(targetFile);
+        //拼接数据
+        String imgstr = fileUploadConfig.getAccessPath() + "2021-11-17" + "/" + filename;
+        return AjaxResult.success(imgstr);
+    }
+
+
+}
diff --git a/ruoyi-service/ruoyi-integration/pom.xml b/ruoyi-service/ruoyi-integration/pom.xml
index 1971df9..5a824fc 100644
--- a/ruoyi-service/ruoyi-integration/pom.xml
+++ b/ruoyi-service/ruoyi-integration/pom.xml
@@ -127,12 +127,30 @@
             <version>4.7.1</version>
         </dependency>
 
-        <!--spirngboot集成mongodb-->
+        <!--mongodb-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-mongodb</artifactId>
         </dependency>
 
+        <!--华为云-->
+        <dependency>
+            <groupId>com.huaweicloud.sdk</groupId>
+            <artifactId>huaweicloud-sdk-core</artifactId>
+            <version>[3.0.40-rc, 3.2.0)</version>
+        </dependency>
+        <dependency>
+            <groupId>com.huaweicloud.sdk</groupId>
+            <artifactId>huaweicloud-sdk-iotda</artifactId>
+            <version>[3.0.40-rc, 3.2.0)</version>
+        </dependency>
+        <dependency>
+            <groupId>com.huaweicloud.sdk</groupId>
+            <artifactId>huaweicloud-sdk-bundle</artifactId>
+            <version>3.1.87</version>
+        </dependency>
+
+
     </dependencies>
 
     <build>
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/builder/IotBuilder.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/builder/IotBuilder.java
new file mode 100644
index 0000000..d11cc16
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/builder/IotBuilder.java
@@ -0,0 +1,57 @@
+package com.ruoyi.integration.iotda.builder;
+
+import com.huaweicloud.sdk.core.auth.AbstractCredentials;
+import com.huaweicloud.sdk.core.auth.BasicCredentials;
+import com.huaweicloud.sdk.core.auth.ICredential;
+import com.huaweicloud.sdk.core.region.Region;
+import com.huaweicloud.sdk.iam.v3.IamClient;
+import com.huaweicloud.sdk.iam.v3.region.IamRegion;
+import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
+import com.ruoyi.integration.iotda.config.IotDAConfig;
+import com.ruoyi.integration.iotda.constant.IotConstant;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class IotBuilder {
+
+    @Autowired
+    private IotDAConfig config;
+
+    /**
+     * iot build
+     *
+     * @return
+     */
+    public IoTDAClient buildIot() {
+        ICredential auth = new BasicCredentials()
+                // 标准版/企业版需要使用衍生算法,基础版请删除配置"withDerivedPredicate";
+                .withDerivedPredicate(AbstractCredentials.DEFAULT_DERIVED_PREDICATE) // Used in derivative ak/sk authentication scenarios
+                .withAk(config.getAk())
+                .withSk(config.getSk());
+        return IoTDAClient.newBuilder()
+                .withCredential(auth)
+                // 标准版/企业版:需自行创建Region对象,基础版:请使用IoTDARegion的region对象,如"withRegion(IoTDARegion.CN_NORTH_4)"
+                .withRegion(new Region("cn-north-4", IotConstant.URL))
+                .build();
+    }
+    /**
+     * iam build
+     *
+     * @return
+     */
+    public IamClient buildIam() {
+        ICredential auth = new BasicCredentials()
+                // 标准版/企业版需要使用衍生算法,基础版请删除配置"withDerivedPredicate";
+                .withDerivedPredicate(AbstractCredentials.DEFAULT_DERIVED_PREDICATE) // Used in derivative ak/sk authentication scenarios
+                .withAk(config.getAk())
+                .withSk(config.getSk());
+        return IamClient.newBuilder()
+                .withCredential(auth)
+                .withRegion(IamRegion.valueOf("cn-north-4"))
+                .build();
+    }
+
+}
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/config/IotAccountConfig.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/config/IotAccountConfig.java
new file mode 100644
index 0000000..8b34ca1
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/config/IotAccountConfig.java
@@ -0,0 +1,27 @@
+package com.ruoyi.integration.iotda.config;
+
+import lombok.Data;
+import lombok.ToString;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@ToString
+@Component
+@ConfigurationProperties(prefix = "iot.account.conf")
+public class IotAccountConfig {
+
+    /**
+     * hostAccount配置
+     */
+    private String hostAccount;
+    /**
+     * iamAccount配置
+     */
+    private String iamAccount;
+    /**
+     * iamPassword配置
+     */
+    private String iamPassword;
+
+}
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/config/IotDAConfig.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/config/IotDAConfig.java
new file mode 100644
index 0000000..01a297d
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/config/IotDAConfig.java
@@ -0,0 +1,35 @@
+package com.ruoyi.integration.iotda.config;
+
+import lombok.Data;
+import lombok.ToString;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@ToString
+@Component
+@ConfigurationProperties(prefix = "iot.conf")
+public class IotDAConfig {
+
+    /**
+     * ak配置
+     */
+    private String ak;
+    /**
+     * sk配置
+     */
+    private String sk;
+    /**
+     * endpoint配置  938d8d39e2.iotda.cn-north-4.myhuaweicloud.com
+     */
+    private String endpoint;
+    /**
+     * project_id配置  	0cc59978c61e4b4da24e8c3d02937b45
+     */
+    private String projectId;
+    /**
+     * Instance-Id配置  	c60f266a-57a2-460c-a24e-eabda84602eb
+     */
+    private String instanceId;
+
+}
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/constant/IotConstant.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/constant/IotConstant.java
new file mode 100644
index 0000000..b84b38b
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/constant/IotConstant.java
@@ -0,0 +1,25 @@
+package com.ruoyi.integration.iotda.constant;
+
+public class IotConstant {
+    /**
+     * 华为云iot  token
+     */
+    public static final String IOT_TOKEN = "iot_token";
+    /**
+     * 模式
+     */
+    public static final String PASSWORD = "password";
+    /**
+     * URL
+     */
+    public static final String URL = "https://iotda.cn-north-4.myhuaweicloud.com";
+    /**
+     * 创建产品
+     */
+    public static final String CREATE_PRODUCT = URL+"/v5/iot/{project_id}/products";
+    /**
+     * 创建产品
+     */
+    public static final String DELETE_PRODUCT = URL+"/v5/iot/{project_id}/products/{product_id}";
+
+}
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/api/IotInterfaceUtil.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/api/IotInterfaceUtil.java
new file mode 100644
index 0000000..2528cc6
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/api/IotInterfaceUtil.java
@@ -0,0 +1,261 @@
+package com.ruoyi.integration.iotda.utils.api;
+
+import com.huaweicloud.sdk.core.auth.AbstractCredentials;
+import com.huaweicloud.sdk.core.auth.ICredential;
+import com.huaweicloud.sdk.core.exception.ConnectionException;
+import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
+import com.huaweicloud.sdk.core.exception.ServiceResponseException;
+import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
+import com.huaweicloud.sdk.iotda.v5.model.*;
+import com.ruoyi.common.core.utils.CodeGenerateUtils;
+import com.ruoyi.common.core.utils.uuid.UUID;
+import com.ruoyi.integration.iotda.builder.IotBuilder;
+import com.ruoyi.integration.iotda.config.IotAccountConfig;
+import com.ruoyi.integration.iotda.config.IotDAConfig;
+import com.ruoyi.integration.iotda.constant.IotConstant;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * iot接口调用工具类
+ */
+@Slf4j
+@Component
+public class IotInterfaceUtil {
+
+    private static final String dataFormat = "json";
+    private static final String protocolType = "HTTPS";
+    private static final String deviceType = "充电桩";
+    private static final String serviceType = "直流充电";
+
+    @Autowired
+    private IotBuilder iotBuilder;
+    @Autowired
+    private IotDAConfig iotDAConfig;
+
+    private String decodeUrl(String url) {
+        return MessageFormat.format(url, iotDAConfig.getProjectId());
+    }
+
+    public static void main(String[] args) {
+
+    }
+
+    /**
+     * 创建产品
+     * @param productId 产品ID,使用UUID.randomUUID().toString()生成 需替换特殊字符 "-" 为空
+     * @param productName 产品名称
+     * @return CreateProductResponse
+     */
+    public CreateProductResponse createProductSolution(String productId,String productName) {
+        CreateProductRequest request = new CreateProductRequest();
+        AddProduct body = new AddProduct();
+        List<ServiceCapability> listbodyServiceCapabilities = new ArrayList<>();
+        listbodyServiceCapabilities.add(
+                new ServiceCapability()
+                        .withServiceId(CodeGenerateUtils.generateVolumeSn())
+                        .withServiceType(serviceType)
+        );
+        body.withServiceCapabilities(listbodyServiceCapabilities);
+        body.withDataFormat(dataFormat);
+        body.withProtocolType(protocolType);
+        body.withDeviceType(deviceType);
+        body.withName(productName);
+        body.withProductId(productId);
+        request.withBody(body);
+        request.withInstanceId(iotDAConfig.getInstanceId());
+        try {
+            CreateProductResponse response = iotBuilder.buildIot().createProduct(request);
+            log.info("创建产品:{}",response.toString());
+            return response;
+        } catch (ConnectionException | RequestTimeoutException e) {
+            e.printStackTrace();
+        } catch (ServiceResponseException e) {
+            e.printStackTrace();
+            log.info(String.valueOf(e.getHttpStatusCode()));
+            log.info(e.getRequestId());
+            log.info(e.getErrorCode());
+            log.info(e.getErrorMsg());
+        }
+        return null;
+    }
+
+
+    /**
+     * 删除产品
+     * @param productId 产品ID,使用UUID.randomUUID().toString()生成 需替换特殊字符 "-" 为空
+     * @return DeleteProductResponse
+     */
+    public DeleteProductResponse deleteProductRequest(String productId) {
+        DeleteProductRequest request = new DeleteProductRequest();
+        request.withProductId(productId);
+        request.withInstanceId(iotDAConfig.getInstanceId());
+        try {
+            DeleteProductResponse response = iotBuilder.buildIot().deleteProduct(request);
+            log.info("删除产品:{}",response.toString());
+            return response;
+        } catch (ConnectionException e) {
+            e.printStackTrace();
+        } catch (RequestTimeoutException e) {
+            e.printStackTrace();
+        } catch (ServiceResponseException e) {
+            e.printStackTrace();
+            System.out.println(e.getHttpStatusCode());
+            System.out.println(e.getRequestId());
+            System.out.println(e.getErrorCode());
+            System.out.println(e.getErrorMsg());
+        }
+        return null;
+    }
+
+    /**
+     * 创建设备
+     * @param productId 产品ID
+     * @param nodeId 设备标识码  通常使用IMEI、MAC地址或Serial No作为node_id
+     * @param deviceId 设备ID 使用CodeGenerateUtils.generateVolumeSn()
+     * @param deviceName 设备名称
+     * @param description 设备描述
+     * @return AddDeviceResponse
+     */
+    public AddDeviceResponse addDeviceRequest(String productId,String nodeId,String deviceId,String deviceName,String description) {
+        AddDeviceRequest request = new AddDeviceRequest();
+        AddDevice body = new AddDevice();
+        body.withDeviceId(deviceId);
+        body.withNodeId(nodeId);
+        body.withDeviceName(deviceName);
+        body.withProductId(productId);
+        body.withDescription(description);
+        request.withBody(body);
+        try {
+            AddDeviceResponse response = iotBuilder.buildIot().addDevice(request);
+            log.info("创建设备:{}",response.toString());
+            return response;
+        } catch (ConnectionException e) {
+            e.printStackTrace();
+        } catch (RequestTimeoutException e) {
+            e.printStackTrace();
+        } catch (ServiceResponseException e) {
+            e.printStackTrace();
+            System.out.println(e.getHttpStatusCode());
+            System.out.println(e.getRequestId());
+            System.out.println(e.getErrorCode());
+            System.out.println(e.getErrorMsg());
+        }
+        return null;
+    }
+
+    /**
+     * 修改设备
+     * @param deviceId 设备ID 使用已有设备编号
+     * @param deviceName 设备名称
+     * @param description 设备描述
+     * @return UpdateDeviceResponse
+     */
+    public UpdateDeviceResponse updateDeviceRequest(String deviceId,String deviceName,String description) {
+        UpdateDeviceRequest request = new UpdateDeviceRequest();
+        request.withDeviceId(deviceId);
+        UpdateDevice body = new UpdateDevice();
+        body.withDescription(description);
+        body.withDeviceName(deviceName);
+        request.withBody(body);
+        try {
+            UpdateDeviceResponse response = iotBuilder.buildIot().updateDevice(request);
+            log.info("修改设备:{}",response.toString());
+            return response;
+        } catch (ConnectionException e) {
+            e.printStackTrace();
+        } catch (RequestTimeoutException e) {
+            e.printStackTrace();
+        } catch (ServiceResponseException e) {
+            e.printStackTrace();
+            System.out.println(e.getHttpStatusCode());
+            System.out.println(e.getRequestId());
+            System.out.println(e.getErrorCode());
+            System.out.println(e.getErrorMsg());
+        }
+        return null;
+    }
+
+    /**
+     * 冻结设备
+     * @param deviceId 设备ID 使用已有设备编号
+     * @return FreezeDeviceResponse
+     */
+    public FreezeDeviceResponse freezeDeviceRequest(String deviceId) {
+        FreezeDeviceRequest request = new FreezeDeviceRequest();
+        request.withDeviceId(deviceId);
+        try {
+            FreezeDeviceResponse response = iotBuilder.buildIot().freezeDevice(request);
+            log.info("冻结设备:{}",response.toString());
+            return response;
+        } catch (ConnectionException e) {
+            e.printStackTrace();
+        } catch (RequestTimeoutException e) {
+            e.printStackTrace();
+        } catch (ServiceResponseException e) {
+            e.printStackTrace();
+            System.out.println(e.getHttpStatusCode());
+            System.out.println(e.getRequestId());
+            System.out.println(e.getErrorCode());
+            System.out.println(e.getErrorMsg());
+        }
+        return null;
+    }
+
+    /**
+     * 解冻设备
+     * @param deviceId 设备ID 使用已有设备编号
+     * @return UnfreezeDeviceResponse
+     */
+    public UnfreezeDeviceResponse unfreezeDeviceRequest(String deviceId) {
+        UnfreezeDeviceRequest request = new UnfreezeDeviceRequest();
+        request.withDeviceId(deviceId);
+        try {
+            UnfreezeDeviceResponse response = iotBuilder.buildIot().unfreezeDevice(request);
+            log.info("解冻设备:{}",response.toString());
+            return response;
+        } catch (ConnectionException e) {
+            e.printStackTrace();
+        } catch (RequestTimeoutException e) {
+            e.printStackTrace();
+        } catch (ServiceResponseException e) {
+            e.printStackTrace();
+            System.out.println(e.getHttpStatusCode());
+            System.out.println(e.getRequestId());
+            System.out.println(e.getErrorCode());
+            System.out.println(e.getErrorMsg());
+        }
+        return null;
+    }
+
+    /**
+     * 删除设备
+     * @param deviceId 设备ID 使用已有设备编号
+     * @return DeleteDeviceResponse
+     */
+    public DeleteDeviceResponse deleteDeviceRequest(String deviceId) {
+        DeleteDeviceRequest request = new DeleteDeviceRequest();
+        request.withDeviceId(deviceId);
+        try {
+            DeleteDeviceResponse response = iotBuilder.buildIot().deleteDevice(request);
+            log.info("删除设备:{}",response.toString());
+            return response;
+        } catch (ConnectionException e) {
+            e.printStackTrace();
+        } catch (RequestTimeoutException e) {
+            e.printStackTrace();
+        } catch (ServiceResponseException e) {
+            e.printStackTrace();
+            System.out.println(e.getHttpStatusCode());
+            System.out.println(e.getRequestId());
+            System.out.println(e.getErrorCode());
+            System.out.println(e.getErrorMsg());
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java
new file mode 100644
index 0000000..9b0d3b1
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java
@@ -0,0 +1,13 @@
+package com.ruoyi.integration.iotda.utils.listener;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * iotda消息监听
+ */
+@Slf4j
+@Component
+public class IotMessageListener {
+    
+}
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/produce/IotMessageProduce.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/produce/IotMessageProduce.java
new file mode 100644
index 0000000..6e386cb
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/produce/IotMessageProduce.java
@@ -0,0 +1,13 @@
+package com.ruoyi.integration.iotda.utils.produce;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * iotda消息发送
+ */
+@Slf4j
+@Component
+public class IotMessageProduce {
+    
+}
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/time/UtcToSeconds.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/time/UtcToSeconds.java
new file mode 100644
index 0000000..0206b39
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/time/UtcToSeconds.java
@@ -0,0 +1,19 @@
+package com.ruoyi.integration.iotda.utils.time;
+
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+ 
+public class UtcToSeconds {
+    public static long convertToSeconds(String utcTimeString) {
+        Instant instant = Instant.parse(utcTimeString);
+        long seconds = instant.atOffset(ZoneOffset.UTC).toEpochSecond();
+        return seconds;
+    }
+ 
+    public static void main(String[] args) {
+        String utcTimeString = "2023-04-01T12:00:00Z";
+        long seconds = convertToSeconds(utcTimeString);
+        System.out.println("Seconds since epoch: " + seconds);
+    }
+}
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/token/IotTokenUtil.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/token/IotTokenUtil.java
new file mode 100644
index 0000000..c2a2428
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/token/IotTokenUtil.java
@@ -0,0 +1,72 @@
+package com.ruoyi.integration.iotda.utils.token;
+
+import com.huaweicloud.sdk.core.exception.ConnectionException;
+import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
+import com.huaweicloud.sdk.core.exception.ServiceResponseException;
+import com.huaweicloud.sdk.iam.v3.model.*;
+import com.ruoyi.common.redis.service.RedisService;
+import com.ruoyi.integration.iotda.constant.IotConstant;
+import com.ruoyi.integration.iotda.builder.IotBuilder;
+import com.ruoyi.integration.iotda.config.IotAccountConfig;
+import com.ruoyi.integration.iotda.utils.time.UtcToSeconds;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Component
+public class IotTokenUtil {
+    @Autowired
+    private IotBuilder iotBuilder;
+    @Autowired
+    private IotAccountConfig accountConfig;
+    @Autowired
+    private RedisService redisService;
+
+    /**
+     * 获取token
+     * @return
+     */
+    public KeystoneCreateUserTokenByPasswordResponse getToken() {
+        KeystoneCreateUserTokenByPasswordRequest request = new KeystoneCreateUserTokenByPasswordRequest();
+        KeystoneCreateUserTokenByPasswordRequestBody body = new KeystoneCreateUserTokenByPasswordRequestBody();
+        PwdPasswordUserDomain domainUser = new PwdPasswordUserDomain();
+        domainUser.withName(accountConfig.getHostAccount());
+        PwdPasswordUser userPassword = new PwdPasswordUser();
+        userPassword.withDomain(domainUser)
+                .withName(accountConfig.getIamAccount())
+                .withPassword(accountConfig.getIamPassword());
+        PwdPassword passwordIdentity = new PwdPassword();
+        passwordIdentity.withUser(userPassword);
+        List<PwdIdentity.MethodsEnum> listIdentityMethods = new ArrayList<>();
+        listIdentityMethods.add(PwdIdentity.MethodsEnum.fromValue(IotConstant.PASSWORD));
+        PwdIdentity identityAuth = new PwdIdentity();
+        identityAuth.withMethods(listIdentityMethods)
+                .withPassword(passwordIdentity);
+        PwdAuth authbody = new PwdAuth();
+        authbody.withIdentity(identityAuth);
+        body.withAuth(authbody);
+        request.withBody(body);
+        try {
+            KeystoneCreateUserTokenByPasswordResponse response = iotBuilder.buildIam().keystoneCreateUserTokenByPassword(request);
+            redisService.setCacheObject(IotConstant.IOT_TOKEN, response.getXSubjectToken(), UtcToSeconds.convertToSeconds(response.getToken().getExpiresAt()), TimeUnit.SECONDS);
+            return response;
+        } catch (ConnectionException e) {
+            e.printStackTrace();
+        } catch (RequestTimeoutException e) {
+            e.printStackTrace();
+        } catch (ServiceResponseException e) {
+            e.printStackTrace();
+            System.out.println(e.getHttpStatusCode());
+            System.out.println(e.getRequestId());
+            System.out.println(e.getErrorCode());
+            System.out.println(e.getErrorMsg());
+        }
+        return null;
+    }
+
+}

--
Gitblit v1.7.1