ソースを参照

拓元算法相关-可发布

谭斌 1 年間 前
コミット
2bc1cafa62

+ 20 - 0
device-api-service/src/main/java/com/xy/config/DeviceThreadPoolConfig.java

@@ -19,6 +19,8 @@ public class DeviceThreadPoolConfig {
 
     public static final String DEVICE_STATUS_UP = "deviceStatusUp";
 
+    public static final String TY_DEVICE_STATUS = "tyDeviceStatus";
+
     /**
      * 公用线程池
      */
@@ -83,6 +85,24 @@ public class DeviceThreadPoolConfig {
                 .builder();
     }
 
+    /**
+     * 拓元设备状态
+     *
+     * @return {@link ThreadPoolTaskExecutor}
+     */
+    @DynamicTp
+    @Bean(TY_DEVICE_STATUS)
+    public ThreadPoolTaskExecutor tyDeviceStatus() {
+        int coreSize = 1;
+        return ThreadPoolUtils.newPoll()
+                .name(TY_DEVICE_STATUS)
+                .coreSize(coreSize)
+                .maxSize(coreSize * 10)
+                .keepAlive(30)
+                .queueSize(coreSize)
+                .builder();
+    }
+
     /**
      * 设备状态上报线程池
      */

+ 9 - 0
device-api-service/src/main/java/com/xy/entity/DeviceInfo.java

@@ -125,5 +125,14 @@ public class DeviceInfo {
      * 商户名称
      */
     private String mercName;
+    /**
+     * 第三方设备登记状态
+     */
+    private String thirdStatus;
+
+    /**
+     * 第三方设备审核结果
+     */
+    private String thirdResult;
 
 }

+ 56 - 1
device-api-service/src/main/java/com/xy/service/DeviceInfoServiceImpl.java

@@ -86,6 +86,7 @@ public class DeviceInfoServiceImpl extends ServiceImpl<DeviceInfoMapper, DeviceI
     private final CloudWalkApiService cloudWalkApiService;
     private final AlgorithmService algorithmService;
     private final CountApiService countApiService;
+    private final TyApiService tyApiService;
     /**
      * 质检商户code
      */
@@ -111,7 +112,6 @@ public class DeviceInfoServiceImpl extends ServiceImpl<DeviceInfoMapper, DeviceI
 
     private final MercPlaceService mercPlaceService;
 
-    private final TyApiService tyApiService;
 
     @Override
     @ApiOperation("设备列表-管理员")
@@ -210,6 +210,61 @@ public class DeviceInfoServiceImpl extends ServiceImpl<DeviceInfoMapper, DeviceI
         return R.ok(pageBean.setRecords(builder));
     }
 
