Преглед изворни кода

feat:新增冷链设备导入模版下载接口
feat:新增冷链设备导入接口

黄渊昊 пре 5 месеци
родитељ
комит
3bebb3d2e0

+ 23 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/controller/MonitorDeviceController.java

@@ -17,6 +17,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotEmpty;
 import org.springframework.validation.annotation.Validated;
@@ -24,6 +25,7 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 import vip.xiaonuo.coldchain.modular.monitordevice.entity.MonitorDevice;
 import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDeviceAddParam;
 import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDeviceEditParam;
@@ -171,4 +173,25 @@ public class MonitorDeviceController {
     public CommonResult<CountEntity> getIndexCount() {
         return CommonResult.data(monitorDeviceService.getIndexCount());
     }
+
+    /**
+     * 下载Excel模板
+     */
+    @Operation(summary = "下载Excel模板")
+    @GetMapping("/coldchain/monitordevice/downloadTemplate")
+    public CommonResult<String> downloadTemplate(HttpServletResponse response) {
+       monitorDeviceService.downloadTemplate(response);
+       return CommonResult.ok();
+    }
+
+    /**
+     * 导入数据
+     */
+    @Operation(summary = "导入数据")
+    @GetMapping("/coldchain/monitordevice/import")
+    public CommonResult<String> importMonitorDevice(MultipartFile file) {
+        monitorDeviceService.importMonitorDevice(file);
+        return CommonResult.ok();
+    }
+
 }

+ 87 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/entity/MonitorDeviceTemplate.java

@@ -0,0 +1,87 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.coldchain.modular.monitordevice.entity;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+/**
+ * 采集器模版
+ *
+ * @author 黄渊昊
+ **/
+@Getter
+@Setter
+@EqualsAndHashCode
+@Data
+public class MonitorDeviceTemplate{
+
+    /**
+     * 设备型号
+     */
+    @Schema(description = "设备型号")
+    @ExcelProperty("设备型号编码")
+    private String modelName;
+
+    /**
+     * 设备编码
+     */
+    @Schema(description = "设备编码")
+    @ExcelProperty("设备编码")
+    private String deviceCode;
+
+    /**
+     * 设备名称
+     */
+    @Schema(description = "设备名称")
+    @ExcelProperty("设备名称")
+    private String deviceName;
+
+    /**
+     * 传感器路数
+     */
+    @Schema(description = "传感器路数")
+    @ExcelProperty("传感器总路数")
+    private Integer sensorCount;
+
+    /** 报警上限 */
+    @Schema(description = "报警上限")
+    @ExcelProperty("温度上限(℃)")
+    private Float temperatureUp;
+
+    /** 报警上限 */
+    @Schema(description = "报警上限")
+    @ExcelProperty("湿度上限(%)")
+    private Float humidityUp;
+
+    /** 报警上限 */
+    @Schema(description = "报警上限")
+    @ExcelProperty("二氧化碳上限(ppm)")
+    private Float co2Up;
+
+    /** 报警下限 */
+    @Schema(description = "报警下限")
+    @ExcelProperty("温度下限(℃)")
+    private Float temperatureDown;
+
+    /** 报警下限 */
+    @Schema(description = "报警下限")
+    @ExcelProperty("湿度下限(%)")
+    private Float humidityDown;
+
+    /** 报警下限 */
+    @Schema(description = "报警下限")
+    @ExcelProperty("二氧化碳下限(ppm)")
+    private Float co2Down;
+}

+ 15 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/MonitorDeviceService.java

@@ -16,6 +16,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.github.jfcloud.influxdb.flux.AggregationWindow;
 import com.github.jfcloud.influxdb.flux.QueryCondition;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.web.multipart.MultipartFile;
 import rk.netDevice.sdk.p2.ParamData;
 import rk.netDevice.sdk.p2.ParamIdsData;
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
@@ -114,4 +116,17 @@ public interface MonitorDeviceService extends IService<MonitorDevice> {
     CountEntity getIndexCount();
 
     MonitorDevice queryByDeviceCode(Integer deviceId);
+
+    /**
+     * 下载导入模版
+     * @param response
+     */
+    void downloadTemplate(HttpServletResponse response);
+
+    /**
+     * 导入数据
+     * @param file
+     * @return
+     */
+    void importMonitorDevice(MultipartFile file);
 }

