Parcourir la source

Merge branch 'master' into 新购SIM卡

hechunping il y a 11 mois
Parent
commit
e60858563b
18 fichiers modifiés avec 685 ajouts et 101 suppressions
  1. 6 2
      device-api-service-merc-mini/src/main/java/com/xy/controller/MercMiniDeviceController.java
  2. 31 39
      device-api-service-merc-mini/src/main/java/com/xy/controller/MercMiniDeviceDataController.java
  3. 234 16
      device-api-service/src/main/java/com/xy/job/MercFeeCountDayJob.java
  4. 114 0
      device-api-service/src/main/java/com/xy/open/DeviceOpenApiService.java
  5. 42 0
      device-api-service/src/main/java/com/xy/open/config/OpenServiceConfig.java
  6. 59 0
      device-api-service/src/main/java/com/xy/open/dto/DeviceOpenApiDTO.java
  7. 56 0
      device-api-service/src/main/java/com/xy/open/vo/DeviceOpenApiVO.java
  8. 12 8
      device-api-service/src/main/java/com/xy/service/DeviceConfigServiceImpl.java
  9. 1 2
      device-api-service/src/main/java/com/xy/service/DeviceSetRecordsServiceImpl.java
  10. 73 29
      device-api-service/src/main/java/com/xy/service/factory/device/impl/alipay/AliPayOpenDeviceFatoryImpl.java
  11. 4 1
      device-api-service/src/main/resources/mapper/DeviceInfoMapper.xml
  12. 12 4
      device-api/src/main/java/com/xy/alipay/SpiDeviceService.java
  13. 9 0
      device-api/src/main/java/com/xy/dto/DeviceInfoDto.java
  14. 1 0
      device-api/src/main/java/com/xy/dto/MercFeeCountDayDto.java
  15. 10 0
      device-start/src/main/resources/i18n/isp/bizerror_en.properties
  16. 14 0
      device-start/src/main/resources/i18n/isp/bizerror_zh_CN.properties
  17. 2 0
      device-start/src/main/resources/i18n/isp/goods_error_en.properties
  18. 5 0
      device-start/src/main/resources/i18n/isp/goods_error_zh_CN.properties

+ 6 - 2
device-api-service-merc-mini/src/main/java/com/xy/controller/MercMiniDeviceController.java

@@ -17,6 +17,7 @@ import com.xy.dto.*;
 import com.xy.dto.be.MercDto;
 import com.xy.dto.common.MercPlaceDto;
 import com.xy.entity.*;
+import com.xy.enums.LogEnum;
 import com.xy.enums.MercStatus;
 import com.xy.service.*;
 import com.xy.service.be.MercFeignService;
@@ -89,7 +90,7 @@ public class MercMiniDeviceController {
         redisService.remove("device:auth:code:" + deviceId);
     }
 