+    @ApiOperation("拓元算法设备列表")
+    @PostMapping("tyDeviceList")
+    public R<PageBean<DeviceInfoDto.Vo>> tyDeviceList(@RequestBody @Validated DeviceInfoDto.TyDeviceDTO dto) {
+        PageBean pageBean = dto.getPage();
+        String searchKey = dto.getSearchKey();
+        Integer thirdStatus = dto.getThirdStatus();
+        List<String> statusList = new ArrayList<>();
+        //1待审核,2已审核
+        if (thirdStatus != null && thirdStatus.intValue() == 1) {
+            statusList = CollUtil.newArrayList("1000", "2000", "3000", "5000");
+        }
+        // 2已审核  4000: 设备登记成功
+        if (thirdStatus != null && thirdStatus.intValue() == 2) {
+            statusList.add("4000");
+        }
+        LambdaQueryWrapper<DeviceInfo> lqw = new LambdaQueryWrapper<>();
+        lqw.eq(DeviceInfo::getAlgorithmId, AlgorithmTypeEnum.TY.getId());
+        lqw.in(CollUtil.isNotEmpty(statusList), DeviceInfo::getThirdStatus, statusList);
+        lqw.and(StrUtil.isNotEmpty(searchKey), wrapper -> wrapper
+                .eq(DeviceInfo::getDeviceId, searchKey)
+                .or()
+                .likeRight(DeviceInfo::getDeviceName, searchKey));
+        IPage<DeviceInfo> iPage = page(toIPage(pageBean), lqw);
+        List<DeviceInfo> records = iPage.getRecords();
+        if (CollUtil.isNotEmpty(records)) {
+            ThreadPoolUtils.Execute execute = ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.TY_DEVICE_STATUS, records.size());
+            records.forEach(deviceInfo -> execute.execute(() -> {
+                Long deviceId = deviceInfo.getDeviceId();
+                /**
+                 * 请求状态码。
+                 * 1000: 未知的设备CPUID
+                 * 2000: 设备登记 审批中
+                 * 3000: 设备登记已拒绝
+                 * 4000: 设备登记成功
+                 * 5000: 设备已禁⽤
+                 */
+                String tyStatus = deviceInfo.getThirdStatus();
+                if (!"4000".equals(tyStatus)) {
+                    //未登记成功的需要实时查询
+                    //查询登记设备
+                    DeviceQueryVO deviceQueryVO = tyApiService.deviceQuery(new DeviceQueryDTO().setCpuId(String.valueOf(deviceId)));
+                    Integer status = deviceQueryVO.getStatus();
+                    String message = deviceQueryVO.getMessage();
+                    deviceInfo.setThirdStatus(String.valueOf(status));
+                    deviceInfo.setThirdResult(message);
+                    updateById(deviceInfo);
+                }
+            }));
+            execute.end();
+
+        }
+        PageBean<DeviceInfoDto.Vo> voPageBean = toPageBean(DeviceInfoDto.Vo.class, iPage);
+
+        return R.ok(voPageBean);
+    }
 
     /**
      * 商户设备列表分页-穿梭框用

+ 16 - 0
device-api-service/src/main/java/com/xy/service/ExportAsyncService.java

@@ -3,6 +3,7 @@ package com.xy.service;
 import com.xy.annotate.RestMappingController;
 import com.xy.dto.DeviceInfoDto;
 import com.xy.utils.R;
+import com.xy.utils.TyImgUrlConvert;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
@@ -11,6 +12,7 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
 import javax.validation.Valid;
+import java.io.IOException;
 
 /***
  * 异步导出处理
@@ -31,4 +33,18 @@ public class ExportAsyncService {
         deviceInfoService.exportDevicesAsync(page);
         return R.ok();
     }
+
+    @ApiOperation("拓元商品上传")
+    @PostMapping("tyGoodsImgUpload")
+    public R tyGoodsImgUpload() {
+        try {
+            TyImgUrlConvert.upload();
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return R.ok();
+    }
+
 }

+ 109 - 0
device-api-service/src/main/java/com/xy/utils/TyImgUrlConvert.java

@@ -0,0 +1,109 @@
+package com.xy.utils;
+
+import com.aliyun.oss.ClientConfiguration;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.common.auth.DefaultCredentialProvider;
+import com.aliyun.oss.model.CannedAccessControlList;
+import com.aliyun.oss.model.PutObjectResult;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * 拓元算法有效期商品链接下载并转换到喵星人自己的oss上。由于拓元的barcode唯一使用barcode命名图片
+ *
+ * @author 谭斌
+ * @date 2023/11/13
+ */
+public class TyImgUrlConvert {
+
+    public static void main(String[] args) throws Exception {
+        upload();
+    }
+
+    public static void upload() throws InterruptedException, IOException {
+        // 初始化OSS
+        OSS ossClient = new OSSClient("oss-cn-beijing.aliyuncs.com",
+                new DefaultCredentialProvider("LTAI5tKyfiX3LT2PENxrax6a", "QDpoLnUek0e0DE613mECgIirDExW89"),
+                new ClientConfiguration());
+
+        
+        InputStream inputStream = IoUtils.inputStream("tyGoods.xlsx").get();
+        // 读取Excel
+        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
+
+        XSSFSheet sheet = workbook.getSheetAt(0);
+
+        // 创建线程池
+        ExecutorService executor = Executors.newFixedThreadPool(20);
+
+        // 遍历每一行数据
+        for (Row row : sheet) {
+            if (row.getRowNum() == 0) { // 跳过表头
+                continue;
+            }
+
+            Cell barcodeCell = row.getCell(0);
+            Cell urlCell = row.getCell(1);
+
+            if (barcodeCell == null || urlCell == null) {
+                continue;
+            }
+
+            String barcode = barcodeCell.getStringCellValue();
+            String url = urlCell.getStringCellValue();
+            String bucketName = "mxrnetfiles";
+            // 下载并上传图片到阿里云对象存储
+            Future<String> future = executor.submit(() -> {
+                try {
+                    // 下载图片
+                    HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
+                    connection.setRequestMethod("GET");
+                    connection.connect();
+                    BufferedImage image = ImageIO.read(connection.getInputStream());
+
+                    // 上传图片到阿里云对象存储
+                    File tempFile = File.createTempFile("image", ".png");
+                    FileOutputStream fos = new FileOutputStream(tempFile);
+                    ImageIO.write(image, "png", fos);
+                    fos.close();
+                    String fileUrl = "tyGoods/" + barcode + ".png";
+                    PutObjectResult result = ossClient.putObject(bucketName, fileUrl, tempFile);
+                    // 设置权限(公开读)
+                    ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
+                    if (result != null) {
+//                        https://cdn.ossfile.mxrvending.com/tyGoods/6948960111210.png
+                        System.out.println("------OSS文件上传成功------ " + fileUrl);
+                    }
+                    tempFile.delete();
+
+                    return "OK";
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    return "ERROR";
+                }
+            });
+
+            // 等待所有任务完成
+            while (!future.isDone()) {
+                Thread.sleep(100);
+            }
+        }
+        // 关闭线程池
+        executor.shutdown();
+    }
+}

+ 31 - 0
device-api/src/main/java/com/xy/dto/DeviceInfoDto.java

@@ -117,6 +117,25 @@ public class DeviceInfoDto {
         private String mercCode;
     }
 
+    @Data
+    @Accessors(chain = true)
+    public static class TyDeviceDTO {
+        @NotNull(message = "分页对象不能空")
+        @ApiModelProperty(value = "分页对象", required = true)
+        private PageBean page;
+
+        @ApiModelProperty(value = "设备ID或名称搜索")
+        private String searchKey;
+
+        /**
+         * 第三方设备登记状态
+         */
+        @ApiModelProperty(value = "第三方设备登记状态1待审核,2已审核")
+        private Integer thirdStatus;
+
+
+    }
+
     @Data
     @Accessors(chain = true)
     public static class MyDeviceDTO {
@@ -575,6 +594,18 @@ public class DeviceInfoDto {
         @ApiModelProperty("管理员名字")
         private String adminName;
 
+        /**
+         * 第三方设备登记状态
+         */
+        @ApiModelProperty("第三方设备登记状态")
+        private String thirdStatus;
+
+        /**
+         * 第三方设备审核结果
+         */
+        @ApiModelProperty("第三方设备审核结果")
+        private String thirdResult;
+
     }
 
     @Data

BIN
device-start/src/main/resources/tyGoods.xlsx