+ 78 - 7
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/impl/MonitorDeviceServiceImpl.java

@@ -16,6 +16,10 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollStreamUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -23,10 +27,13 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.jfcloud.influxdb.flux.AggregationWindow;
 import com.github.jfcloud.influxdb.flux.QueryCondition;
 import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 import rk.netDevice.sdk.p2.ParamData;
 import rk.netDevice.sdk.p2.ParamIdsData;
 import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
@@ -37,6 +44,7 @@ import vip.xiaonuo.coldchain.core.renke.RenKeService;
 import vip.xiaonuo.coldchain.core.service.JfcloudSensorDataService;
 import vip.xiaonuo.coldchain.modular.monitordevice.dto.MonitorDevicePageDto;
 import vip.xiaonuo.coldchain.modular.monitordevice.entity.MonitorDevice;
+import vip.xiaonuo.coldchain.modular.monitordevice.entity.MonitorDeviceTemplate;
 import vip.xiaonuo.coldchain.modular.monitordevice.enums.MonitorDeviceStatusEnum;
 import vip.xiaonuo.coldchain.modular.monitordevice.mapper.MonitorDeviceMapper;
 import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDeviceAddParam;
@@ -56,6 +64,12 @@ import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
 
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.text.ParseException;
 import java.time.Instant;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -81,7 +95,6 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
     @Resource
     private MonitorTargetService monitorTargetService;
 
-
     private String bucketName;
 
     @Override
@@ -101,7 +114,6 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
             queryWrapper.lambda().orderByAsc(MonitorDevice::getSortCode);
         }
         queryWrapper.lambda().eq(MonitorDevice::getCreateOrg,loginUser.getOrgId()).eq(MonitorDevice::getDeleteFlag,CommonDeleteFlagEnum.NOT_DELETE);
-        //分页查询
         Page<MonitorDevice> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
         if (page.getTotal() < 1) {
             return page;
@@ -193,7 +205,7 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
 
     public List<MonitorDevice> getDeviceByDeviceCode(String deviceCode) {
         return this.list(new QueryWrapper<MonitorDevice>().eq("device_code", deviceCode)
-                .lambda().eq(MonitorDevice::getDeleteFlag,CommonDeleteFlagEnum.NOT_DELETE));
+                .lambda().eq(MonitorDevice::getDeleteFlag, CommonDeleteFlagEnum.NOT_DELETE));
     }
 
 
@@ -298,7 +310,7 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
 
 
     @Override