-    @LogOperate
+    @LogOperate(logType = LogEnum.LogType.V2, optType = LogEnum.OptType.V2, logContent = "解绑商户")
     @ApiOperation("解绑商户")
     @PostMapping("unBindMercDevice")
     R<Boolean> unBindMercDevice(@RequestBody @Validated DeviceInfoDto.MercDeviceUnBindDto dto) {
@@ -102,7 +103,7 @@ public class MercMiniDeviceController {
         return R.ok(deviceInfoService.unBindDeviceByMerc(dto)).setLogMsg(log);
     }
 
-    @LogOperate
+    @LogOperate(logType = LogEnum.LogType.V2, optType = LogEnum.OptType.V2, logContent = "商户设备授权")
     @ApiOperation("商户设备授权")
     @PostMapping("deviceAuth")
     public R mercDeviceAuth(@RequestBody @Validated DeviceInfoDto.MercDeviceAuthDto auth) {
@@ -269,6 +270,9 @@ public class MercMiniDeviceController {
             // 工作温度设置
             DeviceTempSetDto.Vo lastTempset = R.feignCheckData(deviceTempSetService.getLastOne(new DeviceTempSetDto.GetLastOneDto().setDeviceId(vo.getDeviceId())));
             vo.setJobTempSetValue(lastTempset == null ? null : lastTempset.getTempValue());
+            // 设备配置
+            DeviceConfigDto.Vo deviceConfig = deviceConfigService.obj(new DeviceConfigDto.Obj().setDeviceId(vo.getDeviceId())).getData();
+            vo.setDeviceConfig(deviceConfig);
         }
 
         DeviceConfig deviceConfig = deviceConfigService.getById(obj.getDeviceId());

+ 31 - 39
device-api-service-merc-mini/src/main/java/com/xy/controller/MercMiniDeviceDataController.java

@@ -1,22 +1,14 @@
 package com.xy.controller;
 
-import cn.hutool.core.collection.CollUtil;
 import com.xy.annotate.RestMappingController;
-import com.xy.dto.DeviceDataDayDto;
 import com.xy.dto.be.MercDto;
 import com.xy.service.DeviceDataDayService;
 import com.xy.service.be.MercService;
-import com.xy.utils.Emptys;
 import com.xy.utils.MercAuthUtils;
-import com.xy.utils.PageBean;
 import com.xy.utils.R;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
 
-import javax.validation.Valid;
 import java.util.List;
 
 /**
@@ -35,37 +27,37 @@ public class MercMiniDeviceDataController {
     private final DeviceDataDayService deviceDataDayService;
     private final MercService mercService;
 
-    @PostMapping("sumPage")
-    @ApiOperation("设备销售数据统计分页")
-    public R<PageBean<DeviceDataDayDto.SumPageVo>> sumPage(@RequestBody @Valid DeviceDataDayDto.SumPageDto dto) {
-        dto.setMercId(MercAuthUtils.getMercId());
-        if (Emptys.check(dto.getDeviceId())) {
-            dto.setMercDeviceIds(CollUtil.newArrayList(dto.getDeviceId()));
-        }else{
-            List<Long> mercDeviceIds = getMercDeviceIds();
-            if (CollUtil.isEmpty(mercDeviceIds)) {
-                return R.ok(new PageBean<>());
-            }
-            dto.setMercDeviceIds(mercDeviceIds);
-        }
-        return R.ok(deviceDataDayService.sumPage(dto).getData());
-    }
-
-    @PostMapping("sumCount")
-    @ApiOperation("设备销售数据统计总计")
-    public R<DeviceDataDayDto.SumCountVo> sumCount(@RequestBody @Valid DeviceDataDayDto.SumCountDto dto) {
-        dto.setMercId(MercAuthUtils.getMercId());
-        if (Emptys.check(dto.getDeviceId())) {
-            dto.setMercDeviceIds(CollUtil.newArrayList(dto.getDeviceId()));
-        }else{
-            List<Long> mercDeviceIds = getMercDeviceIds();
-            if (CollUtil.isEmpty(mercDeviceIds)) {
-                return R.ok(new DeviceDataDayDto.SumCountVo());
-            }
-            dto.setMercDeviceIds(mercDeviceIds);
-        }
-        return R.ok(deviceDataDayService.sumCount(dto).getData());
-    }
+//    @PostMapping("sumPage")
+//    @ApiOperation("设备销售数据统计分页")
+//    public R<PageBean<DeviceDataDayDto.SumPageVo>> sumPage(@RequestBody @Valid DeviceDataDayDto.SumPageDto dto) {
+//        dto.setMercId(MercAuthUtils.getMercId());
+//        if (Emptys.check(dto.getDeviceId())) {
+//            dto.setMercDeviceIds(CollUtil.newArrayList(dto.getDeviceId()));
+//        } else {
+//            List<Long> mercDeviceIds = getMercDeviceIds();
+//            if (CollUtil.isEmpty(mercDeviceIds)) {
+//                return R.ok(new PageBean<>());
+//            }
+//            dto.setMercDeviceIds(mercDeviceIds);
+//        }
+//        return R.ok(deviceDataDayService.sumPage(dto).getData());
+//    }
+//
+//    @PostMapping("sumCount")
+//    @ApiOperation("设备销售数据统计总计")
+//    public R<DeviceDataDayDto.SumCountVo> sumCount(@RequestBody @Valid DeviceDataDayDto.SumCountDto dto) {
+//        dto.setMercId(MercAuthUtils.getMercId());
+//        if (Emptys.check(dto.getDeviceId())) {
+//            dto.setMercDeviceIds(CollUtil.newArrayList(dto.getDeviceId()));
+//        } else {
+//            List<Long> mercDeviceIds = getMercDeviceIds();
+//            if (CollUtil.isEmpty(mercDeviceIds)) {
+//                return R.ok(new DeviceDataDayDto.SumCountVo());
+//            }
+//            dto.setMercDeviceIds(mercDeviceIds);
+//        }
+//        return R.ok(deviceDataDayService.sumCount(dto).getData());
+//    }
 
     /**
      * 获取商户设备列表

+ 234 - 16
device-api-service/src/main/java/com/xy/job/MercFeeCountDayJob.java

@@ -40,7 +40,7 @@ import java.util.stream.Collectors;
 
 
 /**
- * 商户佣金费用收益每日统计任务(不含今天) 每日凌晨1点执行
+ * 商户佣金费用收益每日统计任务(不含今天) 每日凌晨4点执行 (算法服务费是凌晨3点执行)
  */
 @Slf4j
 @Component
@@ -66,6 +66,222 @@ public class MercFeeCountDayJob {
 
     private final MercService mercService;
 
+    @PostMapping("queryByDay")
+    @ApiOperation("指定日期查询")
+    public R queryByDay(@RequestBody @Validated MercFeeCountDayDto.ExcuteDayDTO dto) {
+        Integer type = dto.getType();
+        String date = dto.getDate();
+        DateTime yesterday = DateUtil.yesterday();
+        String queryDay = DateUtil.format(yesterday, DatePattern.PURE_DATE_PATTERN);
+        if (StrUtil.isNotEmpty(date)) {
+            queryDay = date;
+        }
+        String monthValue = StrUtil.sub(queryDay, 0, 6);
+        Integer dateValue = Integer.valueOf(queryDay);
+        LocalDate dayDate = LocalDate.parse(queryDay, DateTimeFormatter.BASIC_ISO_DATE);
+        LocalDateTime dayTime = dayDate.atStartOfDay();
+        LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(dayTime);
+        LocalDateTime endTime = LocalDateTimeUtil.endOfDay(dayTime);
+
+        List<String> columnsMerc = Arrays.asList(LambdaUtils.getUnderlineCaseName(MercDto.Vo::getId));
+
+        List<MercDto.Vo> approvedMercList = getApprovedMercList(columnsMerc);
+        if (CollUtil.isEmpty(approvedMercList)) {
+            return R.ok();
+        }
+
+        List<MercFeeCountDay> saveMercFeeCountList = new ArrayList<>();
+        for (MercDto.Vo merc : approvedMercList) {
+            Long parentMercId = merc.getId();
+            List<Long> mercIds = R.feignCheckData(mercService.getChildMercIds(new MercDto.QuerySubDTO().setParentMercID(parentMercId)));
+            if (CollUtil.isEmpty(mercIds)) {
+                // 子商户都没有,就不用查分佣收益了
+                continue;
+            }
+            //~~~~~~~~~~~~~1设备管理费
+            if (type == 1) {
+                PageBean<DeviceChargingHistoryDto.PageVo> pageVoPageBean = getDeviceManagerFeeMerc(parentMercId, beginTime, endTime);
+                List<DeviceChargingHistoryDto.PageVo> records = pageVoPageBean == null ? null : pageVoPageBean.getRecords();
+                if (CollUtil.isNotEmpty(records)) {
+                    // 根据设备分组获取,每台设备缴费金额
+                    Map<Long, Integer> devicePayMoneyMap = records.stream()
+                            .collect(Collectors.groupingBy(DeviceChargingHistoryDto.PageVo::getMercId,
+                                    Collectors.summingInt(DeviceChargingHistoryDto.PageVo::getChargingMoney)));
+                    // 根据设备分组获取,每台设备佣金金额
+                    Map<Long, Integer> deviceAgentMoneyMap = records.stream()
+                            .collect(Collectors.groupingBy(DeviceChargingHistoryDto.PageVo::getMercId,
+                                    Collectors.summingInt(DeviceChargingHistoryDto.PageVo::getAgentMoney)));
+                    Set<Long> subMercIdSet = devicePayMoneyMap.keySet();
+                    for (Long mercId : subMercIdSet) {
+                        Integer payMoney = devicePayMoneyMap.get(mercId);
+                        Integer brokerage = deviceAgentMoneyMap.get(mercId);
+                        MercFeeCountDay deviceDayFee = new MercFeeCountDay();
+                        deviceDayFee.setFeeType(EnumMercFeeType.T1.getIntCode());
+                        deviceDayFee.setParentMercId(parentMercId);
+                        deviceDayFee.setDateValue(dateValue);
+                        deviceDayFee.setPayMoney(payMoney);
+                        deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
+                        deviceDayFee.setBrokerage(brokerage);
+                        deviceDayFee.setMercId(mercId);
+                        deviceDayFee.setParentMercId(parentMercId);
+                        saveMercFeeCountList.add(deviceDayFee);
+                    }
+                } else {
+                    // 没有费用的也要记录,为了前端收益概览的展示
+                    for (Long mercId : mercIds) {
+
+                        MercFeeCountDay deviceDayFee = new MercFeeCountDay();
+                        deviceDayFee.setFeeType(EnumMercFeeType.T1.getIntCode());
+                        deviceDayFee.setParentMercId(parentMercId);
+                        deviceDayFee.setDateValue(dateValue);
+                        deviceDayFee.setPayMoney(0);
+                        deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
+                        deviceDayFee.setBrokerage(0);
+                        deviceDayFee.setMercId(mercId);
+                        deviceDayFee.setParentMercId(parentMercId);
+                        saveMercFeeCountList.add(deviceDayFee);
+                    }
+                }
+            } else if (type == 2) {
+                //~~~~~~~~~~~~~2设备激活费
+                PageBean<DeviceAlgorithmChargingHistoryDto.PageByTopMercVO> deviceActiveFeeByMerc = getDeviceActiveFeeByMerc(parentMercId, beginTime, endTime);
+                List<DeviceAlgorithmChargingHistoryDto.PageByTopMercVO> deviceActiveFeeList = deviceActiveFeeByMerc == null ? null : deviceActiveFeeByMerc.getRecords();
+                if (CollUtil.isNotEmpty(deviceActiveFeeList)) {
+                    // 根据设备分组获取,每台设备缴费金额
+                    Map<Long, Integer> devicePayMoneyMap = deviceActiveFeeList.stream()
+                            .collect(Collectors.groupingBy(DeviceAlgorithmChargingHistoryDto.PageByTopMercVO::getMercId,
+                                    Collectors.summingInt(DeviceAlgorithmChargingHistoryDto.PageByTopMercVO::getChargingMoney)));
+                    // 根据设备分组获取,每台设备佣金金额
+                    Map<Long, Integer> deviceAgentMoneyMap = deviceActiveFeeList.stream()
+                            .collect(Collectors.groupingBy(DeviceAlgorithmChargingHistoryDto.PageByTopMercVO::getMercId,
+                                    Collectors.summingInt(DeviceAlgorithmChargingHistoryDto.PageByTopMercVO::getAgentMoney)));
+                    Set<Long> subMercIdSet = devicePayMoneyMap.keySet();
+                    for (Long mercId : subMercIdSet) {
+                        Integer payMoney = devicePayMoneyMap.get(mercId);
+                        Integer brokerage = deviceAgentMoneyMap.get(mercId);
+                        MercFeeCountDay deviceDayFee = new MercFeeCountDay();
+                        deviceDayFee.setFeeType(EnumMercFeeType.T2.getIntCode());
+                        deviceDayFee.setParentMercId(parentMercId);
+                        deviceDayFee.setDateValue(dateValue);
+                        deviceDayFee.setPayMoney(payMoney);
+                        deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
+                        deviceDayFee.setBrokerage(brokerage);
+                        deviceDayFee.setMercId(mercId);
+                        deviceDayFee.setParentMercId(parentMercId);
+                        saveMercFeeCountList.add(deviceDayFee);
+                    }
+                } else {
+                    // 没有费用的也要记录,为了前端收益概览的展示
+                    for (Long mercId : mercIds) {
+
+                        MercFeeCountDay deviceDayFee = new MercFeeCountDay();
+                        deviceDayFee.setFeeType(EnumMercFeeType.T2.getIntCode());
+                        deviceDayFee.setParentMercId(parentMercId);
+                        deviceDayFee.setDateValue(dateValue);
+                        deviceDayFee.setPayMoney(0);
+                        deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
+                        deviceDayFee.setBrokerage(0);
+                        deviceDayFee.setMercId(mercId);
+                        deviceDayFee.setParentMercId(parentMercId);
+                        saveMercFeeCountList.add(deviceDayFee);
+                    }
+                }
+
+            } else if (type == 3) {
+                //~~~~~~~~~~~~~3算法服务费
+                PageBean<MercDeviceAlgorithmChargingDto.PageByTopMercVO> deviceAgFeeByMerc = getDeviceAgFeeByMerc(parentMercId, beginTime, endTime);
+                List<MercDeviceAlgorithmChargingDto.PageByTopMercVO> deviceAgFeeList = deviceAgFeeByMerc == null ? null : deviceAgFeeByMerc.getRecords();
+                if (CollUtil.isNotEmpty(deviceAgFeeList)) {
+                    // 根据设备分组获取,每台设备缴费金额
+                    Map<Long, Integer> devicePayMoneyMap = deviceAgFeeList.stream()
+                            .collect(Collectors.groupingBy(MercDeviceAlgorithmChargingDto.PageByTopMercVO::getMercId,
+                                    Collectors.summingInt(MercDeviceAlgorithmChargingDto.PageByTopMercVO::getFeeBalance)));
+                    // 根据设备分组获取,每台设备佣金金额
+                    Map<Long, Integer> deviceAgentMoneyMap = deviceAgFeeList.stream()
+                            .collect(Collectors.groupingBy(MercDeviceAlgorithmChargingDto.PageByTopMercVO::getMercId,
+                                    Collectors.summingInt(MercDeviceAlgorithmChargingDto.PageByTopMercVO::getFee)));
+                    Set<Long> subMercIdSet = devicePayMoneyMap.keySet();
+                    for (Long mercId : subMercIdSet) {
+                        Integer payMoney = devicePayMoneyMap.get(mercId);
+                        Integer brokerage = deviceAgentMoneyMap.get(mercId);
+                        MercFeeCountDay deviceDayFee = new MercFeeCountDay();
+                        deviceDayFee.setFeeType(EnumMercFeeType.T3.getIntCode());
+                        deviceDayFee.setParentMercId(parentMercId);
+                        deviceDayFee.setDateValue(dateValue);
+                        deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
+                        deviceDayFee.setPayMoney(payMoney);
+                        deviceDayFee.setBrokerage(brokerage);
+                        deviceDayFee.setMercId(mercId);
+                        deviceDayFee.setParentMercId(parentMercId);
+                        saveMercFeeCountList.add(deviceDayFee);
+                    }
+                } else {
+                    // 没有费用的也要记录,为了前端收益概览的展示
+                    for (Long mercId : mercIds) {
+
+                        MercFeeCountDay deviceDayFee = new MercFeeCountDay();
+                        deviceDayFee.setFeeType(EnumMercFeeType.T3.getIntCode());
+                        deviceDayFee.setParentMercId(parentMercId);
+                        deviceDayFee.setDateValue(dateValue);
+                        deviceDayFee.setPayMoney(0);
+                        deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
+                        deviceDayFee.setBrokerage(0);
+                        deviceDayFee.setMercId(mercId);
+                        deviceDayFee.setParentMercId(parentMercId);
+                        saveMercFeeCountList.add(deviceDayFee);
+                    }
+                }
+
+            } else if (type == 4) {
+                //~~~~~~~~~~~~~4流量卡费
+                PageBean<DeviceSimChargeDto.PageByTopMercVO> simFeeByMerc = getSimFeeByMerc(parentMercId, beginTime, endTime);
+                List<DeviceSimChargeDto.PageByTopMercVO> simFeeList = simFeeByMerc == null ? null : simFeeByMerc.getRecords();
+                if (CollUtil.isNotEmpty(simFeeList)) {
+                    // 根据设备分组获取,每台设备缴费金额
+                    Map<Long, Integer> devicePayMoneyMap = simFeeList.stream()
+                            .collect(Collectors.groupingBy(DeviceSimChargeDto.PageByTopMercVO::getMercId,
+                                    Collectors.summingInt(DeviceSimChargeDto.PageByTopMercVO::getMoney)));
+                    // 根据设备分组获取,每台设备佣金金额
+                    Map<Long, Integer> deviceAgentMoneyMap = simFeeList.stream()
+                            .collect(Collectors.groupingBy(DeviceSimChargeDto.PageByTopMercVO::getMercId,
+                                    Collectors.summingInt(DeviceSimChargeDto.PageByTopMercVO::getAgentMoney)));
+                    Set<Long> subMercIdSet = devicePayMoneyMap.keySet();
+                    for (Long mercId : subMercIdSet) {
+                        Integer payMoney = devicePayMoneyMap.get(mercId);
+                        Integer brokerage = deviceAgentMoneyMap.get(mercId);
+                        MercFeeCountDay deviceDayFee = new MercFeeCountDay();
+                        deviceDayFee.setFeeType(EnumMercFeeType.T4.getIntCode());
+                        deviceDayFee.setParentMercId(parentMercId);
+                        deviceDayFee.setDateValue(dateValue);
+                        deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
+                        deviceDayFee.setPayMoney(payMoney);
+                        deviceDayFee.setBrokerage(brokerage);
+                        deviceDayFee.setMercId(mercId);
+                        deviceDayFee.setParentMercId(parentMercId);
+                        saveMercFeeCountList.add(deviceDayFee);
+                    }
+                } else {
+                    // 没有费用的也要记录,为了前端收益概览的展示
+                    for (Long mercId : mercIds) {
+
+                        MercFeeCountDay deviceDayFee = new MercFeeCountDay();
+                        deviceDayFee.setFeeType(EnumMercFeeType.T4.getIntCode());
+                        deviceDayFee.setParentMercId(parentMercId);
+                        deviceDayFee.setDateValue(dateValue);
+                        deviceDayFee.setPayMoney(0);
+                        deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
+                        deviceDayFee.setBrokerage(0);
+                        deviceDayFee.setMercId(mercId);
+                        deviceDayFee.setParentMercId(parentMercId);
+                        saveMercFeeCountList.add(deviceDayFee);
+                    }
+                }
+
+            }
+        }
+        return R.ok(saveMercFeeCountList);
+    }
+
 
     @PostMapping("excuteJob")
     @ApiOperation("指定日期执行")
@@ -89,7 +305,7 @@ public class MercFeeCountDayJob {
         if (StrUtil.isNotEmpty(date)) {
             queryDay = date;
 
-            //指定日期需要判断是否重复执行
+            // 指定日期需要判断是否重复执行
             MercFeeCountDayDto.SelectList selectList = new MercFeeCountDayDto.SelectList();
             selectList.setDateValue(Integer.valueOf(queryDay));
             List<MercFeeCountDayDto.Vo> vos = R.feignCheckData(mercFeeCountDayService.list(selectList));
@@ -116,18 +332,18 @@ public class MercFeeCountDayJob {
             Long parentMercId = merc.getId();
             List<Long> mercIds = R.feignCheckData(mercService.getChildMercIds(new MercDto.QuerySubDTO().setParentMercID(parentMercId)));
             if (CollUtil.isEmpty(mercIds)) {
-                //子商户都没有,就不用查分佣收益了
+                // 子商户都没有,就不用查分佣收益了
                 continue;
             }
             //~~~~~~~~~~~~~1设备管理费
             PageBean<DeviceChargingHistoryDto.PageVo> pageVoPageBean = getDeviceManagerFeeMerc(parentMercId, beginTime, endTime);
             List<DeviceChargingHistoryDto.PageVo> records = pageVoPageBean == null ? null : pageVoPageBean.getRecords();
             if (CollUtil.isNotEmpty(records)) {
-                //根据设备分组获取,每台设备缴费金额
+                // 根据设备分组获取,每台设备缴费金额
                 Map<Long, Integer> devicePayMoneyMap = records.stream()
                         .collect(Collectors.groupingBy(DeviceChargingHistoryDto.PageVo::getMercId,
                                 Collectors.summingInt(DeviceChargingHistoryDto.PageVo::getChargingMoney)));
-                //根据设备分组获取,每台设备佣金金额
+                // 根据设备分组获取,每台设备佣金金额
                 Map<Long, Integer> deviceAgentMoneyMap = records.stream()
                         .collect(Collectors.groupingBy(DeviceChargingHistoryDto.PageVo::getMercId,
                                 Collectors.summingInt(DeviceChargingHistoryDto.PageVo::getAgentMoney)));
@@ -149,7 +365,7 @@ public class MercFeeCountDayJob {
                 }
                 mercFeeCountDayService.saveBatch(saveMercFeeCountList);
             } else {
-                //没有费用的也要记录,为了前端收益概览的展示
+                // 没有费用的也要记录,为了前端收益概览的展示
                 List<MercFeeCountDay> saveMercFeeCountList = new ArrayList<>();
                 for (Long mercId : mercIds) {
 
@@ -173,11 +389,11 @@ public class MercFeeCountDayJob {
             PageBean<DeviceAlgorithmChargingHistoryDto.PageByTopMercVO> deviceActiveFeeByMerc = getDeviceActiveFeeByMerc(parentMercId, beginTime, endTime);
             List<DeviceAlgorithmChargingHistoryDto.PageByTopMercVO> deviceActiveFeeList = deviceActiveFeeByMerc == null ? null : deviceActiveFeeByMerc.getRecords();
             if (CollUtil.isNotEmpty(deviceActiveFeeList)) {
-                //根据设备分组获取,每台设备缴费金额
+                // 根据设备分组获取,每台设备缴费金额
                 Map<Long, Integer> devicePayMoneyMap = deviceActiveFeeList.stream()
                         .collect(Collectors.groupingBy(DeviceAlgorithmChargingHistoryDto.PageByTopMercVO::getMercId,
                                 Collectors.summingInt(DeviceAlgorithmChargingHistoryDto.PageByTopMercVO::getChargingMoney)));
-                //根据设备分组获取,每台设备佣金金额
+                // 根据设备分组获取,每台设备佣金金额
                 Map<Long, Integer> deviceAgentMoneyMap = deviceActiveFeeList.stream()
                         .collect(Collectors.groupingBy(DeviceAlgorithmChargingHistoryDto.PageByTopMercVO::getMercId,
                                 Collectors.summingInt(DeviceAlgorithmChargingHistoryDto.PageByTopMercVO::getAgentMoney)));
@@ -199,7 +415,7 @@ public class MercFeeCountDayJob {
                 }
                 mercFeeCountDayService.saveBatch(saveMercFeeCountList);
             } else {
-                //没有费用的也要记录,为了前端收益概览的展示
+                // 没有费用的也要记录,为了前端收益概览的展示
                 List<MercFeeCountDay> saveMercFeeCountList = new ArrayList<>();
                 for (Long mercId : mercIds) {
 
@@ -223,14 +439,14 @@ public class MercFeeCountDayJob {
             PageBean<MercDeviceAlgorithmChargingDto.PageByTopMercVO> deviceAgFeeByMerc = getDeviceAgFeeByMerc(parentMercId, beginTime, endTime);
             List<MercDeviceAlgorithmChargingDto.PageByTopMercVO> deviceAgFeeList = deviceAgFeeByMerc == null ? null : deviceAgFeeByMerc.getRecords();
             if (CollUtil.isNotEmpty(deviceAgFeeList)) {
-                //根据设备分组获取,每台设备缴费金额
+                // 根据设备分组获取,每台设备缴费金额
                 Map<Long, Integer> devicePayMoneyMap = deviceAgFeeList.stream()
                         .collect(Collectors.groupingBy(MercDeviceAlgorithmChargingDto.PageByTopMercVO::getMercId,
                                 Collectors.summingInt(MercDeviceAlgorithmChargingDto.PageByTopMercVO::getFeeBalance)));
-                //根据设备分组获取,每台设备佣金金额
+                // 根据设备分组获取,每台设备佣金金额
                 Map<Long, Integer> deviceAgentMoneyMap = deviceAgFeeList.stream()
                         .collect(Collectors.groupingBy(MercDeviceAlgorithmChargingDto.PageByTopMercVO::getMercId,
-                                Collectors.summingInt(MercDeviceAlgorithmChargingDto.PageByTopMercVO::getAgentMoney)));
+                                Collectors.summingInt(MercDeviceAlgorithmChargingDto.PageByTopMercVO::getFee)));
                 Set<Long> subMercIdSet = devicePayMoneyMap.keySet();
                 List<MercFeeCountDay> saveMercFeeCountList = new ArrayList<>();
                 for (Long mercId : subMercIdSet) {
@@ -240,6 +456,7 @@ public class MercFeeCountDayJob {
                     deviceDayFee.setFeeType(EnumMercFeeType.T3.getIntCode());
                     deviceDayFee.setParentMercId(parentMercId);
                     deviceDayFee.setDateValue(dateValue);
+                    deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
                     deviceDayFee.setPayMoney(payMoney);
                     deviceDayFee.setBrokerage(brokerage);
                     deviceDayFee.setMercId(mercId);
@@ -248,7 +465,7 @@ public class MercFeeCountDayJob {
                 }
                 mercFeeCountDayService.saveBatch(saveMercFeeCountList);
             } else {
-                //没有费用的也要记录,为了前端收益概览的展示
+                // 没有费用的也要记录,为了前端收益概览的展示
                 List<MercFeeCountDay> saveMercFeeCountList = new ArrayList<>();
                 for (Long mercId : mercIds) {
 
@@ -271,11 +488,11 @@ public class MercFeeCountDayJob {
             PageBean<DeviceSimChargeDto.PageByTopMercVO> simFeeByMerc = getSimFeeByMerc(parentMercId, beginTime, endTime);
             List<DeviceSimChargeDto.PageByTopMercVO> simFeeList = simFeeByMerc == null ? null : simFeeByMerc.getRecords();
             if (CollUtil.isNotEmpty(simFeeList)) {
-                //根据设备分组获取,每台设备缴费金额
+                // 根据设备分组获取,每台设备缴费金额
                 Map<Long, Integer> devicePayMoneyMap = simFeeList.stream()
                         .collect(Collectors.groupingBy(DeviceSimChargeDto.PageByTopMercVO::getMercId,
                                 Collectors.summingInt(DeviceSimChargeDto.PageByTopMercVO::getMoney)));
-                //根据设备分组获取,每台设备佣金金额
+                // 根据设备分组获取,每台设备佣金金额
                 Map<Long, Integer> deviceAgentMoneyMap = simFeeList.stream()
                         .collect(Collectors.groupingBy(DeviceSimChargeDto.PageByTopMercVO::getMercId,
                                 Collectors.summingInt(DeviceSimChargeDto.PageByTopMercVO::getAgentMoney)));
@@ -288,6 +505,7 @@ public class MercFeeCountDayJob {
                     deviceDayFee.setFeeType(EnumMercFeeType.T4.getIntCode());
                     deviceDayFee.setParentMercId(parentMercId);
                     deviceDayFee.setDateValue(dateValue);
+                    deviceDayFee.setMonthValue(Integer.valueOf(monthValue));
                     deviceDayFee.setPayMoney(payMoney);
                     deviceDayFee.setBrokerage(brokerage);
                     deviceDayFee.setMercId(mercId);
@@ -296,7 +514,7 @@ public class MercFeeCountDayJob {
                 }
                 mercFeeCountDayService.saveBatch(saveMercFeeCountList);
             } else {
-                //没有费用的也要记录,为了前端收益概览的展示
+                // 没有费用的也要记录,为了前端收益概览的展示
                 List<MercFeeCountDay> saveMercFeeCountList = new ArrayList<>();
                 for (Long mercId : mercIds) {
 

+ 114 - 0
device-api-service/src/main/java/com/xy/open/DeviceOpenApiService.java

@@ -0,0 +1,114 @@
+package com.xy.open;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.json.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.xy.annotate.RestMappingController;
+import com.xy.annotation.Open;
+import com.xy.bean.OpenContext;
+import com.xy.bean.ServiceContext;
+import com.xy.dto.CommandMqtt;
+import com.xy.dto.OpenPlatformConfigDto;
+import com.xy.entity.DeviceInfo;
+import com.xy.exception.ServiceException;
+import com.xy.open.dto.DeviceOpenApiDTO;
+import com.xy.open.vo.DeviceOpenApiVO;
+import com.xy.service.DeviceInfoServiceImpl;
+import com.xy.service.MqttService;
+import com.xy.service.OpenPlatformConfigService;
+import com.xy.utils.PageBean;
+import com.xy.utils.R;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.xy.utils.PlusBeans.toIPage;
+import static com.xy.utils.PlusBeans.toPageBean;
+
+/**
+ * 开放api
+ */
+
+@Slf4j
+@Service
+@Api(tags = "设备API")
+@RequiredArgsConstructor
+@RestMappingController("/openApi")
+public class DeviceOpenApiService {
+
+    private final DeviceInfoServiceImpl deviceInfoService;
+    private final OpenPlatformConfigService openPlatformConfigService;
+    private final MqttService mqttService;
+
+
+    @ApiOperation(value = "获取商户设备列表", notes = "获取商户设备列表")
+    @Open(value = "device.page.get", version = "1.0", permission = true)
+    @PostMapping("/device/page/get")
+    public PageBean<DeviceOpenApiVO.DeviceList> devicePageGet(@RequestBody @Valid DeviceOpenApiDTO.DeviceListGet dto) {
+        OpenContext oct = ServiceContext.getCurrentContext().getOpenContext();
+        String appId = oct.getAppId();
+        boolean b = R.feignCheckData(openPlatformConfigService.checkAuthByMercCode(new OpenPlatformConfigDto.CheckAuth().setAppId(appId).setMercCodes(dto.getMercCodes())));
+        if (!b) {
+            throw new ServiceException("您传入的商户编码中包含非法编码!");
+        }
+        PageBean pageBean = dto.getPage();
+        LambdaQueryWrapper<DeviceInfo> lqw = Wrappers.<DeviceInfo>lambdaQuery()
+                .in(DeviceInfo::getMercCode, dto.getMercCodes()
+                );
+        IPage<DeviceInfo> iPage = deviceInfoService.page(toIPage(pageBean), lqw);
+        return toPageBean(DeviceOpenApiVO.DeviceList.class, iPage);
+    }
+
+    @ApiOperation(value = "设备操作", notes = "设备操作(开打印机门锁:openPrinterLock)")
+    @Open(value = "device.operate", version = "1.0", permission = true)
+    @PostMapping("/device/operate")
+    public DeviceOpenApiDTO.DeviceOperateResult deviceOperate(@RequestBody @Valid DeviceOpenApiDTO.DeviceOperate dto) {
+        DeviceOpenApiDTO.DeviceOperateResult result = new DeviceOpenApiDTO.DeviceOperateResult();
+        OpenContext oct = ServiceContext.getCurrentContext().getOpenContext();
+        String appId = oct.getAppId();
+        List<Long> mercIds = R.feignCheckData(openPlatformConfigService.getMercIdsByAppId(new OpenPlatformConfigDto.QueryByApp().setAppId(appId)));
+        if (CollUtil.isEmpty(mercIds)) {
+            throw new ServiceException("尚未分配商户,请联系平台客服!");
+        }
+        Long deviceId = dto.getDeviceId();
+        DeviceInfo deviceInfo = deviceInfoService.getById(deviceId);
+        if (deviceInfo == null) {
+            throw new ServiceException("设备不存在!");
+        }
+        if (!CollUtil.contains(mercIds, deviceInfo.getMercId())) {
+            throw new ServiceException("您没有权限操作该设备!");
+        }
+        String action = dto.getAction();
+        if ("openPrinterLock".equals(action)) {
+            action = "locker";
+        } else {
+            throw new ServiceException("未知或不支持的操作类型!");
+        }
+        List<CommandMqtt> commandMqtts = new ArrayList<>();
+        JSONObject templet = new JSONObject();
+        templet.putOnce("wkSn", "$wkSn$");
+        templet.putOnce("cmdType", "task");
+        templet.putOnce("actionType", "issue");
+        JSONObject data = new JSONObject();
+        data.putOnce("type", action);
+        data.putOnce("id", "0");
+        data.putOnce("jgh", "1");
+        data.putOnce("task", "open");
+        templet.putOnce("data", data);
+        commandMqtts.add(new CommandMqtt().setDeviceId(deviceId).setTemplet(templet));
+        mqttService.senCommand(commandMqtts);
+        result.setResult(true);
+        return result;
+    }
+
+}

+ 42 - 0
device-api-service/src/main/java/com/xy/open/config/OpenServiceConfig.java

@@ -0,0 +1,42 @@
+package com.xy.open.config;
+
+
+import com.xy.bean.ServiceConfig;
+import com.xy.configuration.AlipayServiceConfiguration;
+import com.xy.swagger.SwaggerSupport;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
+
+/**
+ * 开放平台功能
+ *
+ * @author tanghc
+ */
+@Configuration
+public class OpenServiceConfig extends AlipayServiceConfiguration {
+
+    static {
+        ServiceConfig.getInstance().getI18nModules().add("i18n/isp/goods_error");
+    }
+
+
+    /**
+     * 开启文档,本地微服务文档地址:http://localhost:2222/doc.html
+     * http://ip:port/v2/api-docs
+     */
+    @Configuration
+    @EnableSwagger2WebMvc
+    public static class Swagger2 extends SwaggerSupport {
+        @Override
+        protected String getDocTitle() {
+            return "智能货柜-设备接口文档";
+        }
+
+        @Override
+        protected boolean swaggerAccessProtected() {
+            return false;
+        }
+    }
+
+}
+

+ 59 - 0
device-api-service/src/main/java/com/xy/open/dto/DeviceOpenApiDTO.java

@@ -0,0 +1,59 @@
+package com.xy.open.dto;
+
+import com.xy.utils.PageBean;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 设备DTO
+ */
+public class DeviceOpenApiDTO {
+
+    /**
+     * 根据商户编码获取商户设备列表
+     */
+    @Data
+    @Accessors(chain = true)
+    public static class DeviceListGet {
+        @NotNull(message = "分页对象不可为空")
+        @ApiModelProperty(value = "分页对象", required = true)
+        private PageBean page;
+
+        @NotEmpty(message = "商户编码不可为空")
+        @ApiModelProperty(value = "商户编码", required = true)
+        private List<String> mercCodes;
+
+    }
+
+    @Data
+    @Accessors(chain = true)
+    public static class DeviceOperate {
+        @NotNull(message = "设备ID")
+        @ApiModelProperty(value = "设备ID", required = true)
+        private Long deviceId;
+
+
+        @NotNull(message = "操作类型")
+        @ApiModelProperty(value = "操作类型(开打印机门锁:openPrinterLock)", required = true)
+        private String action;
+
+
+    }
+
+
+    @Data
+    @Accessors(chain = true)
+    public static class DeviceOperateResult {
+        @ApiModelProperty(value = "请求结果(成功:true,失败:false)")
+        private Boolean result;
+
+
+    }
+
+
+}

+ 56 - 0
device-api-service/src/main/java/com/xy/open/vo/DeviceOpenApiVO.java

@@ -0,0 +1,56 @@
+package com.xy.open.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.time.LocalDateTime;
+
+/**
+ * 设备VO
+ */
+public class DeviceOpenApiVO {
+
+    @Data
+    @Accessors(chain = true)
+    public static class DeviceList {
+
+        @ApiModelProperty(value = "商户编码")
+        private String mercCode;
+
+
+        @ApiModelProperty(value = "商户ID")
+        private String mercId;
+
+        @ApiModelProperty(value = "设备编号")
+        private Long deviceId;
+
+        @ApiModelProperty(value = "设备名称")
+        private String deviceName;
+
+        @ApiModelProperty(value = "算法平台ID->1:旷世算法 2:云从算法 3:支付宝算法 4:拓元算法 5:商汤算法")
+        private Long algorithmId;
+
+        @ApiModelProperty(value = "设备类型-> 1: 动态视觉柜(单门) 2: 动态视觉柜(双门) 3: 重力柜(单门) 4:重力柜(双门) 5:支付宝视动态觉柜")
+        private Integer deviceType;
+
+
+        @ApiModelProperty(value = "经度")
+        private String lon;
+
+        @ApiModelProperty(value = "纬度")
+        private String lat;
+
+        @ApiModelProperty(value = "激活状态->1: 已激活 2: 未激活")
+        private Integer activeState;
+
+        @ApiModelProperty("激活时间")
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        private LocalDateTime activeTime;
+
+
+    }
+
+
+}

+ 12 - 8
device-api-service/src/main/java/com/xy/service/DeviceConfigServiceImpl.java

@@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
 import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -54,14 +55,17 @@ public class DeviceConfigServiceImpl extends ServiceImpl<DeviceConfigMapper, Dev
     @ApiOperation("批量更新")
     public R batchUpdate(@RequestBody @Validated DeviceConfigDto.BatchUpdate batchUpdate) {
         List<Long> deviceIds = batchUpdate.getDeviceIds();
-        List<DeviceConfig> deviceConfigs = this.listByIds(deviceIds);
-        if (CollUtil.isNotEmpty(deviceConfigs)) {
-            deviceConfigs.forEach(d -> {
-                d.setTempMin(batchUpdate.getTempMin());
-                d.setTempMax(batchUpdate.getTempMax());
-                d.setStockOutGoodsNum(batchUpdate.getStockOutGoodsNum());
-                d.setStockOutRate(batchUpdate.getStockOutRate());
-                d.setUpdateTime(LocalDateTime.now());
+        List<DeviceConfig> deviceConfigs = new ArrayList<>();
+        if (CollUtil.isNotEmpty(deviceIds)) {
+            deviceIds.forEach(d -> {
+                DeviceConfig deviceConfig = new DeviceConfig();
+                deviceConfig.setDeviceId(d);
+                deviceConfig.setTempMin(batchUpdate.getTempMin());
+                deviceConfig.setTempMax(batchUpdate.getTempMax());
+                deviceConfig.setStockOutGoodsNum(batchUpdate.getStockOutGoodsNum());
+                deviceConfig.setStockOutRate(batchUpdate.getStockOutRate());
+                deviceConfig.setUpdateTime(LocalDateTime.now());
+                deviceConfigs.add(deviceConfig);
             });
             this.saveOrUpdateBatch(deviceConfigs);
         }

+ 1 - 2
device-api-service/src/main/java/com/xy/service/DeviceSetRecordsServiceImpl.java

@@ -41,7 +41,7 @@ public class DeviceSetRecordsServiceImpl extends ServiceImpl<DeviceSetRecordsMap
 
     @PostMapping("lastOne")
     @ApiOperation("返显最后一条记录")
-    public R lastOne(@RequestBody DeviceSetRecordsDto.LastOneDto dto) {
+    public R<List<DeviceSetRecordsDto.LastOneVo>> lastOne(@RequestBody DeviceSetRecordsDto.LastOneDto dto) {
         List<DeviceSetRecordsDto.LastOneVo> voList = new ArrayList<>();
         dto.getTypeList().forEach(type -> {
             LambdaQueryWrapper<DeviceSetRecords> lqw = new LambdaQueryWrapper<DeviceSetRecords>()
@@ -56,7 +56,6 @@ public class DeviceSetRecordsServiceImpl extends ServiceImpl<DeviceSetRecordsMap
                         .setContent(one.getContent());
                 voList.add(vo);
             }
-
         });
         return R.ok(voList);
     }

+ 73 - 29
device-api-service/src/main/java/com/xy/service/factory/device/impl/alipay/AliPayOpenDeviceFatoryImpl.java

@@ -13,10 +13,7 @@ import com.xy.config.DeviceThreadPoolConfig;
 import com.xy.constants.SpiResponseConst;
 import com.xy.device.EnumDeviceOnlineStatus;
 import com.xy.dto.*;
-import com.xy.dto.spi.DeviceAlarmNotifyDTO;
-import com.xy.dto.spi.DeviceAttributesNotifyDTO;
-import com.xy.dto.spi.DeviceSetAttributesNotifyDTO;
-import com.xy.dto.spi.DeviceStatusChangeNotifyDTO;
+import com.xy.dto.spi.*;
 import com.xy.entity.DeviceInfo;
 import com.xy.entity.DeviceStatus;
 import com.xy.service.*;
@@ -32,6 +29,10 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.Arrays;
 import java.util.List;
 
@@ -60,6 +61,8 @@ public class AliPayOpenDeviceFatoryImpl implements DeviceFactory, SpiDeviceServi
 
     private DeviceTempSetServiceImpl deviceTempSetService;
 
+    private DeviceSetRecordsServiceImpl deviceSetRecordsService;
+
     @Override
     public R save(DeviceRegisterDto.Save save) {
         R r = openDeviceFactoryImpl.save(save);
@@ -132,37 +135,38 @@ public class AliPayOpenDeviceFatoryImpl implements DeviceFactory, SpiDeviceServi
                     //声音设置
                     Integer value = data.getInt("alound");
                     alipayDeviceService.setAttributes(new DeviceSetAttr().setTerminalId(terminalId).setType("VOL").setValue(String.valueOf(value)));
+                    DeviceSetRecordsDto.Save save = new DeviceSetRecordsDto.Save();
+                    save.setType("voice")
+                            .setDeviceId(commandMqtt.getDeviceId())
+                            .setContent(data.toString());
+                    deviceSetRecordsService.save(save);
                 } else if (data.getStr("type").equals("temperature")) {
                     //温度设置
                     Integer value = data.getInt("target");
                     alipayDeviceService.setAttributes(new DeviceSetAttr().setTerminalId(terminalId).setType("TEMP").setValue(String.valueOf(value)));
                     //写入记录
-                    try {
-                        DeviceTempSetDto.Save save = new DeviceTempSetDto.Save()
-                                .setDeviceId(commandMqtt.getDeviceId())
-                                .setWorkMode(data.getStr("workModel"))
-                                .setTempValue(data.getInt("target"))
-                                .setTempValue1(data.getInt("target1"))
-                                .setTempValue2(data.getInt("target2"))
-                                .setTempValue3(data.getInt("target3"))
-                                .setJob1StartTime(data.getInt("start1"))
-                                .setJob1EndTime(data.getInt("end1"))
-                                .setJob2StartTime(data.getInt("start2"))
-                                .setJob2EndTime(data.getInt("end2"))
-                                .setJob3StartTime(data.getInt("start3"))
-                                .setJob3EndTime(data.getInt("end3"));
-                        String warningLow = data.getStr("warningLow");
-                        String warningHigh = data.getStr("warningHigh");
-                        if (!warningLow.equals("$warningLow$")) {
-                            save.setWarningLow(Integer.valueOf(warningLow));
-                        }
-                        if (!warningHigh.equals("$warningHigh$")) {
-                            save.setWarningHigh(Integer.valueOf(warningHigh));
-                        }
-                        deviceTempSetService.save(save);
-                    } catch (Exception e) {
-                        log.error("异常{}", templet);
+                    DeviceTempSetDto.Save save = new DeviceTempSetDto.Save()
+                            .setDeviceId(commandMqtt.getDeviceId())
+                            .setWorkMode(data.getStr("workModel"))
+                            .setTempValue(data.getInt("target"))
+                            .setTempValue1(data.getInt("target1"))
+                            .setTempValue2(data.getInt("target2"))
+                            .setTempValue3(data.getInt("target3"))
+                            .setJob1StartTime(data.getInt("start1"))
+                            .setJob1EndTime(data.getInt("end1"))
+                            .setJob2StartTime(data.getInt("start2"))
+                            .setJob2EndTime(data.getInt("end2"))
+                            .setJob3StartTime(data.getInt("start3"))
+                            .setJob3EndTime(data.getInt("end3"));
+                    String warningLow = data.getStr("warningLow");
+                    String warningHigh = data.getStr("warningHigh");
+                    if (!warningLow.equals("$warningLow$")) {
+                        save.setWarningLow(Integer.valueOf(warningLow));
+                    }
+                    if (!warningHigh.equals("$warningHigh$")) {
+                        save.setWarningHigh(Integer.valueOf(warningHigh));
                     }
+                    deviceTempSetService.save(save);
                 }
             }
         });
@@ -223,6 +227,46 @@ public class AliPayOpenDeviceFatoryImpl implements DeviceFactory, SpiDeviceServi
         return SpiResponseConst.SUCCESS;
     }
 
+    @ApiOperation("设备异常通知SPI")
+    @Override
+    public String deviceExceptionNotify(DeviceExceptionNotifyDTO deviceExceptionNotifyDTO) {
+        String terminalId = deviceExceptionNotifyDTO.getTerminalId();
+        String action = deviceExceptionNotifyDTO.getAction();
+        String exceptionDesc = deviceExceptionNotifyDTO.getExceptionDesc();
+        //triggerTime 示例 1551156574510
+        Long triggerTime = deviceExceptionNotifyDTO.getTriggerTime();
+        LocalDateTime triggerDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(triggerTime), ZoneId.systemDefault());
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        String formattedDateTime = triggerDateTime.format(formatter);
+        String devCode = "";
+        if ("恢复".equals(action)) {
+            if (exceptionDesc.contains("重力")) {
+                devCode = "DEV6004";
+            } else if (exceptionDesc.contains("摄像头")) {
+                devCode = "DEV6001";
+            }
+        } else if ("故障".equals(action)) {
+            if (exceptionDesc.contains("重力")) {
+                devCode = "DEV6003";
+            } else if (exceptionDesc.contains("摄像头")) {
+                devCode = "DEV6000";
+            }
+        }
+
+        if (StrUtil.isEmpty(devCode)) {
+            log.error("设备异常通知SPI->未知的异常类型:{}", JSONUtil.toJsonPrettyStr(deviceExceptionNotifyDTO));
+            return SpiResponseConst.FAIL;
+        }
+        //添加设备异常记录
+        DeviceEventMsgDto.Save save = new DeviceEventMsgDto.Save()
+                .setDeviceId(Long.valueOf(terminalId));
+        save.setCode(devCode);
+        save.setMsg(exceptionDesc + ";发生时间:" + formattedDateTime);
+        deviceEventMsgService.save(save);
+
+        return SpiResponseConst.SUCCESS;
+    }
+
     @Override
     @ApiOperation("设备状态变更通知SPI")
     public String deviceStatusChangeNotify(DeviceStatusChangeNotifyDTO deviceStatusChangeNotifyDTO) {

+ 4 - 1
device-api-service/src/main/resources/mapper/DeviceInfoMapper.xml

@@ -98,7 +98,7 @@
     </resultMap>
 
     <select id="listByAdminName" resultType="com.xy.dto.DeviceInfoDto$ListByAdminName">
-        SELECT d.device_id, d.device_name, p.admin_name, d.device_type
+        SELECT d.device_id, d.device_name, p.admin_name, d.device_type,d.algorithm_id
         FROM device_info d
         left join merc_place p on p.id = d.place_id
         <where>
@@ -113,6 +113,9 @@
             <if test="dto.searchKey != null and dto.searchKey != ''">
                 and CONCAT(IFNULL(d.device_name, ''), IFNULL(p.admin_name, '')) like CONCAT('%', #{dto.searchKey}, '%')
             </if>
+            <if test="dto.algorithmId != null">
+                and d.algorithm_id = #{dto.algorithmId}
+            </if>
         </where>
     </select>
 

+ 12 - 4
device-api/src/main/java/com/xy/alipay/SpiDeviceService.java

@@ -1,10 +1,7 @@
 package com.xy.alipay;
 
 import com.xy.annotate.RestMappingController;
-import com.xy.dto.spi.DeviceAlarmNotifyDTO;
-import com.xy.dto.spi.DeviceAttributesNotifyDTO;
-import com.xy.dto.spi.DeviceSetAttributesNotifyDTO;
-import com.xy.dto.spi.DeviceStatusChangeNotifyDTO;
+import com.xy.dto.spi.*;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
@@ -30,6 +27,17 @@ public interface SpiDeviceService {
     @PostMapping(value = "/faultInform/notify")
     String deviceAlarmNotify(@RequestBody DeviceAlarmNotifyDTO deviceAlarmNotifyDTO);
 
+    /**
+     * 设备异常通知
+     * 触发条件:动态设备发生重力异常或者摄像头异常,影响到该设备交易的正常识别时,会通过该通知同步到商户
+     * 使用场景:接收设备恢复,进行相应业务处理和任务触发
+     *
+     * @param deviceExceptionNotifyDTO
+     * @return
+     */
+    @PostMapping(value = "/deviceException/notify")
+    String deviceExceptionNotify(@RequestBody DeviceExceptionNotifyDTO deviceExceptionNotifyDTO);
+
     /**
      * 设备状态变更通知
      * 触发条件:设备激活状态或运营状态发生变化时

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

@@ -159,6 +159,9 @@ public class DeviceInfoDto {
 
         @ApiModelProperty(value = "设备名/设备ID/管理员名")
         private String searchKey;
+
+        @ApiModelProperty("算法ID")
+        private Long algorithmId;
     }
 
 
@@ -212,6 +215,9 @@ public class DeviceInfoDto {
 
         @ApiModelProperty("商户编号")
         private String mercCode;
+
+        @ApiModelProperty("算法ID")
+        private Long algorithmId;
     }
 
 
@@ -699,6 +705,9 @@ public class DeviceInfoDto {
         @ApiModelProperty("第三方设备审核结果")
         private String thirdResult;
 
+        @ApiModelProperty("设备配置")
+        private DeviceConfigDto.Vo deviceConfig;
+
     }
 
     @Data

+ 1 - 0
device-api/src/main/java/com/xy/dto/MercFeeCountDayDto.java

@@ -25,6 +25,7 @@ public class MercFeeCountDayDto {
         @NotBlank(message = "日期不可为空yyyyMMdd")
         @ApiModelProperty(value = "分页对象", required = true)
         private String date;
+        private Integer type;
     }
 
     @Data

+ 10 - 0
device-start/src/main/resources/i18n/isp/bizerror_en.properties

@@ -0,0 +1,10 @@
+# 错误配置
+
+# 系统配置
+isp.error_isv.common-error=The system is busy.
+isp.error_isv.invalid-parameter=Invalid parameter, {0}
+
+# ==== 参数配置 ====
+
+goods.remark.notNull=The goods_remark can not be null
+goods.comment.length=The goods_comment length must >= {0} and <= {1}

+ 14 - 0
device-start/src/main/resources/i18n/isp/bizerror_zh_CN.properties

@@ -0,0 +1,14 @@
+# 错误配置
+
+# 系统繁忙
+isp.error_isv.common-error=\u7cfb\u7edf\u7e41\u5fd9
+# 参数无效
+isp.error_isv.invalid-parameter=\u53c2\u6570\u65e0\u6548, {0}
+
+# ==== 参数配置 ====
+
+# 商品备注不能为空
+goods.remark.notNull=\u5546\u54c1\u5907\u6ce8\u4e0d\u80fd\u4e3a\u7a7a
+# 商品评论长度必须在{0}和{1}之间
+goods.comment.length=\u5546\u54c1\u8bc4\u8bba\u957f\u5ea6\u5fc5\u987b\u5728{0}\u548c{1}\u4e4b\u95f4
+

+ 2 - 0
device-start/src/main/resources/i18n/isp/goods_error_en.properties

@@ -0,0 +1,2 @@
+isp.goods_error_100=the goods_name can NOT be null
+isp.goods_error_101=the goods_name must bigger than {0}

+ 5 - 0
device-start/src/main/resources/i18n/isp/goods_error_zh_CN.properties

@@ -0,0 +1,5 @@
+# 商品名字不能为空
+isp.goods_error_100=\u5546\u54C1\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A
+
+# 商品名称太短,不能小于{0}个字
+isp.goods_error_101=\u5546\u54C1\u540D\u79F0\u592A\u77ED\uFF0C\u4E0D\u80FD\u5C0F\u4E8E{0}\u4E2A\u5B57