-    public List<MonitorDevice> myList(Boolean isAll,String sensorType) {
+    public List<MonitorDevice> myList(Boolean isAll, String sensorType) {
         SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
 
         //查询设备类型
@@ -348,7 +360,7 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
 
     @Override
     public List<SensorData> queryDataByDeviceIdAndRoads(String deviceId, Integer roads, String startTime, String endTime, String field, AggregationWindow aggregationWindow) {
-        return sensorDataService.queryDataByDeviceIdAndRoads(deviceId, roads, startTime, endTime,field,aggregationWindow);
+        return sensorDataService.queryDataByDeviceIdAndRoads(deviceId, roads, startTime, endTime, field, aggregationWindow);
     }
 
     @Override
@@ -376,7 +388,7 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
         Integer sensorCount = 0;
         SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
         LambdaQueryWrapper<MonitorDevice> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(MonitorDevice::getDeleteFlag, CommonDeleteFlagEnum.NOT_DELETE).eq(MonitorDevice::getCreateOrg,loginUser.getOrgId());
+        queryWrapper.eq(MonitorDevice::getDeleteFlag, CommonDeleteFlagEnum.NOT_DELETE).eq(MonitorDevice::getCreateOrg, loginUser.getOrgId());
         List<MonitorDevice> monitorDeviceList = list(queryWrapper);
         for (MonitorDevice monitorDevice : monitorDeviceList) {
             sensorCount += monitorDevice.getSensorCount();
@@ -390,7 +402,66 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
     @Override
     public MonitorDevice queryByDeviceCode(Integer deviceId) {
         LambdaQueryWrapper<MonitorDevice> onlineDeviceQueryWrapper = new LambdaQueryWrapper<>();
-        onlineDeviceQueryWrapper.eq(MonitorDevice::getDeviceCode, deviceId).eq(MonitorDevice::getDeleteFlag,CommonDeleteFlagEnum.NOT_DELETE);
+        onlineDeviceQueryWrapper.eq(MonitorDevice::getDeviceCode, deviceId).eq(MonitorDevice::getDeleteFlag, CommonDeleteFlagEnum.NOT_DELETE);
         return this.getOne(onlineDeviceQueryWrapper);
     }
+
+    @Override
+    public void downloadTemplate(HttpServletResponse response) {
+        String fileName = "冷链设备导入模板";
+        String sheetName = "冷链设备导入模板";
+        try {
+//            ExcelUtil.writeExcel(response, null, fileName, sheetName, MonitorDeviceTemplate.class);
+            //表头样式
+            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
+            //设置表头居中对齐
+            headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
+            //内容样式
+            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
+            //设置内容靠左对齐
+            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
+
+            response.setContentType("application/vnd.ms-excel");
+            response.setCharacterEncoding("utf8");
+            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + ".xlsx");
+
+            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
+            EasyExcel.write(response.getOutputStream(), MonitorDeviceTemplate.class)
+                    .excelType(ExcelTypeEnum.XLSX).sheet(sheetName)
+                    .registerWriteHandler(horizontalCellStyleStrategy)
+                    .doWrite(new ArrayList<MonitorDeviceTemplate>());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void importMonitorDevice(MultipartFile file) {
+        List<MonitorDeviceTemplate> monitorDeviceTemplateList = null;
+        // excel同步读取数据
+        try {
+            monitorDeviceTemplateList = EasyExcel.read(new BufferedInputStream(file.getInputStream())).head(MonitorDeviceTemplate.class).sheet().doReadSync();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        // 检查是否大于1000条
+        if (monitorDeviceTemplateList.size() > 2) {
+            throw new RuntimeException("超过最多处理条数");
+        }
+        // 将 userExcelList 转成 userList
+        List<MonitorDevice> monitorDeviceList = new ArrayList<>();
+        for (MonitorDeviceTemplate monitorDeviceTemplate : monitorDeviceTemplateList) {
+            // 判断上下限输入是否合法
+            if (monitorDeviceTemplate.getCo2Down() >= monitorDeviceTemplate.getCo2Up() ||
+                    monitorDeviceTemplate.getHumidityDown() >= monitorDeviceTemplate.getHumidityUp() ||
+                    monitorDeviceTemplate.getTemperatureDown() >= monitorDeviceTemplate.getTemperatureUp()) {
+                throw new CommonException("设备:*" + monitorDeviceTemplate.getDeviceName() + "*的上下限填写有误");
+            }
+            MonitorDevice monitorDevice = BeanUtil.copyProperties(monitorDeviceTemplate, MonitorDevice.class);
+            monitorDeviceList.add(monitorDevice);
+        }
+        // 入库操作
+        this.saveBatch(monitorDeviceList);
+    }
+
 }

+ 1 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevicetype/service/impl/MonitorDeviceTypeServiceImpl.java

@@ -101,6 +101,7 @@ public class MonitorDeviceTypeServiceImpl extends ServiceImpl<MonitorDeviceTypeM
         if (sensorType != null) {
             queryWrapper.eq(MonitorDeviceType::getSensorType, sensorType);
         }
+        queryWrapper.eq(MonitorDeviceType::getDeleteFlag,CommonDeleteFlagEnum.NOT_DELETE);
         return list(queryWrapper);
     }
 

+ 4 - 1
snowy-web-app/src/main/java/vip/xiaonuo/core/config/GlobalConfigure.java

@@ -145,7 +145,10 @@ public class GlobalConfigure implements WebMvcConfigurer {
             /* 微信获取用户信息 */
             "/coldchain/alarmuser/getUserInfo",
 
-            "/qp/*"
+            "/qp/*",
+
+            /* 全值匹配组织名 */
+            "/coldchain/alarmuser/getOrgByName"
     };
 
     /**