From a8ac9d91dbd4493112030f8f3d4c9a13fcb0bfc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=BE=E5=AF=8C=E6=96=8C?= Date: Fri, 26 Sep 2025 21:40:55 +0800 Subject: [PATCH] =?UTF-8?q?feat=20(farm):=20=E8=AE=BE=E5=A4=87=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5,=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构设备接口 - 修复部分bug --- Readme.md | 13 +- .../controller/admin/api/ApiController.java | 2 +- .../api/vo/FarmBaseAndDeviceInfoReqVO.java | 3 + .../admin/api/vo/FarmBaseInfoReqVO.java | 3 + .../controller/admin/wx/WxController.java | 106 ++++- .../admin/wx/vo/DeviceInfoRespVO.java | 54 ++- .../mysql/deviceinfo/DeviceInfoMapper.java | 2 +- .../farm/manager/devices/DeviceManager.java | 143 ++++--- .../manager/devices/commons/DeviceConst.java | 174 +++++---- .../farm/manager/devices/conf/DeviceConf.java | 92 ++--- .../devices/conf/SchedulingConfig.java | 4 +- .../manager/devices/soil/SoilService.java | 350 ++++++++--------- .../devices/wf/WaterFertilizerService.java | 90 ----- .../devices/wf/dto/DevicePageReqVO.java | 24 ++ .../EquipmentProducerManager.java | 78 ++++ .../commons/DeviceConst.java | 105 +++++ .../equipmentproducer/conf/DeviceConf.java | 62 +++ .../conf/SchedulingConfig.java | 15 + .../dto/DeviceListResponse.java | 30 ++ .../dto/HistoryDataResponse.java | 31 ++ .../dto/RealTimeDataResponse.java | 27 ++ .../dto/UnifiedLoginResponse.java | 38 ++ .../dto/UpdateDeviceResponse.java | 31 ++ .../soil/devicelist/SysUserDeviceReqVO.java | 24 ++ .../soil/devicelist/SysUserDeviceRespVO.java | 55 +++ .../history/HistoryDataListPageReqVO.java | 108 +++++ .../history/HistoryDataListPageRespVO.java | 62 +++ .../dto/soil/login/UserLoginReqVO.java | 18 + .../dto/soil/login/UserLoginRespVO.java | 43 ++ .../dto/soil/realtime/RealTimeDataReqVO.java | 21 + .../dto/soil/realtime/RealTimeDataRespVO.java | 79 ++++ .../dto/wf/devicelist/DevicePageReqVO.java | 24 ++ .../dto/wf/devicelist/DevicePageRespVO.java | 51 +++ .../dto/wf/login/LoginReqVO.java | 18 + .../dto/wf/login/LoginRespVO.java | 19 + .../wf/realtime/RealTimeDeviceDataReqVO.java | 22 ++ .../wf/realtime/RealTimeDeviceDataRespVO.java | 35 ++ .../updateparams/UpdateDeviceStatusReqVO.java | 28 ++ .../UpdateDeviceStatusRespVO.java | 18 + .../service/AbstractDeviceService.java | 161 ++++++++ .../service/DeviceService.java | 39 ++ .../service/HistoryDataStorageService.java | 75 ++++ .../service/TokenCacheService.java | 140 +++++++ .../service/impl/SoilService.java | 368 ++++++++++++++++++ .../service/impl/WaterFertilizerService.java | 332 ++++++++++++++++ .../service/baseinfo/BaseInfoServiceImpl.java | 1 + .../service/deviceinfo/DeviceInfoService.java | 5 + .../deviceinfo/DeviceInfoServiceImpl.java | 34 +- .../farm/service/home/HomeServiceImpl.java | 2 +- .../productionplan/ProductionPlanService.java | 28 +- .../ProductionPlanServiceImpl.java | 11 + .../mapper/deviceinfo/DeviceInfoMapper.xml | 11 +- .../farmingrecord/FarmingRecordMapper.xml | 6 +- .../productionplan/ProductionPlanMapper.xml | 1 + 54 files changed, 2802 insertions(+), 514 deletions(-) delete mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/wf/WaterFertilizerService.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/wf/dto/DevicePageReqVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/EquipmentProducerManager.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/commons/DeviceConst.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/conf/DeviceConf.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/conf/SchedulingConfig.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/DeviceListResponse.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/HistoryDataResponse.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/RealTimeDataResponse.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/UnifiedLoginResponse.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/UpdateDeviceResponse.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/devicelist/SysUserDeviceReqVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/devicelist/SysUserDeviceRespVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/history/HistoryDataListPageReqVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/history/HistoryDataListPageRespVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/login/UserLoginReqVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/login/UserLoginRespVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/realtime/RealTimeDataReqVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/realtime/RealTimeDataRespVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/devicelist/DevicePageReqVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/devicelist/DevicePageRespVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/login/LoginReqVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/login/LoginRespVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/realtime/RealTimeDeviceDataReqVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/realtime/RealTimeDeviceDataRespVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/updateparams/UpdateDeviceStatusReqVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/updateparams/UpdateDeviceStatusRespVO.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/AbstractDeviceService.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/DeviceService.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/HistoryDataStorageService.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/TokenCacheService.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/impl/SoilService.java create mode 100644 yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/impl/WaterFertilizerService.java diff --git a/Readme.md b/Readme.md index 45201fcb..2370dc8e 100644 --- a/Readme.md +++ b/Readme.md @@ -42,4 +42,15 @@ cn.iocoder.yudao.module.farm.controller.admin ├── xxx // 角色管理 ├── xxx // 菜单管理 └── xxx // 字典管理 -```` \ No newline at end of file +```` + + +# 设备商提供能力 +| 功能类型 | 土壤设备 | 水肥机 | +|--------------|----------|----------| +| 登录 | ✅ 支持 | ✅ 支持 | +| 获取设备列表 | ✅ 支持 | ✅ 支持 | +| 获取实时数据 | ✅ 支持 | ✅ 支持 | +| 获取历史数据 | ✅ 支持 | ❌ 不支持 | +| 更新设备属性 | ❌ 不支持 | ✅ 支持 | + diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/ApiController.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/ApiController.java index 51beb9a9..b1daeaa7 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/ApiController.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/ApiController.java @@ -92,7 +92,7 @@ public class ApiController { @PostMapping("/digital-cockpit/baseAndDevice/list") @Operation(summary = "数字驾驶舱-基地与设备信息列表") public CommonResult> getBaseAndDeviceInfoList(@Valid @RequestBody FarmBaseAndDeviceInfoReqVO req) { - CommonResult> bResult = baseInfoService.getBaseInfoList(new FarmBaseInfoReqVO(req.getTenantId())); + CommonResult> bResult = baseInfoService.getBaseInfoList(new FarmBaseInfoReqVO(req.getBaseId(),req.getTenantId())); List dList = BeanUtils.toBean(bResult.getData(), FarmBaseAndDeviceInfoRespVO.class); Map dtNameMap = deviceInfoService.getDeviceTypeNameMap(req.getTenantId()); diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/vo/FarmBaseAndDeviceInfoReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/vo/FarmBaseAndDeviceInfoReqVO.java index 780645c6..9aedff2d 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/vo/FarmBaseAndDeviceInfoReqVO.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/vo/FarmBaseAndDeviceInfoReqVO.java @@ -15,6 +15,9 @@ import lombok.NoArgsConstructor; @AllArgsConstructor @NoArgsConstructor public class FarmBaseAndDeviceInfoReqVO { + @Schema(description = "基地D") + @NotNull(message = "基地D: 不能为空") + private String baseId; @Schema(description = "租户ID") @NotNull(message = "租户ID: 不能为空") private String tenantId; diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/vo/FarmBaseInfoReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/vo/FarmBaseInfoReqVO.java index ea9f3b1a..ecded284 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/vo/FarmBaseInfoReqVO.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/api/vo/FarmBaseInfoReqVO.java @@ -16,6 +16,9 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class FarmBaseInfoReqVO { + @Schema(description = "基地D") +// @NotNull(message = "基地D: 不能为空") + private String baseId; @Schema(description = "租户ID") @NotNull(message = "租户ID: 不能为空") private String tenantId; diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/wx/WxController.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/wx/WxController.java index d33896f2..bb46cf67 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/wx/WxController.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/wx/WxController.java @@ -2,11 +2,18 @@ package cn.iocoder.yudao.module.farm.controller.admin.wx; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.farm.controller.admin.api.vo.DeviceStateRespVO; import cn.iocoder.yudao.module.farm.controller.admin.wx.vo.*; +import cn.iocoder.yudao.module.farm.dal.dataobject.baseinfo.BaseInfoDO; +import cn.iocoder.yudao.module.farm.dal.dataobject.deviceinfo.DeviceInfoDO; +import cn.iocoder.yudao.module.farm.dal.dataobject.plotinfo.PlotInfoDO; +import cn.iocoder.yudao.module.farm.service.baseinfo.BaseInfoService; import cn.iocoder.yudao.module.farm.service.deviceinfo.DeviceInfoService; import cn.iocoder.yudao.module.farm.service.farminformation.FarmInformationService; import cn.iocoder.yudao.module.farm.service.farmingrecord.FarmingRecordService; import cn.iocoder.yudao.module.farm.service.messagecenter.MessageCenterService; +import cn.iocoder.yudao.module.farm.service.plotinfo.PlotInfoService; +import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -20,6 +27,11 @@ import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser; +import static cn.iocoder.yudao.module.farm.enums.CommonConstants.BINDING_STATE_MAP; +import static cn.iocoder.yudao.module.farm.enums.CommonConstants.DEVICE_STATE_MAP; /** * @description: 微信端 @@ -36,12 +48,18 @@ public class WxController { private final DeviceInfoService deviceInfoService; private final FarmingRecordService farmingRecordService; private final MessageCenterService messageCenterService; + private final BaseInfoService baseInfoService; + private final PlotInfoService plotInfoService; + private final ProductionPlanService productionPlanService; - public WxController(FarmInformationService farmInformationService, DeviceInfoService deviceInfoService, FarmingRecordService farmingRecordService, MessageCenterService messageCenterService) { + public WxController(FarmInformationService farmInformationService, DeviceInfoService deviceInfoService, FarmingRecordService farmingRecordService, MessageCenterService messageCenterService, BaseInfoService baseInfoService, PlotInfoService plotInfoService, ProductionPlanService productionPlanService) { this.farmInformationService = farmInformationService; this.deviceInfoService = deviceInfoService; this.farmingRecordService = farmingRecordService; this.messageCenterService = messageCenterService; + this.baseInfoService = baseInfoService; + this.plotInfoService = plotInfoService; + this.productionPlanService = productionPlanService; } @@ -74,29 +92,75 @@ public class WxController { @Operation(summary = "获取设备信息") @Parameter(name = "baseId", description = "基地编号") public CommonResult getDeviceInfoList(@RequestParam("baseId") String baseId) { - DeviceInfoRespVO.DeviceRealData realData = new DeviceInfoRespVO.DeviceRealData("剩余电量", 100, "大气湿度", 0, "大气温度", 0); - DeviceInfoRespVO.DeviceDetail deviceDetail = new DeviceInfoRespVO.DeviceDetail(); - deviceDetail.setId("DEV001"); - deviceDetail.setDeviceUniqueId("SN202405270001"); - deviceDetail.setDeviceType("DT001"); - deviceDetail.setDeviceTypeName("农业环境气象监测-新"); - deviceDetail.setImage("http://223.83.152.93:9000/farm/20250909/trsqjc_1757398720478.png"); - deviceDetail.setImageList(Arrays.asList("http://223.83.152.93:9000/farm/20250909/trsqjc_1757398720478.png")); - deviceDetail.setDeviceState(1); - deviceDetail.setDeviceStateName("在线"); - deviceDetail.setBindingState(1); - deviceDetail.setBindingStateName("已绑定"); - deviceDetail.setPlotName("门村村小香薯种植基地"); - deviceDetail.setRealData(realData); + List plotInfos = this.getPlotInfos(baseId); + ProductionPlanService.CultivatingInfo cultivatingInfo = productionPlanService.getCultivatingInfo(baseId, ""); + int cultivatingSpecies = cultivatingInfo.getCultivatingSpeciesCount(); // 在种物种 + int cultivatingPlotCount = cultivatingInfo.getCultivatingPlotCount(); // 在种地块 + int plotCount = plotInfos.size(); + BaseInfoDO b = baseInfoService.getBaseInfo(baseId); - DeviceInfoRespVO d = new DeviceInfoRespVO(); - d.setTotal(1); - d.setOnlineTotal(1); - d.setOfflineTotal(0); - d.setDeviceDetail(deviceDetail); + DeviceInfoRespVO res = new DeviceInfoRespVO(); + res.setBaseId(baseId); + res.setBaseName(b.getName()); + res.setBaseArea(b.getArea().intValue()); + res.setBasePoint(b.getPoint()); + res.setCultivatingPlotCount(cultivatingPlotCount); + res.setPlotCount(plotCount); + res.setCultivatingSpecies(cultivatingSpecies); + res.setPlotInfos(plotInfos); + return CommonResult.success(res); + } - return CommonResult.success(d); + private List getPlotInfos(String baseId) { + List res = new ArrayList<>(); + + List pList = plotInfoService.getPlotInfos(baseId); + pList.forEach(p -> { + List deviceInfos = this.getDeviceInfos(baseId, p.getId()); + DeviceInfoRespVO.PlotInfo target = new DeviceInfoRespVO.PlotInfo(); + target.setPlotId(p.getId()); + target.setPlotName(p.getPlotName()); + target.setPlotArea(p.getPlotArea().intValue()); + target.setPlotColor(p.getPlotColor()); + target.setPlotPoint(p.getPoint()); + target.setDeviceDetails(deviceInfos); + res.add(target); + }); + + return res; + } + + private List getDeviceInfos(String baseId, String plotId) { + Map dtMap = deviceInfoService.getDeviceTypeNameMap(String.valueOf(getLoginUser().getTenantId())); + List bdList = deviceInfoService.getBaseAndDeviceInfoList(baseId, plotId); + DeviceStateRespVO ds = deviceInfoService.countDeviceState(baseId, String.valueOf(getLoginUser().getTenantId())); + + return bdList.stream().map(e -> { + List imageList = deviceInfoService.getImage(e.getDeviceType()); + DeviceInfoRespVO.DeviceDetail target = new DeviceInfoRespVO.DeviceDetail(); + target.setTotal(ds.getTotalDevices()); + target.setOnlineTotal(ds.getTotalOnlineDevices()); + target.setOfflineTotal(ds.getTotalOfflineDevices()); + + target.setId(e.getId()); + target.setDeviceUniqueId(e.getDeviceUniqueId()); + target.setDeviceType(e.getDeviceType()); + target.setDeviceTypeName(dtMap.get(e.getDeviceType())); + target.setImage(imageList.get(0)); + target.setImageList(imageList); + target.setDeviceState(e.getDeviceState()); + target.setDeviceStateName(DEVICE_STATE_MAP.get(e.getDeviceState())); + target.setBindingState(e.getBindingState()); + target.setBindingStateName(BINDING_STATE_MAP.get(e.getBindingState())); + target.setDevicePoint(e.getPoint()); + // TODO: 2025/9/26 接入真实数据 + target.setRealData(Arrays.asList(new DeviceInfoRespVO.DeviceRealData("剩余电量", 100), + new DeviceInfoRespVO.DeviceRealData("大气湿度", 0), + new DeviceInfoRespVO.DeviceRealData("大气温度", 0) + )); + return target; + }).toList(); } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/wx/vo/DeviceInfoRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/wx/vo/DeviceInfoRespVO.java index c055d354..29eb7667 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/wx/vo/DeviceInfoRespVO.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/wx/vo/DeviceInfoRespVO.java @@ -16,16 +16,52 @@ import java.util.List; @AllArgsConstructor @NoArgsConstructor public class DeviceInfoRespVO { + @Schema(description = "基地ID") + private String baseId; + @Schema(description = "基地名称") + private String baseName; + @Schema(description = "基地面积") + private Integer baseArea; + @Schema(description = "基地坐标") + private String basePoint; + @Schema(description = "在种地块数量") + private Integer cultivatingPlotCount; + @Schema(description = "地块总数量") + private Integer plotCount; + @Schema(description = "在种物种数量") + private Integer cultivatingSpecies; + @Schema(description = "地块列表") + private List plotInfos; - private Integer total; - private Integer onlineTotal; - private Integer offlineTotal; - private DeviceDetail deviceDetail; + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class PlotInfo{ + @Schema(description = "地块ID") + private String plotId; + @Schema(description = "地块名称") + private String plotName; + @Schema(description = "地块面积") + private Integer plotArea; + @Schema(description = "地块坐标") + private String plotPoint; + @Schema(description = "地块颜色") + private String plotColor; + @Schema(description = "设备列表") + private List deviceDetails; + } @Data @AllArgsConstructor @NoArgsConstructor public static class DeviceDetail{ + @Schema(description = "设备总数") + private Integer total; + @Schema(description = "在线设备数量") + private Integer onlineTotal; + @Schema(description = "离线设备数量") + private Integer offlineTotal; + private String id; @Schema(description = "设备全局唯一标识(设备厂商提供)", requiredMode = Schema.RequiredMode.REQUIRED) private String deviceUniqueId; @@ -43,10 +79,10 @@ public class DeviceInfoRespVO { @Schema(description = "绑定状态:1: 绑定; 0: 未绑定") private Integer bindingState; private String bindingStateName; - @Schema(description = "地块名称") - private String plotName; + @Schema(description = "设备坐标") + private String devicePoint; @Schema(description = "设备实时数据") - private DeviceRealData realData; + private List realData; } @Data @@ -55,10 +91,6 @@ public class DeviceInfoRespVO { public static class DeviceRealData{ private String k1; private Integer v1; - private String k2; - private Integer v2; - private String k3; - private Integer v3; } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/mysql/deviceinfo/DeviceInfoMapper.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/mysql/deviceinfo/DeviceInfoMapper.java index 9973b92f..71d5d8ae 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/mysql/deviceinfo/DeviceInfoMapper.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/dal/mysql/deviceinfo/DeviceInfoMapper.java @@ -102,5 +102,5 @@ public interface DeviceInfoMapper extends BaseMapperX { * @param tenantId * @return */ - DeviceStateRespVO countDeviceState(String tenantId); + DeviceStateRespVO countDeviceState(@Param("baseId") String baseId,@Param("tenantId") String tenantId); } \ No newline at end of file diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/DeviceManager.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/DeviceManager.java index ed69d83f..4ea3a79b 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/DeviceManager.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/DeviceManager.java @@ -15,7 +15,6 @@ import org.springframework.stereotype.Service; import java.util.List; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser; -import static cn.iocoder.yudao.module.farm.manager.devices.commons.DeviceConst.ALARM_STATUS_NAME_MAP; /** * @description: 设备管理 @@ -23,79 +22,79 @@ import static cn.iocoder.yudao.module.farm.manager.devices.commons.DeviceConst.A * @author: binda * @date: 2025/9/17 10:50 */ -@Service +//@Service public class DeviceManager { - private final SoilService soilService; - private final WaterFertilizerService waterFertilizerService; - - public DeviceManager(SoilService soilService, WaterFertilizerService waterFertilizerService) { - this.soilService = soilService; - this.waterFertilizerService = waterFertilizerService; - } - - public DeviceInfoDetailV2RespVO getRealData(String deviceUniqueId) { - DeviceInfoDetailV2RespVO.SoilInfo soilInfo = this.getSoilData(deviceUniqueId); - DeviceInfoDetailV2RespVO.WfInfo wfInfo = this.getWfData(deviceUniqueId); - return new DeviceInfoDetailV2RespVO(deviceUniqueId, null, null); - } - - public DeviceInfoDetailV2RespVO.SoilInfo getSoilData(String deviceUniqueId) { - // 判断该deviceUniqueId是否来源于土壤墒情 - boolean flag = false; - if (flag) { - return null; - } - - String tenantId = String.valueOf(getLoginUser().getTenantId()); - if (!soilService.validateUserToken(tenantId)) { - soilService.userLogin(); - } - - List realTimeData = soilService.getRealTimeData(new RealTimeDataReqVO(deviceUniqueId)); - HistoryDataListPageRespVO historyDataList = soilService.getHistoryDataList(new HistoryDataListPageReqVO()); - return new DeviceInfoDetailV2RespVO.SoilInfo(deviceUniqueId, coverToSoil(realTimeData), coverToSoil(historyDataList)); - } - - public DeviceInfoDetailV2RespVO.RealTimeData coverToSoil(List realTimeData) { - if (ObjectUtils.isEmpty(realTimeData)) { - return null; - } - RealTimeDataRespVO sourceObj = realTimeData.get(0); - return BeanUtils.toBean(sourceObj, DeviceInfoDetailV2RespVO.RealTimeData.class); - } - - public List coverToSoil(HistoryDataListPageRespVO historyDataList ) { - if (ObjectUtils.isEmpty(historyDataList)) { - return null; - } - - List source = historyDataList.getRows(); - return source.stream().map(e -> { - DeviceInfoDetailV2RespVO.HistoryDataList target = new DeviceInfoDetailV2RespVO.HistoryDataList(); - target.setHistoryId(e.getHistoryId()); - target.setRecordTime(DateUtils.timestampToLocalDateTime(e.getRecordTime())); - target.setDeviceAddress(e.getDeviceAddress()); - target.setAlarmStatus(e.getAlarmStatus()); - target.setAlarmStatusName(ALARM_STATUS_NAME_MAP.getOrDefault(e.getAlarmStatus(),"")); - target.setTemStr(e.getTemStr()); - target.setTemValue(e.getTemValue()); - target.setHumStr(e.getHumStr()); - target.setHumValue(e.getHumValue()); - return target; - }).toList(); - - } - - - - public DeviceInfoDetailV2RespVO.WfInfo getWfData(String deviceUniqueId) { - String tenantId = String.valueOf(getLoginUser().getTenantId()); - - - - return null; - } +// private final SoilService soilService; +// private final WaterFertilizerService waterFertilizerService; +// +// public DeviceManager(SoilService soilService, WaterFertilizerService waterFertilizerService) { +// this.soilService = soilService; +// this.waterFertilizerService = waterFertilizerService; +// } +// +// public DeviceInfoDetailV2RespVO getRealData(String deviceUniqueId) { +// DeviceInfoDetailV2RespVO.SoilInfo soilInfo = this.getSoilData(deviceUniqueId); +// DeviceInfoDetailV2RespVO.WfInfo wfInfo = this.getWfData(deviceUniqueId); +// return new DeviceInfoDetailV2RespVO(deviceUniqueId, null, null); +// } +// +// public DeviceInfoDetailV2RespVO.SoilInfo getSoilData(String deviceUniqueId) { +// // 判断该deviceUniqueId是否来源于土壤墒情 +// boolean flag = false; +// if (flag) { +// return null; +// } +// +// String tenantId = String.valueOf(getLoginUser().getTenantId()); +// if (!soilService.validateUserToken(tenantId)) { +// soilService.userLogin(); +// } +// +// List realTimeData = soilService.getRealTimeData(new RealTimeDataReqVO(deviceUniqueId)); +// HistoryDataListPageRespVO historyDataList = soilService.getHistoryDataList(new HistoryDataListPageReqVO()); +// return new DeviceInfoDetailV2RespVO.SoilInfo(deviceUniqueId, coverToSoil(realTimeData), coverToSoil(historyDataList)); +// } +// +// public DeviceInfoDetailV2RespVO.RealTimeData coverToSoil(List realTimeData) { +// if (ObjectUtils.isEmpty(realTimeData)) { +// return null; +// } +// RealTimeDataRespVO sourceObj = realTimeData.get(0); +// return BeanUtils.toBean(sourceObj, DeviceInfoDetailV2RespVO.RealTimeData.class); +// } +// +// public List coverToSoil(HistoryDataListPageRespVO historyDataList ) { +// if (ObjectUtils.isEmpty(historyDataList)) { +// return null; +// } +// +// List source = historyDataList.getRows(); +// return source.stream().map(e -> { +// DeviceInfoDetailV2RespVO.HistoryDataList target = new DeviceInfoDetailV2RespVO.HistoryDataList(); +// target.setHistoryId(e.getHistoryId()); +// target.setRecordTime(DateUtils.timestampToLocalDateTime(e.getRecordTime())); +// target.setDeviceAddress(e.getDeviceAddress()); +// target.setAlarmStatus(e.getAlarmStatus()); +// target.setAlarmStatusName(ALARM_STATUS_NAME_MAP.getOrDefault(e.getAlarmStatus(),"")); +// target.setTemStr(e.getTemStr()); +// target.setTemValue(e.getTemValue()); +// target.setHumStr(e.getHumStr()); +// target.setHumValue(e.getHumValue()); +// return target; +// }).toList(); +// +// } +// +// +// +// public DeviceInfoDetailV2RespVO.WfInfo getWfData(String deviceUniqueId) { +// String tenantId = String.valueOf(getLoginUser().getTenantId()); +// +// +// +// return null; +// } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/commons/DeviceConst.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/commons/DeviceConst.java index cc962c23..158e9e55 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/commons/DeviceConst.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/commons/DeviceConst.java @@ -9,87 +9,97 @@ import java.util.Map; * @date: 2025/9/17 15:24 */ public class DeviceConst { - - /** - * 四情 设备类型 - */ - public final String DEVICE_TYPE_IRRIGATION = "irrigation"; // 灌溉 - public final String DEVICE_TYPE_WORM = "worm"; // 虫害 - public final String DEVICE_TYPE_WORM_FLAG_SHIP = "wormFlagship"; - public final String DEVICE_TYPE_SOIL = "soil"; // 土壤 - public final String DEVICE_TYPE_MET = "met"; // 重金属 - public final String DEVICE_TYPE_SPORE = "spore"; // 孢子 - public final String DEVICE_TYPE_CAMERA = "camera"; // 监控 - - /** - * 四情 设备状态 - */ - public final String DEVICE_STATUS_ONLINE = "online"; - public final String DEVICE_STATUS_OFFLINE = "offline"; - public final String DEVICE_STATUS_ALARM = "alarm"; - - /** - * 四情 http 状态 - */ - public final String HTTP_STATUS_1000 = "1000"; // 成功 - public final String HTTP_STATUS_1001 = "1001"; // 失败 (执行错误) - public final String HTTP_STATUS_1002 = "1002"; // 失败 (验证失败) - public final String HTTP_STATUS_1003 = "1003"; // 服务端异常 - public final String HTTP_STATUS_1004 = "1004"; // 登录过期 - public final String HTTP_STATUS_2000 = "2000"; // 登录超时 - public final String HTTP_STATUS_4000 = "4000"; // 未登录或登录失败 - public final String HTTP_STATUS_5000 = "5000"; // 操作失败 - - /** - * 四情-墒情 设备实时数据 - 节点类型 - */ - public final int NODE_TYPE_1 = 1; // 模拟量 - public final int NODE_TYPE_1_1 = 1; // 模拟量 使能模拟量 - public final int NODE_TYPE_1_2 = 2; // 模拟量 使能 - - public final int NODE_TYPE_2 = 2; // 模拟量 - public final int NODE_TYPE_2_1 = 1; // 模拟量 使能模拟量 - public final int NODE_TYPE_2_2 = 2; // 模拟量 禁用 - - public final int NODE_TYPE_3 = 3; // 模拟量 - public final int NODE_TYPE_3_1 = 1; // 模拟量 禁用模拟量 - public final int NODE_TYPE_3_2 = 2; // 模拟量 使能 - - public final int NODE_TYPE_4 = 4; // 浮点型设备 - public final int NODE_TYPE_5 = 5; // 开关量型设备 - public final int NODE_TYPE_6 = 6; // 32位有符号整型 - public final int NODE_TYPE_7 = 7; // 32位无符号整型 - public final int NODE_TYPE_8 = 8; // 遥调设备 - - /** - * 四情-墒情 设备实时数据 - 节点报警等级 - */ - public final int ALARM_STATUS_0 = 0; // 正常 - public final int ALARM_STATUS_1 = 1; // 超上限报警 - public final int ALARM_STATUS_2 = 2; // 超下限报警 - public final int ALARM_STATUS_3 = 3; // 开关闭合报警 - public final int ALARM_STATUS_4 = 4; // 开关断开报警 - public final int ALARM_STATUS_5 = 5; // 遥调报警 - - /** - * 四情-设备报警通知记录 - 通知类型 - */ - public final int NOTICE_TYPE_0 = 0; // 邮箱 - public final int NOTICE_TYPE_1 = 1; // 短信 - - - - - public final static int ALARM_STATUS_NAME_0 = 0; // 正常 - public final static int ALARM_STATUS_NAME_1 = 1; // 报警 - - // TODO: 2025/9/17 UpdateNodeInfoReqVO - - - public static Map ALARM_STATUS_NAME_MAP = new HashMap<>(); - static { - ALARM_STATUS_NAME_MAP.put(ALARM_STATUS_NAME_0, "正常"); - ALARM_STATUS_NAME_MAP.put(ALARM_STATUS_NAME_1, "报警"); - } +// +// /** +// * 四情 设备类型 +// * +// * 虫情设备普通版: worm; +// * 虫情设备旗舰版: wormFlagship; +// * 孢子设备: spore; +// * 气象设备:met; +// * 墒情设备:soil; +// * 智慧环控 3.0 设备:irrigation; +// * 智慧环控 2.0 设备:irrigation2; +// * 摄像头:camera; +// * +// */ +// public final String DEVICE_TYPE_IRRIGATION = "irrigation"; +// public final String DEVICE_TYPE_WORM = "worm"; +// public final String DEVICE_TYPE_WORM_FLAG_SHIP = "wormFlagship"; +// public final String DEVICE_TYPE_SOIL = "soil"; +// public final String DEVICE_TYPE_MET = "met"; +// public final String DEVICE_TYPE_SPORE = "spore"; +// public final String DEVICE_TYPE_CAMERA = "camera"; +// +// /** +// * 四情 设备状态 +// */ +// public final String DEVICE_STATUS_ONLINE = "online"; +// public final String DEVICE_STATUS_OFFLINE = "offline"; +// public final String DEVICE_STATUS_ALARM = "alarm"; +// +// /** +// * 四情 http 状态 +// */ +// public final String HTTP_STATUS_1000 = "1000"; // 成功 +// public final String HTTP_STATUS_1001 = "1001"; // 失败 (执行错误) +// public final String HTTP_STATUS_1002 = "1002"; // 失败 (验证失败) +// public final String HTTP_STATUS_1003 = "1003"; // 服务端异常 +// public final String HTTP_STATUS_1004 = "1004"; // 登录过期 +// public final String HTTP_STATUS_2000 = "2000"; // 登录超时 +// public final String HTTP_STATUS_4000 = "4000"; // 未登录或登录失败 +// public final String HTTP_STATUS_5000 = "5000"; // 操作失败 +// +// /** +// * 四情-墒情 设备实时数据 - 节点类型 +// */ +// public final int NODE_TYPE_1 = 1; // 模拟量 +// public final int NODE_TYPE_1_1 = 1; // 模拟量 使能模拟量 +// public final int NODE_TYPE_1_2 = 2; // 模拟量 使能 +// +// public final int NODE_TYPE_2 = 2; // 模拟量 +// public final int NODE_TYPE_2_1 = 1; // 模拟量 使能模拟量 +// public final int NODE_TYPE_2_2 = 2; // 模拟量 禁用 +// +// public final int NODE_TYPE_3 = 3; // 模拟量 +// public final int NODE_TYPE_3_1 = 1; // 模拟量 禁用模拟量 +// public final int NODE_TYPE_3_2 = 2; // 模拟量 使能 +// +// public final int NODE_TYPE_4 = 4; // 浮点型设备 +// public final int NODE_TYPE_5 = 5; // 开关量型设备 +// public final int NODE_TYPE_6 = 6; // 32位有符号整型 +// public final int NODE_TYPE_7 = 7; // 32位无符号整型 +// public final int NODE_TYPE_8 = 8; // 遥调设备 +// +// /** +// * 四情-墒情 设备实时数据 - 节点报警等级 +// */ +// public final int ALARM_STATUS_0 = 0; // 正常 +// public final int ALARM_STATUS_1 = 1; // 超上限报警 +// public final int ALARM_STATUS_2 = 2; // 超下限报警 +// public final int ALARM_STATUS_3 = 3; // 开关闭合报警 +// public final int ALARM_STATUS_4 = 4; // 开关断开报警 +// public final int ALARM_STATUS_5 = 5; // 遥调报警 +// +// /** +// * 四情-设备报警通知记录 - 通知类型 +// */ +// public final int NOTICE_TYPE_0 = 0; // 邮箱 +// public final int NOTICE_TYPE_1 = 1; // 短信 +// +// +// +// +// public final static int ALARM_STATUS_NAME_0 = 0; // 正常 +// public final static int ALARM_STATUS_NAME_1 = 1; // 报警 +// +// // TODO: 2025/9/17 UpdateNodeInfoReqVO +// +// +// public static Map ALARM_STATUS_NAME_MAP = new HashMap<>(); +// static { +// ALARM_STATUS_NAME_MAP.put(ALARM_STATUS_NAME_0, "正常"); +// ALARM_STATUS_NAME_MAP.put(ALARM_STATUS_NAME_1, "报警"); +// } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/conf/DeviceConf.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/conf/DeviceConf.java index f8e9e447..eca66f56 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/conf/DeviceConf.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/conf/DeviceConf.java @@ -9,54 +9,54 @@ import org.springframework.context.annotation.Configuration; * @author: binda * @date: 2025/9/17 10:55 */ -@Data -@Configuration -@ConfigurationProperties(prefix = "device-manager") +//@Data +//@Configuration +//@ConfigurationProperties(prefix = "device-manager") public class DeviceConf { - private FourSituations fourSituations; - private WaterAndFertilizer waterAndFertilizer; - - @Data - public static class FourSituations { - private String hosts; - private String username; - private String password; - private Global global; - private Soil soil; - } - - @Data - public static class Global { - private String url21; // 用户登录 - private String url22; // 获取登录用户信息 - private String url23; // 获取子用户信息 - private String url24; // 设备报警通知记录 - private String url25; // 获取用户区域 - private String url26; // 获取用户设备 - private String url27; // 批量获取摄像头设备信息 - private String url28; // 获取设备实时数据 - private String url29; // 区域绑定设备 - } - - @Data - public static class Soil { - private String url41; // 墒情设备, 获取设备全部信息 - private String url42; // 墒情设备, 更新设备信息 - private String url43; // 墒情设备, 更新节点信息 - private String url44; // 墒情设备, 获取历史数据 - } - - @Data - public static class WaterAndFertilizer { - private String hosts; - private String username; - private String password; - private String url1; - private String url2; - private String url3; - private String url4; - } +// private FourSituations fourSituations; +// private WaterAndFertilizer waterAndFertilizer; +// +// @Data +// public static class FourSituations { +// private String hosts; +// private String username; +// private String password; +// private Global global; +// private Soil soil; +// } +// +// @Data +// public static class Global { +// private String url21; // 用户登录 +// private String url22; // 获取登录用户信息 +// private String url23; // 获取子用户信息 +// private String url24; // 设备报警通知记录 +// private String url25; // 获取用户区域 +// private String url26; // 获取用户设备 +// private String url27; // 批量获取摄像头设备信息 +// private String url28; // 获取设备实时数据 +// private String url29; // 区域绑定设备 +// } +// +// @Data +// public static class Soil { +// private String url41; // 墒情设备, 获取设备全部信息 +// private String url42; // 墒情设备, 更新设备信息 +// private String url43; // 墒情设备, 更新节点信息 +// private String url44; // 墒情设备, 获取历史数据 +// } +// +// @Data +// public static class WaterAndFertilizer { +// private String hosts; +// private String username; +// private String password; +// private String url1; +// private String url2; +// private String url3; +// private String url4; +// } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/conf/SchedulingConfig.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/conf/SchedulingConfig.java index 2b3cc9a1..be35ebca 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/conf/SchedulingConfig.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/conf/SchedulingConfig.java @@ -8,8 +8,8 @@ import org.springframework.scheduling.annotation.EnableScheduling; * @author: binda * @date: 2025/9/17 14:42 */ -@Configuration -@EnableScheduling +//@Configuration +//@EnableScheduling public class SchedulingConfig { } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/soil/SoilService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/soil/SoilService.java index cbb3e518..ba9d526f 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/soil/SoilService.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/soil/SoilService.java @@ -22,182 +22,182 @@ import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.*; * @date: 2025/9/17 10:57 */ @Slf4j -@Service +//@Service public class SoilService extends BaseTokenCacheService { - - private final DeviceConf deviceConf; - private final HttpClientUtils httpClientUtils; - - public SoilService(DeviceConf deviceConf, HttpClientUtils httpClientUtils) { - this.deviceConf = deviceConf; - this.httpClientUtils = httpClientUtils; - } - - private final String SOIL = "soil_"; - - public void userLogin() { - String username = deviceConf.getFourSituations().getUsername(); - String password = deviceConf.getFourSituations().getPassword(); - - this.userLogin(new UserLoginReqVO(username,password)); - } - - /** - * 登录获取token - * - * @param req - * @return - */ - public UserLoginRespVO userLogin(UserLoginReqVO req) { - String tenantId = getLoginUser().getTenantId().toString(); - String hosts = deviceConf.getFourSituations().getHosts(); - String userLoginURL = deviceConf.getFourSituations().getGlobal().getUrl21(); - - try { - ApiResponse response = httpClientUtils.postRequest(hosts, userLoginURL, req, null, UserLoginRespVO.class); - - if (response.isSuccess()) { - UserLoginRespVO data = response.getData(); - // TODO: 2025/9/17 持久化 - cacheToken(SOIL+tenantId, data); - } - - return response.getData(); - } catch (Exception e) { - log.error("租户 {} 登录失败: {}", tenantId, e.getMessage(), e); - throw exception(DEVICE_INFO_NOT_EXISTS_FOR_USER_LOGIN); - } - } - - /** - * 验证租户token有效性 - */ - public boolean validateUserToken(String tenantId) { - log.debug("验证租户 {} 的Token", tenantId); - return isTokenValidByTenantId(SOIL+tenantId); - } - - /** - * 获取用户设备 - */ - public List getSysUserDevice(SysUserDeviceReqVO req) { - - String tenantId = getLoginUser().getTenantId().toString(); - String token = getTokenByTenantId(tenantId); - String hosts = deviceConf.getFourSituations().getHosts(); - String getSysUserDeviceURL = deviceConf.getFourSituations().getGlobal().getUrl26(); - - Map headers = new HashMap<>(); - headers.put("token", token); - - Map params = new HashMap<>(); - params.put("groupId", StringUtils.defaultString(req.getGroupId())); - params.put("deviceType", StringUtils.defaultString(req.getDeviceType())); - - try { - - ApiResponse> response = httpClientUtils.getRequestAsList(hosts, getSysUserDeviceURL, params, headers, SysUserDeviceRespVO.class); - if (!response.isSuccess()) { - throw exception(DEVICE_INFO_NOT_EXISTS_FOR_USER_DEVICE); - } - return response.getData(); - } catch (Exception e) { - e.printStackTrace(); - throw exception(DEVICE_INFO_NOT_EXISTS_FOR_USER_DEVICE); - } - - } - - /** - * 获取设备实时数据 - */ - public List getRealTimeData(RealTimeDataReqVO req) { - String tenantId = getLoginUser().getTenantId().toString(); - String token = getTokenByTenantId(tenantId); - String hosts = deviceConf.getFourSituations().getHosts(); - String getSysUserDeviceURL = deviceConf.getFourSituations().getGlobal().getUrl27(); - - Map headers = new HashMap<>(); - headers.put("token", token); - Map params = new HashMap<>(); - params.put("deviceAddrs", req.getDeviceAddrs()); - - try { - ApiResponse> response = httpClientUtils.getRequestAsList(hosts, getSysUserDeviceURL, params, headers, RealTimeDataRespVO.class); - if (!response.isSuccess()) { - throw exception(DEVICE_INFO_NOT_EXISTS_FOR_REAL_TIME_DATA); - } - return response.getData(); - } catch (Exception e) { - e.printStackTrace(); - throw exception(DEVICE_INFO_NOT_EXISTS_FOR_REAL_TIME_DATA); - } - - } - - /** - * 设备报警通知记录 - */ - public List getAlarmNoticeRecord(AlarmNoticeRecordReqVO req) { - - String tenantId = getLoginUser().getTenantId().toString(); - String token = getTokenByTenantId(tenantId); - String hosts = deviceConf.getFourSituations().getHosts(); - String getAlarmNoticeRecord = deviceConf.getFourSituations().getGlobal().getUrl24(); - - Map headers = new HashMap<>(); - headers.put("token", token); - Map params = req.toFieldValueMap(); - - try { - ApiResponse> response = httpClientUtils.getRequestAsList(hosts, getAlarmNoticeRecord, params, headers, AlarmNoticeRecordRespVO.class); - if (!response.isSuccess()) { - throw exception(DEVICE_INFO_NOT_EXISTS_FOR_ALARM_NOTICE_RECORD); - } - return response.getData(); - } catch (Exception e) { - e.printStackTrace(); - throw exception(DEVICE_INFO_NOT_EXISTS_FOR_ALARM_NOTICE_RECORD); - } - - } - - /** - * 墒情设备, 获取设备全部信息 - */ - public List getDeviceAllInfo(DeviceAllInfoReqVO req) { - - - return null; - } - - /** - * 墒情设备, 更新设备信息 - */ - public Boolean updateDevice(UpdateDeviceReqVO req) { - - - return false; - } - - /** - * 墒情设备, 更新节点信息 - */ - public Boolean updateNodeInfo(UpdateNodeInfoReqVO req) { - - - return false; - } - - /** - * 墒情设备, 获取历史数据 - */ - public HistoryDataListPageRespVO getHistoryDataList(HistoryDataListPageReqVO req) { - - - - return null; - } +// +// private final DeviceConf deviceConf; +// private final HttpClientUtils httpClientUtils; +// +// public SoilService(DeviceConf deviceConf, HttpClientUtils httpClientUtils) { +// this.deviceConf = deviceConf; +// this.httpClientUtils = httpClientUtils; +// } +// +// private final String SOIL = "soil_"; +// +// public void userLogin() { +// String username = deviceConf.getFourSituations().getUsername(); +// String password = deviceConf.getFourSituations().getPassword(); +// +// this.userLogin(new UserLoginReqVO(username,password)); +// } +// +// /** +// * 登录获取token +// * +// * @param req +// * @return +// */ +// public UserLoginRespVO userLogin(UserLoginReqVO req) { +// String tenantId = getLoginUser().getTenantId().toString(); +// String hosts = deviceConf.getFourSituations().getHosts(); +// String userLoginURL = deviceConf.getFourSituations().getGlobal().getUrl21(); +// +// try { +// ApiResponse response = httpClientUtils.postRequest(hosts, userLoginURL, req, null, UserLoginRespVO.class); +// +// if (response.isSuccess()) { +// UserLoginRespVO data = response.getData(); +// // TODO: 2025/9/17 持久化 +// cacheToken(SOIL+tenantId, data); +// } +// +// return response.getData(); +// } catch (Exception e) { +// log.error("租户 {} 登录失败: {}", tenantId, e.getMessage(), e); +// throw exception(DEVICE_INFO_NOT_EXISTS_FOR_USER_LOGIN); +// } +// } +// +// /** +// * 验证租户token有效性 +// */ +// public boolean validateUserToken(String tenantId) { +// log.debug("验证租户 {} 的Token", tenantId); +// return isTokenValidByTenantId(SOIL+tenantId); +// } +// +// /** +// * 获取用户设备 +// */ +// public List getSysUserDevice(SysUserDeviceReqVO req) { +// +// String tenantId = getLoginUser().getTenantId().toString(); +// String token = getTokenByTenantId(tenantId); +// String hosts = deviceConf.getFourSituations().getHosts(); +// String getSysUserDeviceURL = deviceConf.getFourSituations().getGlobal().getUrl26(); +// +// Map headers = new HashMap<>(); +// headers.put("token", token); +// +// Map params = new HashMap<>(); +// params.put("groupId", StringUtils.defaultString(req.getGroupId())); +// params.put("deviceType", StringUtils.defaultString(req.getDeviceType())); +// +// try { +// +// ApiResponse> response = httpClientUtils.getRequestAsList(hosts, getSysUserDeviceURL, params, headers, SysUserDeviceRespVO.class); +// if (!response.isSuccess()) { +// throw exception(DEVICE_INFO_NOT_EXISTS_FOR_USER_DEVICE); +// } +// return response.getData(); +// } catch (Exception e) { +// e.printStackTrace(); +// throw exception(DEVICE_INFO_NOT_EXISTS_FOR_USER_DEVICE); +// } +// +// } +// +// /** +// * 获取设备实时数据 +// */ +// public List getRealTimeData(RealTimeDataReqVO req) { +// String tenantId = getLoginUser().getTenantId().toString(); +// String token = getTokenByTenantId(tenantId); +// String hosts = deviceConf.getFourSituations().getHosts(); +// String getSysUserDeviceURL = deviceConf.getFourSituations().getGlobal().getUrl27(); +// +// Map headers = new HashMap<>(); +// headers.put("token", token); +// Map params = new HashMap<>(); +// params.put("deviceAddrs", req.getDeviceAddrs()); +// +// try { +// ApiResponse> response = httpClientUtils.getRequestAsList(hosts, getSysUserDeviceURL, params, headers, RealTimeDataRespVO.class); +// if (!response.isSuccess()) { +// throw exception(DEVICE_INFO_NOT_EXISTS_FOR_REAL_TIME_DATA); +// } +// return response.getData(); +// } catch (Exception e) { +// e.printStackTrace(); +// throw exception(DEVICE_INFO_NOT_EXISTS_FOR_REAL_TIME_DATA); +// } +// +// } +// +// /** +// * 设备报警通知记录 +// */ +// public List getAlarmNoticeRecord(AlarmNoticeRecordReqVO req) { +// +// String tenantId = getLoginUser().getTenantId().toString(); +// String token = getTokenByTenantId(tenantId); +// String hosts = deviceConf.getFourSituations().getHosts(); +// String getAlarmNoticeRecord = deviceConf.getFourSituations().getGlobal().getUrl24(); +// +// Map headers = new HashMap<>(); +// headers.put("token", token); +// Map params = req.toFieldValueMap(); +// +// try { +// ApiResponse> response = httpClientUtils.getRequestAsList(hosts, getAlarmNoticeRecord, params, headers, AlarmNoticeRecordRespVO.class); +// if (!response.isSuccess()) { +// throw exception(DEVICE_INFO_NOT_EXISTS_FOR_ALARM_NOTICE_RECORD); +// } +// return response.getData(); +// } catch (Exception e) { +// e.printStackTrace(); +// throw exception(DEVICE_INFO_NOT_EXISTS_FOR_ALARM_NOTICE_RECORD); +// } +// +// } +// +// /** +// * 墒情设备, 获取设备全部信息 +// */ +// public List getDeviceAllInfo(DeviceAllInfoReqVO req) { +// +// +// return null; +// } +// +// /** +// * 墒情设备, 更新设备信息 +// */ +// public Boolean updateDevice(UpdateDeviceReqVO req) { +// +// +// return false; +// } +// +// /** +// * 墒情设备, 更新节点信息 +// */ +// public Boolean updateNodeInfo(UpdateNodeInfoReqVO req) { +// +// +// return false; +// } +// +// /** +// * 墒情设备, 获取历史数据 +// */ +// public HistoryDataListPageRespVO getHistoryDataList(HistoryDataListPageReqVO req) { +// +// +// +// return null; +// } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/wf/WaterFertilizerService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/wf/WaterFertilizerService.java deleted file mode 100644 index 0122db68..00000000 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/wf/WaterFertilizerService.java +++ /dev/null @@ -1,90 +0,0 @@ -package cn.iocoder.yudao.module.farm.manager.devices.wf; - -import cn.iocoder.yudao.module.farm.manager.devices.conf.DeviceConf; -import cn.iocoder.yudao.module.farm.manager.devices.soil.BaseTokenCacheService; -import cn.iocoder.yudao.module.farm.manager.devices.wf.dto.*; -import cn.iocoder.yudao.module.farm.utils.HttpClientUtils; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser; -import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.DEVICE_INFO_NOT_EXISTS_FOR_WF_LOGIN; - -/** - * @description: 水肥机 - * @author: binda - * @date: 2025/9/17 10:59 - */ -@Slf4j -@Service -public class WaterFertilizerService extends BaseTokenCacheService { - - private final DeviceConf deviceConf; - private final HttpClientUtils httpClientUtils; - - public WaterFertilizerService(DeviceConf deviceConf, HttpClientUtils httpClientUtils) { - this.deviceConf = deviceConf; - this.httpClientUtils = httpClientUtils; - } - - private final String Authorization = "Authorization"; - private final String Bearer = "Bearer "; - private final String WF = "wf_"; - - /** - * 获取公钥 - */ - public LoginRespVO login() { - String tenantId = getLoginUser().getTenantId().toString(); - String hosts = deviceConf.getWaterAndFertilizer().getHosts(); - String loginURL = deviceConf.getWaterAndFertilizer().getUrl1(); - LoginReqVO req = new LoginReqVO(deviceConf.getWaterAndFertilizer().getUsername(), - deviceConf.getWaterAndFertilizer().getPassword()); - - try { - HttpClientUtils.ApiResponse response = httpClientUtils.postRequest(hosts, loginURL, req, null, LoginRespVO.class); - if (!response.isSuccess()) { - throw exception(DEVICE_INFO_NOT_EXISTS_FOR_WF_LOGIN); - } - LoginRespVO data = response.getData(); - cacheToken(WF+tenantId, data.getToken()); - return response.getData(); - } catch (Exception e) { - e.printStackTrace(); - throw exception(DEVICE_INFO_NOT_EXISTS_FOR_WF_LOGIN); - } - - } - - /** - * 获取设备列表 - * @param userCode 用户名 - * @return - */ - public DevicePageRespVO getDeviceList(String userCode) { - - return null; - } - - /** - * 获取设备实时状态 - * @param deviceId 设备ID - * @return - */ - public RealTimeDeviceDataRespVO getRealTimeDeviceData(String deviceId) { - return null; - } - - /** - * 更改设备属性 - * @param deviceId 设备ID - * @param paramStr 更改值: true: 打开,false: 关闭 - * @return - */ - public UpdateDeviceStatusRespVO updateDeviceStatus(String deviceId, String paramStr) { - - return null; - } -} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/wf/dto/DevicePageReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/wf/dto/DevicePageReqVO.java new file mode 100644 index 00000000..b0a47734 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/devices/wf/dto/DevicePageReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.farm.manager.devices.wf.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: + * @author: binda + * @date: 2025/9/25 23:07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DevicePageReqVO { + /** + * 令牌 必填 + */ + private String token; + /** + * 用户名 + */ + private String userCode; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/EquipmentProducerManager.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/EquipmentProducerManager.java new file mode 100644 index 00000000..00a37065 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/EquipmentProducerManager.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer; + +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.*; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.service.DeviceService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @description: + * @author: binda + * @date: 2025/9/25 20:44 + */ +@Service +public class EquipmentProducerManager { + + private final Map deviceServiceMap; + + public EquipmentProducerManager(List deviceServices) { + this.deviceServiceMap = deviceServices.stream() + .collect(Collectors.toMap(DeviceService::getDeviceType, Function.identity())); + } + + /** + * 统一登录方法 + */ + public UnifiedLoginResponse login(String deviceType, Long tenantId, String deviceId, Object loginRequest) { + DeviceService service = this.getDeviceService(deviceType); + return service.login(tenantId, deviceId, loginRequest); + } + + /** + * 统一获取设备列表方法 + */ + public DeviceListResponse getDeviceList(String deviceType, Long tenantId, String token, Object listRequest) { + DeviceService service = this.getDeviceService(deviceType); + return service.getDeviceList(tenantId, token, listRequest); + } + + /** + * 统一获取实时数据方法 + */ + public RealTimeDataResponse getRealTimeData(String deviceType, Long tenantId, String token, Object realTimeRequest) { + DeviceService service = this.getDeviceService(deviceType); + return service.getRealTimeData(tenantId, token, realTimeRequest); + } + + /** + * 统一获取历史数据方法 + */ + public HistoryDataResponse getHistoryData(String deviceType, Long tenantId, String token, Object historyRequest) { + DeviceService service = getDeviceService(deviceType); + return service.getHistoryData(tenantId, token, historyRequest); + } + + /** + * 统一更新设备属性方法 + */ + public UpdateDeviceResponse updateDeviceProperties(String deviceType, Long tenantId, String token, Object updateRequest) { + DeviceService service = getDeviceService(deviceType); + return service.updateDeviceProperties(tenantId, token, updateRequest); + } + + /** + * 根据设备类型获取对应的设备服务 + */ + private DeviceService getDeviceService(String deviceType) { + DeviceService service = deviceServiceMap.get(deviceType); + if (service == null) { + throw new IllegalArgumentException("不支持的设备类型: " + deviceType); + } + return service; + } + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/commons/DeviceConst.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/commons/DeviceConst.java new file mode 100644 index 00000000..f670b021 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/commons/DeviceConst.java @@ -0,0 +1,105 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.commons; + +import java.util.HashMap; +import java.util.Map; + +/** + * @description: 设备常量 + * @author: binda + * @date: 2025/9/17 15:24 + */ +public class DeviceConst { + + /** + * 四情 设备类型 + * + * 虫情设备普通版: worm; + * 虫情设备旗舰版: wormFlagship; + * 孢子设备: spore; + * 气象设备:met; + * 墒情设备:soil; + * 智慧环控 3.0 设备:irrigation; + * 智慧环控 2.0 设备:irrigation2; + * 摄像头:camera; + * + */ + public final String DEVICE_TYPE_IRRIGATION = "irrigation"; + public final String DEVICE_TYPE_WORM = "worm"; + public final String DEVICE_TYPE_WORM_FLAG_SHIP = "wormFlagship"; + public final String DEVICE_TYPE_SOIL = "soil"; + public final String DEVICE_TYPE_MET = "met"; + public final String DEVICE_TYPE_SPORE = "spore"; + public final String DEVICE_TYPE_CAMERA = "camera"; + + /** + * 四情 设备状态 + */ + public final String DEVICE_STATUS_ONLINE = "online"; + public final String DEVICE_STATUS_OFFLINE = "offline"; + public final String DEVICE_STATUS_ALARM = "alarm"; + + /** + * 四情 http 状态 + */ + public final String HTTP_STATUS_1000 = "1000"; // 成功 + public final String HTTP_STATUS_1001 = "1001"; // 失败 (执行错误) + public final String HTTP_STATUS_1002 = "1002"; // 失败 (验证失败) + public final String HTTP_STATUS_1003 = "1003"; // 服务端异常 + public final String HTTP_STATUS_1004 = "1004"; // 登录过期 + public final String HTTP_STATUS_2000 = "2000"; // 登录超时 + public final String HTTP_STATUS_4000 = "4000"; // 未登录或登录失败 + public final String HTTP_STATUS_5000 = "5000"; // 操作失败 + + /** + * 四情-墒情 设备实时数据 - 节点类型 + */ + public final int NODE_TYPE_1 = 1; // 模拟量 + public final int NODE_TYPE_1_1 = 1; // 模拟量 使能模拟量 + public final int NODE_TYPE_1_2 = 2; // 模拟量 使能 + + public final int NODE_TYPE_2 = 2; // 模拟量 + public final int NODE_TYPE_2_1 = 1; // 模拟量 使能模拟量 + public final int NODE_TYPE_2_2 = 2; // 模拟量 禁用 + + public final int NODE_TYPE_3 = 3; // 模拟量 + public final int NODE_TYPE_3_1 = 1; // 模拟量 禁用模拟量 + public final int NODE_TYPE_3_2 = 2; // 模拟量 使能 + + public final int NODE_TYPE_4 = 4; // 浮点型设备 + public final int NODE_TYPE_5 = 5; // 开关量型设备 + public final int NODE_TYPE_6 = 6; // 32位有符号整型 + public final int NODE_TYPE_7 = 7; // 32位无符号整型 + public final int NODE_TYPE_8 = 8; // 遥调设备 + + /** + * 四情-墒情 设备实时数据 - 节点报警等级 + */ + public final int ALARM_STATUS_0 = 0; // 正常 + public final int ALARM_STATUS_1 = 1; // 超上限报警 + public final int ALARM_STATUS_2 = 2; // 超下限报警 + public final int ALARM_STATUS_3 = 3; // 开关闭合报警 + public final int ALARM_STATUS_4 = 4; // 开关断开报警 + public final int ALARM_STATUS_5 = 5; // 遥调报警 + + /** + * 四情-设备报警通知记录 - 通知类型 + */ + public final int NOTICE_TYPE_0 = 0; // 邮箱 + public final int NOTICE_TYPE_1 = 1; // 短信 + + + + + public final static int ALARM_STATUS_NAME_0 = 0; // 正常 + public final static int ALARM_STATUS_NAME_1 = 1; // 报警 + + // TODO: 2025/9/17 UpdateNodeInfoReqVO + + + public static Map ALARM_STATUS_NAME_MAP = new HashMap<>(); + static { + ALARM_STATUS_NAME_MAP.put(ALARM_STATUS_NAME_0, "正常"); + ALARM_STATUS_NAME_MAP.put(ALARM_STATUS_NAME_1, "报警"); + } + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/conf/DeviceConf.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/conf/DeviceConf.java new file mode 100644 index 00000000..30ac5d28 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/conf/DeviceConf.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.conf; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * @description: 设备配置 + * @author: binda + * @date: 2025/9/17 10:55 + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "device-manager") +public class DeviceConf { + + private FourSituations fourSituations; + private WaterAndFertilizer waterAndFertilizer; + + @Data + public static class FourSituations { + private String hosts; + private String username; + private String password; + private Global global; + private Soil soil; + } + + @Data + public static class Global { + private String url21; // 用户登录 + private String url22; // 获取登录用户信息 + private String url23; // 获取子用户信息 + private String url24; // 设备报警通知记录 + private String url25; // 获取用户区域 + private String url26; // 获取用户设备 + private String url27; // 批量获取摄像头设备信息 + private String url28; // 获取设备实时数据 + private String url29; // 区域绑定设备 + } + + @Data + public static class Soil { + private String url41; // 墒情设备, 获取设备全部信息 + private String url42; // 墒情设备, 更新设备信息 + private String url43; // 墒情设备, 更新节点信息 + private String url44; // 墒情设备, 获取历史数据 + } + + @Data + public static class WaterAndFertilizer { + private String hosts; + private String username; + private String password; + private String url1; + private String url2; + private String url3; + private String url4; + } + + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/conf/SchedulingConfig.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/conf/SchedulingConfig.java new file mode 100644 index 00000000..5e42d023 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/conf/SchedulingConfig.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.conf; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * @description: + * @author: binda + * @date: 2025/9/17 14:42 + */ +@Configuration +@EnableScheduling +public class SchedulingConfig { + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/DeviceListResponse.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/DeviceListResponse.java new file mode 100644 index 00000000..acab8663 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/DeviceListResponse.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto; + +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.service.TokenCacheService; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @description: 统一设备列表响应 + * @author: binda + * @date: 2025/9/25 23:29 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DeviceListResponse { + private String code; + private String message; + private List data; + + public static DeviceListResponse success(List data) { + return new DeviceListResponse("200", "成功", data); + } + + public static DeviceListResponse error(String message) { + return new DeviceListResponse("500", message, null); + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/HistoryDataResponse.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/HistoryDataResponse.java new file mode 100644 index 00000000..012e99b8 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/HistoryDataResponse.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: TODO + * @author: binda + * @date: 2025/9/26 20:32 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class HistoryDataResponse { + private String code; + private String message; + private Object data; + + public static HistoryDataResponse success(Object data) { + return new HistoryDataResponse("200", "成功", data); + } + + public static HistoryDataResponse error(String message) { + return new HistoryDataResponse("500", message, null); + } + + public static HistoryDataResponse notSupported() { + return new HistoryDataResponse("501", "该设备类型不支持历史数据功能", null); + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/RealTimeDataResponse.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/RealTimeDataResponse.java new file mode 100644 index 00000000..3faec305 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/RealTimeDataResponse.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 实时数据 + * @author: binda + * @date: 2025/9/26 18:32 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RealTimeDataResponse { + private String code; + private String message; + private Object data; // 由于不同设备实时数据结构差异大,使用Object类型 + + public static RealTimeDataResponse success(Object data) { + return new RealTimeDataResponse("200", "成功", data); + } + + public static RealTimeDataResponse error(String message) { + return new RealTimeDataResponse("500", message, null); + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/UnifiedLoginResponse.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/UnifiedLoginResponse.java new file mode 100644 index 00000000..a0828b17 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/UnifiedLoginResponse.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 统一登录响应 + * @author: binda + * @date: 2025/9/25 21:26 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UnifiedLoginResponse { + private String code; + private String message; + private LoginData data; + + public static UnifiedLoginResponse success(LoginData data) { + return new UnifiedLoginResponse("200", "成功", data); + } + + public static UnifiedLoginResponse error(String message) { + return new UnifiedLoginResponse("500", message, null); + } + + // 登录数据 + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class LoginData { + private String loginSign; + private Long currDate; + private Long expDate; + private String token; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/UpdateDeviceResponse.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/UpdateDeviceResponse.java new file mode 100644 index 00000000..4d839cf2 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/UpdateDeviceResponse.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: + * @author: binda + * @date: 2025/9/26 21:09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UpdateDeviceResponse { + private String code; + private String message; + private Object data; + + public static UpdateDeviceResponse success(Object data) { + return new UpdateDeviceResponse("200", "成功", data); + } + + public static UpdateDeviceResponse error(String message) { + return new UpdateDeviceResponse("500", message, null); + } + + public static UpdateDeviceResponse notSupported() { + return new UpdateDeviceResponse("501", "该设备类型不支持更新设备属性功能", null); + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/devicelist/SysUserDeviceReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/devicelist/SysUserDeviceReqVO.java new file mode 100644 index 00000000..c4714696 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/devicelist/SysUserDeviceReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.devicelist; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 获取用户设备 请求实体 + * @author: binda + * @date: 2025/9/17 15:28 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysUserDeviceReqVO { + /** + * 区域ID 非必填 + */ + private String groupId; + /** + * 设备类型 非必填 + */ + private String deviceType; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/devicelist/SysUserDeviceRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/devicelist/SysUserDeviceRespVO.java new file mode 100644 index 00000000..c442977b --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/devicelist/SysUserDeviceRespVO.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.devicelist; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @description: 获取用户设备 响应实体 + * @author: binda + * @date: 2025/9/17 15:31 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysUserDeviceRespVO { + private String code; + private String message; + private List data; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class DeviceInfo{ + /** + * 设备地址 + */ + public String deviceAddr; // 设备编号 + /** + * 区域ID + */ + public String groupId; + /** + * 设备类型 + */ + public String deviceType; + /** + * 设备名称 + */ + public String deviceName; // 设备名称 + /** + * 设备的经度 + */ + public String deviceLng; + /** + * 设备的维度 + */ + public String deviceLat; + /** + * 设备iccid + */ + public String deviceIccId; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/history/HistoryDataListPageReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/history/HistoryDataListPageReqVO.java new file mode 100644 index 00000000..97c3ccbc --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/history/HistoryDataListPageReqVO.java @@ -0,0 +1,108 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.history; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * @description: 墒情设备, 获取历史数据 请求实体 + * @author: binda + * @date: 2025/9/17 20:53 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class HistoryDataListPageReqVO { + /** + * 必选 + * 开始时间 (时间戳) + */ + private String beginTime; + /** + * 必选 + * 结束时间 (时间戳) + */ + private String endTime; + /** + * 必选 + * 设备地址 + */ + private String deviceAddr; + /** + * 非必选 + * 节点ID + */ + private String nodeId; + /** + * 必选 + * 页码 + */ + private Integer pages; + /** + * 必选 + * 每页数量 + */ + private Integer limit; + + public HistoryDataListPageReqVO(String beginTime, String endTime) { + this.beginTime = beginTime; + this.endTime = endTime; + } + + + public static class HistoryDataTimeRangeUtil { + + /** + * 获取近12小时的时间范围 + */ + public static HistoryDataListPageReqVO getLast12Hours() { + LocalDateTime endTime = LocalDateTime.now(); + LocalDateTime startTime = endTime.minusHours(12); + + return buildRequestVO(startTime, endTime); + } + + /** + * 获取近一天的时间范围 + */ + public static HistoryDataListPageReqVO getLast24Hours() { + LocalDateTime endTime = LocalDateTime.now(); + LocalDateTime startTime = endTime.minusDays(1); + + return buildRequestVO(startTime, endTime); + } + + /** + * 获取近三天的时间范围 + */ + public static HistoryDataListPageReqVO getLast3Days() { + LocalDateTime endTime = LocalDateTime.now(); + LocalDateTime startTime = endTime.minusDays(3); + + return buildRequestVO(startTime, endTime); + } + + /** + * 获取近七天的时间范围 + */ + public static HistoryDataListPageReqVO getLast7Days() { + LocalDateTime endTime = LocalDateTime.now(); + LocalDateTime startTime = endTime.minusDays(7); + + return buildRequestVO(startTime, endTime); + } + + /** + * 构建请求VO对象 + */ + private static HistoryDataListPageReqVO buildRequestVO(LocalDateTime startTime, LocalDateTime endTime) { + String beginTimeStamp = String.valueOf(startTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + String endTimeStamp = String.valueOf(endTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + + return new HistoryDataListPageReqVO(beginTimeStamp, endTimeStamp); + } + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/history/HistoryDataListPageRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/history/HistoryDataListPageRespVO.java new file mode 100644 index 00000000..60042253 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/history/HistoryDataListPageRespVO.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.history; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @description: 墒情设备, 获取历史数据 响应实体 + * @author: binda + * @date: 2025/9/17 20:53 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class HistoryDataListPageRespVO { + /** + * 页码,每页数量,总页数,总条数 + */ + private Integer pages; + private Integer limit; + private Integer totalPages; + private Integer total; + private List rows; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Row{ + /** + * 记录表 id + */ + private Integer historyId; + /** + * 节点编号 + */ + private Integer nodeId; + /** + * 设备地址 + */ + private String deviceAddress; + /** + * 模拟量 1 + */ + private String temStr; + private Double temValue; + /** + * 模拟狼 2 + */ + private String humStr; + private Double humValue; + /** + * 是否是报警数据 0:正常 1:报警 + */ + private Integer alarmStatus; + /** + * 保存时间(时间戳) + */ + private Long recordTime; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/login/UserLoginReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/login/UserLoginReqVO.java new file mode 100644 index 00000000..a290a86f --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/login/UserLoginReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.login; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 登录请求实体 + * @author: binda + * @date: 2025/9/17 13:46 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserLoginReqVO { + public String loginName; + public String loginPwd; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/login/UserLoginRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/login/UserLoginRespVO.java new file mode 100644 index 00000000..94773911 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/login/UserLoginRespVO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.login; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 登录响应实体 + * @author: binda + * @date: 2025/9/17 13:46 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserLoginRespVO { + + private String code; + private String message; + private VendorData data; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class VendorData { + /** + * 登录标识 + */ + public String loginSign; + /** + * token 生成时间 + */ + public long currDate; + /** + * 过期时间 + */ + public long expDate; + /** + * 令牌 + */ + public String token; + } + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/realtime/RealTimeDataReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/realtime/RealTimeDataReqVO.java new file mode 100644 index 00000000..7b4c25dc --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/realtime/RealTimeDataReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.realtime; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 设备实时数据 请求实体 + * @author: binda + * @date: 2025/9/17 19:02 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RealTimeDataReqVO { + /** + * 设备地址 非必定 + * tips: 多个用英文逗号分隔,空为获取当前用户下的所有设备 + */ + private String deviceAddrs; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/realtime/RealTimeDataRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/realtime/RealTimeDataRespVO.java new file mode 100644 index 00000000..84fba5c6 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/soil/realtime/RealTimeDataRespVO.java @@ -0,0 +1,79 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.realtime; + +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.devicelist.SysUserDeviceRespVO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @description: 设备实时数据 相应试题 + * @author: binda + * @date: 2025/9/17 19:01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RealTimeDataRespVO { + + private String code; + private String message; + private List data; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class DeviceInfo{ + /** + * 设备地址 + */ + private String deviceAddr; + /** + * 设备名称 + */ + private String deviceName; + /** + * 经度 + */ + private Double lat; + /** + * 维度 + */ + private Double lng; + /** + * 设备状态 + */ + private String status; + /** + * 设备类型 + */ + private String deviceType; + + private List data; + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class RealTimeData { + // 节点编号 + private Integer nodeId; + // 节点名称 + private String nodeName; + // 节点类型 + private Integer nodeType; + // 模拟量1 名称,单位,原值,显示值,报警等级 + private String temName; + private String temUnit; + private Double temValue; + private String temValueStr; + private Integer temAlarmStatus; + // 模拟量2 名称,单位,原值,显示值,报警等级 + private String humName; + private String humUnit; + private String humValue; + private String humValueStr; + private String humAlarmStatus; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/devicelist/DevicePageReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/devicelist/DevicePageReqVO.java new file mode 100644 index 00000000..7d876124 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/devicelist/DevicePageReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.devicelist; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: + * @author: binda + * @date: 2025/9/25 23:07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DevicePageReqVO { + /** + * 令牌 必填 + */ + private String token; + /** + * 用户名 + */ + private String userCode; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/devicelist/DevicePageRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/devicelist/DevicePageRespVO.java new file mode 100644 index 00000000..cfb91adb --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/devicelist/DevicePageRespVO.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.devicelist; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import java.util.List; + +/** + * @description: 获取设备列表 分页响应实体 + * @author: binda + * @date: 2025/9/18 14:30 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DevicePageRespVO { + private Integer code; + private String msg; + private Integer total; + private List rows; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Row{ + private Long deviceId; + private Long deptId; + private String productCode; + private String productName; + private String modelCode; + private String deviceCode; + private String code; // 设备编号 + private String name; + private String farmland; + private String modelName; + private String userCode; + private Double lng; + private Double lat; + private Long farmlandId; + private String delFlag; + private String loginIp; + private Date loginDate; + private String createBy; + private Date createTime; + private String updateBy; + private Date updateTime; + private String remark; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/login/LoginReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/login/LoginReqVO.java new file mode 100644 index 00000000..9860683e --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/login/LoginReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.login; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 获取公钥 请求实体 + * @author: binda + * @date: 2025/9/18 14:19 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LoginReqVO { + private String username; + private String password; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/login/LoginRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/login/LoginRespVO.java new file mode 100644 index 00000000..ac231b47 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/login/LoginRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.login; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 获取公钥 响应实体 + * @author: binda + * @date: 2025/9/18 14:26 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LoginRespVO { + private String code; + private String msg; + private String token; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/realtime/RealTimeDeviceDataReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/realtime/RealTimeDeviceDataReqVO.java new file mode 100644 index 00000000..96ae89e4 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/realtime/RealTimeDeviceDataReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.realtime; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: TODO + * @author: binda + * @date: 2025/9/26 18:09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RealTimeDeviceDataReqVO { + + /** + * 设备编号 必填 + */ + private String deviceId; + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/realtime/RealTimeDeviceDataRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/realtime/RealTimeDeviceDataRespVO.java new file mode 100644 index 00000000..023e4d88 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/realtime/RealTimeDeviceDataRespVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.realtime; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @description: 设备实时数据 + * @author: binda + * @date: 2025/9/18 14:38 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RealTimeDeviceDataRespVO { + private String deviceId; + private String name; + private String stateText; // 是否在线 中文 + private String stateValue; // 是否在线 编码 + private List controlProperties; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class ControlProperty { + private String id; // 开关标识 + private String name; + private String operateType; // 设备类型 + private String operateValue; + private String value; + private String formatValue; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/updateparams/UpdateDeviceStatusReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/updateparams/UpdateDeviceStatusReqVO.java new file mode 100644 index 00000000..98cd1570 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/updateparams/UpdateDeviceStatusReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.updateparams; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: + * @author: binda + * @date: 2025/9/26 21:01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UpdateDeviceStatusReqVO { + private String deviceId; + private ParamStr paramStr; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class ParamStr{ + // 设备开关名称 + private String Value1; + // 要修改的值 + private String Value11; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/updateparams/UpdateDeviceStatusRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/updateparams/UpdateDeviceStatusRespVO.java new file mode 100644 index 00000000..a1415f4d --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/dto/wf/updateparams/UpdateDeviceStatusRespVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.updateparams; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 更改设备属性 响应实体 + * @author: binda + * @date: 2025/9/18 14:45 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UpdateDeviceStatusRespVO { + private Integer code; + private String msg; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/AbstractDeviceService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/AbstractDeviceService.java new file mode 100644 index 00000000..75df9c09 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/AbstractDeviceService.java @@ -0,0 +1,161 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.service; + +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.*; + +import java.util.List; +import java.util.Map; + +/** + * @description: + * @author: binda + * @date: 2025/9/25 20:38 + */ +public abstract class AbstractDeviceService extends TokenCacheService implements DeviceService{ + + @Override + public UnifiedLoginResponse login(Long tenantId, String deviceId, Object loginRequest) { + String cacheKey = generateCacheKey(getDeviceType(), tenantId, deviceId); + + // 检查缓存中是否有有效token + TokenCacheService.TokenInfo cachedToken = getToken(cacheKey); + if (cachedToken != null && isTokenValid(cacheKey)) { + return UnifiedLoginResponse.success(convertToLoginData(cachedToken)); + } + + // 调用具体设备登录 + UnifiedLoginResponse loginResponse = doLogin(loginRequest); + + if ("200".equals(loginResponse.getCode()) && loginResponse.getData() != null) { + // 缓存token信息 + TokenCacheService.TokenInfo tokenInfo = new TokenCacheService.TokenInfo( + loginResponse.getData().getToken(), + loginResponse.getData().getCurrDate(), + loginResponse.getData().getExpDate(), + loginResponse.getData().getLoginSign() + ); + cacheToken(cacheKey, tokenInfo); + } + + return loginResponse; + } + + @Override + public DeviceListResponse getDeviceList(Long tenantId, String token, Object listRequest) { + // 验证token有效性 + String deviceCacheKey = generateDeviceCacheKey(getDeviceType(), tenantId, token); + + // 先检查设备缓存 + List cachedDevices = getDeviceList(deviceCacheKey); + if (cachedDevices != null && !cachedDevices.isEmpty()) { + return DeviceListResponse.success(cachedDevices); + } + + // 验证token是否有效 + if (!validateToken(tenantId, token)) { + return DeviceListResponse.error("Token无效或已过期"); + } + // TODO: 2025/9/25 如果token过期,直接登录重新获取token + + // 调用具体设备获取列表 + DeviceListResponse listResponse = doGetDeviceList(token, listRequest); + + if ("200".equals(listResponse.getCode()) && listResponse.getData() != null) { + // 缓存设备列表 + cacheDeviceList(deviceCacheKey, listResponse.getData()); + } + + return listResponse; + } + + @Override + public RealTimeDataResponse getRealTimeData(Long tenantId, String token, Object realTimeRequest) { + // 验证token有效性 + if (!validateToken(tenantId, token)) { + return RealTimeDataResponse.error("Token无效或已过期"); + } + + // 调用具体设备获取实时数据 + return doGetRealTimeData(token, realTimeRequest); + } + + @Override + public HistoryDataResponse getHistoryData(Long tenantId, String token, Object historyRequest) { + // 验证token有效性 + if (!validateToken(tenantId, token)) { + return HistoryDataResponse.error("Token无效或已过期"); + } + + // 调用具体设备获取历史数据 + return doGetHistoryData(token, historyRequest); + } + + @Override + public UpdateDeviceResponse updateDeviceProperties(Long tenantId, String token, Object updateRequest) { + // 验证token有效性 + if (!validateToken(tenantId, token)) { + return UpdateDeviceResponse.error("Token无效或已过期"); + } + + // 调用具体设备更新属性 + return doUpdateDeviceProperties(token, updateRequest); + } + + /** + * 具体设备登录逻辑(由子类实现) + */ + protected abstract UnifiedLoginResponse doLogin(Object loginRequest); + + /** + * 具体设备获取列表逻辑(由子类实现) + */ + protected abstract DeviceListResponse doGetDeviceList(String token, Object listRequest); + + /** + * 具体设备获取实时数据逻辑(由子类实现) + */ + protected abstract RealTimeDataResponse doGetRealTimeData(String token, Object realTimeRequest); + + /** + * 默认实现:不支持设备属性更新功能 + * 子类可以重写此方法来实现具体的属性更新逻辑 + */ + protected UpdateDeviceResponse doUpdateDeviceProperties(String token, Object updateRequest) { + return UpdateDeviceResponse.notSupported(); + } + + /** + * 默认实现:不支持历史数据功能 + * 子类可以重写此方法来实现具体的历史数据获取逻辑 + */ + protected HistoryDataResponse doGetHistoryData(String token, Object historyRequest) { + return HistoryDataResponse.notSupported(); + } + + /** + * 转换TokenInfo为LoginData + */ + protected UnifiedLoginResponse.LoginData convertToLoginData(TokenCacheService.TokenInfo tokenInfo) { + return new UnifiedLoginResponse.LoginData( + tokenInfo.getLoginSign(), + tokenInfo.getCurrDate(), + tokenInfo.getExpDate(), + tokenInfo.getToken() + ); + } + + /** + * 验证token有效性 + */ + private boolean validateToken(Long tenantId, String token) { + // 遍历token缓存,查找匹配的token + for (Map.Entry entry : tokenCacheMap.entrySet()) { + if (entry.getKey().startsWith(getDeviceType() + ":" + tenantId + ":") && + token.equals(entry.getValue().getToken()) && + isTokenValid(entry.getKey())) { + return true; + } + } + return false; + } + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/DeviceService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/DeviceService.java new file mode 100644 index 00000000..68dd7270 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/DeviceService.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.service; + +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.*; + +/** + * @description: + * @author: binda + * @data: 2025/9/25 20:35 + */ +public interface DeviceService { + + String getDeviceType(); + + /** + * 登录获取token + */ + UnifiedLoginResponse login(Long tenantId, String deviceId, Object loginRequest); + + /** + * 获取设备列表 + */ + DeviceListResponse getDeviceList(Long tenantId, String token, Object listRequest); + + /** + * 获取实时数据 + */ + RealTimeDataResponse getRealTimeData(Long tenantId, String token, Object realTimeRequest); + + /** + * 获取历史数据 + */ + HistoryDataResponse getHistoryData(Long tenantId, String token, Object historyRequest); + + /** + * 更新设备属性 + */ + UpdateDeviceResponse updateDeviceProperties(Long tenantId, String token, Object updateRequest); + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/HistoryDataStorageService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/HistoryDataStorageService.java new file mode 100644 index 00000000..c4393e92 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/HistoryDataStorageService.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.service; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @description: 设备历史数据持久化 + * @author: binda + * @date: 2025/9/26 20:37 + */ +@Service +public class HistoryDataStorageService { + + // 模拟MySQL表存储 - 实际项目中这里会是MyBatis Mapper或JPA Repository + private final Map> historyDataStorage = new ConcurrentHashMap<>(); + + + public void saveHistoryData(String deviceAddr, List historyData) { + + } + + public List queryHistoryData(String deviceAddr, + Long beginTime, + Long endTime, + Integer page, + Integer limit) { + return null; + } + + public int getTotalCount(String deviceAddr, Long beginTime, Long endTime) { + return 0; + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class HistoryDataEntity { + /** + * 记录表 id + */ + private Integer historyId; + /** + * 节点编号 + */ + private Integer nodeId; + /** + * 设备地址 + */ + private String deviceAddress; + /** + * 模拟量 1 + */ + private String temStr; + private Double temValue; + /** + * 模拟量 2 + */ + private String humStr; + private Double humValue; + /** + * 是否是报警数据 0:正常 1:报警 + */ + private Integer alarmStatus; + /** + * 保存时间(时间戳) + */ + private Long recordTime; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/TokenCacheService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/TokenCacheService.java new file mode 100644 index 00000000..e33bed6a --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/TokenCacheService.java @@ -0,0 +1,140 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.service; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @description: + * @author: binda + * @date: 2025/9/25 20:38 + */ +@Slf4j +public abstract class TokenCacheService { + + public final Map tokenCacheMap = new ConcurrentHashMap<>(); + private final Map> deviceCacheMap = new ConcurrentHashMap<>(); + + /** + * 生成缓存key + * @param deviceType 设备类型 + * @param tenantId 租户ID + * @param identifier 设备表主键ID + * @return + */ + public String generateCacheKey(String deviceType, Long tenantId, String identifier) { + return deviceType + ":" + tenantId + ":" + identifier; + } + + /** + * 生成设别列表key + * @param deviceType 设备类型 + * @param tenantId 租户ID + * @param token 令牌 + * @return + */ + public String generateDeviceCacheKey(String deviceType, Long tenantId, String token) { + return deviceType + ":" + tenantId + ":" + token; + } + /** + * 缓存token信息 + */ + public void cacheToken(String key, TokenInfo tokenInfo) { + tokenCacheMap.put(key, tokenInfo); + } + + /** + * 通过key获取token信息 + */ + public TokenInfo getToken(String key) { + return tokenCacheMap.get(key); + } + + /** + * 验证token是否有效 + */ + public boolean isTokenValid(String key) { + TokenInfo tokenInfo = tokenCacheMap.get(key); + if (tokenInfo == null) { + return false; + } + return tokenInfo.getExpDate() > System.currentTimeMillis(); + } + + /** + * 移除token + */ + public void removeToken(String key) { + tokenCacheMap.remove(key); + } + + // 设备列表缓存相关方法 + public void cacheDeviceList(String key, List deviceList) { + deviceCacheMap.put(key, deviceList); + } + + public List getDeviceList(String key) { + return deviceCacheMap.get(key); + } + + public void removeDeviceList(String key) { + deviceCacheMap.remove(key); + } + + /** + * 定期清除过期token + */ + @Scheduled(fixedRate = 300000) // 每5分钟执行一次 + public void cleanupExpiredTokens() { + long currentTime = System.currentTimeMillis(); + + // 清理过期token + Iterator> tokenIterator = tokenCacheMap.entrySet().iterator(); + while (tokenIterator.hasNext()) { + Map.Entry entry = tokenIterator.next(); + if (entry.getValue().getExpDate() <= currentTime) { + tokenIterator.remove(); + // 同时清理对应的设备缓存 + removeDeviceList(entry.getKey()); + } + } + log.info("清理过期token缓存"); + + // 清理长时间未使用的设备缓存(可选) + } + + /** + * Token信息封装 + */ + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class TokenInfo { + private String token; + private Long currDate; + private Long expDate; + private String loginSign; + } + + /** + * Token信息封装 + */ + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class DeviceInfo { + // 设备编号 + private String deviceCode; + // 设备名称 + private String deviceName; + // 扩展字段,用于存储原始设备信息 + private Map extraInfo; + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/impl/SoilService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/impl/SoilService.java new file mode 100644 index 00000000..4acaafc6 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/impl/SoilService.java @@ -0,0 +1,368 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.service.impl; + +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.DeviceListResponse; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.HistoryDataResponse; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.RealTimeDataResponse; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.UnifiedLoginResponse; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.devicelist.SysUserDeviceReqVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.devicelist.SysUserDeviceRespVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.history.HistoryDataListPageReqVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.history.HistoryDataListPageRespVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.login.UserLoginReqVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.login.UserLoginRespVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.realtime.RealTimeDataReqVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.soil.realtime.RealTimeDataRespVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.service.AbstractDeviceService; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.service.HistoryDataStorageService; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.service.TokenCacheService; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @description: 土壤墒情 + * @author: binda + * @date: 2025/9/25 20:40 + */ +@Service +public class SoilService extends AbstractDeviceService { + + private final HistoryDataStorageService historyDataStorageService; + + public SoilService(HistoryDataStorageService historyDataStorageService) { + this.historyDataStorageService = historyDataStorageService; + } + + @Override + public String getDeviceType() { + return "soil"; + } + + @Override + protected UnifiedLoginResponse doLogin(Object loginRequest) { + try { + // 转换请求参数 + UserLoginReqVO soilRequest = (UserLoginReqVO) loginRequest; + + // TODO: 2025/9/25 调用土壤设备厂商API POST 请求方式 + UserLoginRespVO vendorResponse = callSoilVendorApi(soilRequest); + + // 转换为统一响应格式 + return convertToUnifiedResponse(vendorResponse); + + } catch (Exception e) { + return UnifiedLoginResponse.error("土壤设备登录失败: " + e.getMessage()); + } + } + + @Override + protected DeviceListResponse doGetDeviceList(String token, Object listRequest) { + try { + // 转换请求参数 + SysUserDeviceReqVO soilRequest = (SysUserDeviceReqVO) listRequest; + + // TODO: 2025/9/25 调用土壤设备厂商API获取设备列表 GET 请求方式 + SysUserDeviceRespVO vendorResponse = callSoilDeviceListApi(token, soilRequest); + + // 转换为统一响应格式 + return convertToUnifiedDeviceResponse(vendorResponse); + + } catch (Exception e) { + return DeviceListResponse.error("土壤设备列表获取失败: " + e.getMessage()); + } + } + + @Override + protected RealTimeDataResponse doGetRealTimeData(String token, Object realTimeRequest) { + try { + // 转换请求参数 + RealTimeDataReqVO soilRequest = (RealTimeDataReqVO) realTimeRequest; + + // TODO: 2025/9/26 调用土壤设备厂商API获取实时数据 + RealTimeDataRespVO vendorResponse = callSoilRealTimeDataApi(token, soilRequest); + + // 直接返回原始响应数据,不进行统一转换 + return RealTimeDataResponse.success(vendorResponse); + + } catch (Exception e) { + return RealTimeDataResponse.error("土壤设备实时数据获取失败: " + e.getMessage()); + } + } + + @Override + protected HistoryDataResponse doGetHistoryData(String token, Object historyRequest) { + try { + // 转换请求参数 + HistoryDataListPageReqVO soilRequest = (HistoryDataListPageReqVO) historyRequest; + + // TODO: 2025/9/26 调用土壤设备厂商API获取历史数据 + HistoryDataListPageRespVO vendorResponse = callSoilHistoryDataApi(token, soilRequest); + + // TODO: 2025/9/26 模拟保存到MySQL + saveHistoryDataToDatabase(vendorResponse, soilRequest); + + return HistoryDataResponse.success(vendorResponse); + + } catch (Exception e) { + return HistoryDataResponse.error("土壤设备历史数据获取失败: " + e.getMessage()); + } + } + + + + + private UserLoginRespVO callSoilVendorApi(UserLoginReqVO request) { + // 模拟调用土壤设备厂商API + // 实际实现中这里会是HTTP请求 + UserLoginRespVO response = new UserLoginRespVO(); + response.setCode("200"); + response.setMessage("成功"); + response.setData(new UserLoginRespVO.VendorData()); + response.getData().setLoginSign("soil-login-sign-" + System.currentTimeMillis()); + response.getData().setCurrDate(System.currentTimeMillis()); + response.getData().setExpDate(System.currentTimeMillis() + 3600000); // 1小时后过期 + response.getData().setToken("soil-token-" + System.currentTimeMillis()); + return response; + } + + private UnifiedLoginResponse convertToUnifiedResponse(UserLoginRespVO vendorResponse) { + if (!"200".equals(vendorResponse.getCode())) { + return UnifiedLoginResponse.error(vendorResponse.getMessage()); + } + + UnifiedLoginResponse.LoginData loginData = new UnifiedLoginResponse.LoginData( + vendorResponse.getData().getLoginSign(), + vendorResponse.getData().getCurrDate(), + vendorResponse.getData().getExpDate(), + vendorResponse.getData().getToken() + ); + + return UnifiedLoginResponse.success(loginData); + } + + private SysUserDeviceRespVO callSoilDeviceListApi(String token, SysUserDeviceReqVO request) { + // 模拟调用土壤设备厂商API + SysUserDeviceRespVO response = new SysUserDeviceRespVO(); + response.setCode("200"); + response.setMessage("成功"); + + List deviceList = new ArrayList<>(); + + // 模拟设备数据 + SysUserDeviceRespVO.DeviceInfo device1 = new SysUserDeviceRespVO.DeviceInfo(); + device1.setDeviceAddr("SOIL_001"); + device1.setDeviceName("土壤监测设备1"); + device1.setGroupId("G001"); + device1.setDeviceType("SOIL_MONITOR"); + deviceList.add(device1); + + SysUserDeviceRespVO.DeviceInfo device2 = new SysUserDeviceRespVO.DeviceInfo(); + device2.setDeviceAddr("SOIL_002"); + device2.setDeviceName("土壤监测设备2"); + device2.setGroupId("G001"); + device2.setDeviceType("SOIL_MONITOR"); + deviceList.add(device2); + + response.setData(deviceList); + return response; + } + + private DeviceListResponse convertToUnifiedDeviceResponse(SysUserDeviceRespVO vendorResponse) { + if (!"200".equals(vendorResponse.getCode())) { + return DeviceListResponse.error(vendorResponse.getMessage()); + } + + List unifiedDevices = vendorResponse.getData().stream() + .map(vendorDevice -> { + TokenCacheService.DeviceInfo device = new TokenCacheService.DeviceInfo(); + device.setDeviceCode(vendorDevice.getDeviceAddr()); + device.setDeviceName(vendorDevice.getDeviceName()); + + // 保存原始设备信息到extraInfo + Map extraInfo = new HashMap<>(); + extraInfo.put("groupId", vendorDevice.getGroupId()); + extraInfo.put("deviceType", vendorDevice.getDeviceType()); + extraInfo.put("deviceLng", vendorDevice.getDeviceLng()); + extraInfo.put("deviceLat", vendorDevice.getDeviceLat()); + extraInfo.put("deviceIccId", vendorDevice.getDeviceIccId()); + device.setExtraInfo(extraInfo); + + return device; + }) + .collect(Collectors.toList()); + + return DeviceListResponse.success(unifiedDevices); + } + + private RealTimeDataRespVO callSoilRealTimeDataApi(String token, RealTimeDataReqVO request) { + // 模拟调用土壤设备厂商API获取实时数据 + RealTimeDataRespVO response = new RealTimeDataRespVO(); + response.setCode("200"); + response.setMessage("成功"); + + List deviceList = new ArrayList<>(); + + // 模拟设备1的实时数据 + RealTimeDataRespVO.DeviceInfo device1 = new RealTimeDataRespVO.DeviceInfo(); + device1.setDeviceAddr("SOIL_001"); + device1.setDeviceName("土壤监测设备1"); + device1.setLat(39.9093); + device1.setLng(116.3974); + device1.setStatus("在线"); + device1.setDeviceType("SOIL_MONITOR"); + + List realTimeDataList1 = new ArrayList<>(); + + // 节点1数据 + RealTimeDataRespVO.RealTimeData node1 = new RealTimeDataRespVO.RealTimeData(); + node1.setNodeId(1); + node1.setNodeName("土壤温度监测点"); + node1.setNodeType(1); + node1.setTemName("土壤温度"); + node1.setTemUnit("°C"); + node1.setTemValue(25.6); + node1.setTemValueStr("25.6°C"); + node1.setTemAlarmStatus(0); + realTimeDataList1.add(node1); + + // 节点2数据 + RealTimeDataRespVO.RealTimeData node2 = new RealTimeDataRespVO.RealTimeData(); + node2.setNodeId(2); + node2.setNodeName("土壤湿度监测点"); + node2.setNodeType(2); + node2.setHumName("土壤湿度"); + node2.setHumUnit("%"); + node2.setHumValue("65.2"); + node2.setHumValueStr("65.2%"); + node2.setHumAlarmStatus("0"); + realTimeDataList1.add(node2); + + device1.setData(realTimeDataList1); + deviceList.add(device1); + + // 模拟设备2的实时数据(如果请求了多个设备) + if (request.getDeviceAddrs() != null && request.getDeviceAddrs().contains("SOIL_002")) { + RealTimeDataRespVO.DeviceInfo device2 = new RealTimeDataRespVO.DeviceInfo(); + device2.setDeviceAddr("SOIL_002"); + device2.setDeviceName("土壤监测设备2"); + device2.setLat(39.9193); + device2.setLng(116.4074); + device2.setStatus("离线"); + device2.setDeviceType("SOIL_MONITOR"); + + List realTimeDataList2 = new ArrayList<>(); + RealTimeDataRespVO.RealTimeData node3 = new RealTimeDataRespVO.RealTimeData(); + node3.setNodeId(1); + node3.setNodeName("土壤温度监测点"); + node3.setNodeType(1); + node3.setTemName("土壤温度"); + node3.setTemUnit("°C"); + node3.setTemValue(23.1); + node3.setTemValueStr("23.1°C"); + node3.setTemAlarmStatus(0); + realTimeDataList2.add(node3); + + device2.setData(realTimeDataList2); + deviceList.add(device2); + } + + response.setData(deviceList); + return response; + } + + private HistoryDataListPageRespVO callSoilHistoryDataApi(String token, HistoryDataListPageReqVO request) { + // 模拟调用土壤设备厂商API获取历史数据 + HistoryDataListPageRespVO response = new HistoryDataListPageRespVO(); + + // 设置分页信息 + response.setPages(request.getPages()); + response.setLimit(request.getLimit()); + + // 模拟从厂商API获取的数据 + List rows = generateMockHistoryData( + request.getDeviceAddr(), + Long.parseLong(request.getBeginTime()), + Long.parseLong(request.getEndTime()), + request.getNodeId() + ); + + int total = rows.size(); + int totalPages = (int) Math.ceil((double) total / request.getLimit()); + + // 分页处理 + int fromIndex = (request.getPages() - 1) * request.getLimit(); + int toIndex = Math.min(fromIndex + request.getLimit(), total); + + if (fromIndex >= total) { + response.setRows(new ArrayList<>()); + } else { + response.setRows(rows.subList(fromIndex, toIndex)); + } + + response.setTotalPages(totalPages); + response.setTotal(total); + + return response; + } + + private List generateMockHistoryData(String deviceAddr, Long beginTime, Long endTime, String nodeId) { + List rows = new ArrayList<>(); + Random random = new Random(); + + // 生成模拟数据 - 假设每小时间隔一条数据 + long currentTime = beginTime; + int recordId = 1; + + while (currentTime <= endTime) { + HistoryDataListPageRespVO.Row row = new HistoryDataListPageRespVO.Row(); + row.setHistoryId(recordId++); + row.setNodeId(nodeId != null ? Integer.parseInt(nodeId) : 1); + row.setDeviceAddress(deviceAddr); + + // 模拟温度数据 + double tempValue = 20 + random.nextDouble() * 15; // 20-35°C + row.setTemValue(tempValue); + row.setTemStr(String.format("%.1f°C", tempValue)); + + // 模拟湿度数据 + double humidityValue = 30 + random.nextDouble() * 40; // 30-70% + row.setHumValue(humidityValue); + row.setHumStr(String.format("%.1f%%", humidityValue)); + + // 模拟报警状态(5%的概率报警) + row.setAlarmStatus(random.nextDouble() < 0.05 ? 1 : 0); + row.setRecordTime(currentTime); + + rows.add(row); + currentTime += 3600000; // 增加1小时 + } + + return rows; + } + + private void saveHistoryDataToDatabase(HistoryDataListPageRespVO response, HistoryDataListPageReqVO request) { + if (historyDataStorageService != null && response.getRows() != null) { + // 转换为实体类 + List entities = response.getRows().stream() + .map(row -> { + HistoryDataStorageService.HistoryDataEntity entity = new HistoryDataStorageService.HistoryDataEntity(); + entity.setHistoryId(row.getHistoryId()); + entity.setNodeId(row.getNodeId()); + entity.setDeviceAddress(row.getDeviceAddress()); + entity.setTemStr(row.getTemStr()); + entity.setTemValue(row.getTemValue()); + entity.setHumStr(row.getHumStr()); + entity.setHumValue(row.getHumValue()); + entity.setAlarmStatus(row.getAlarmStatus()); + entity.setRecordTime(row.getRecordTime()); + return entity; + }) + .collect(Collectors.toList()); + + // 保存到模拟数据库 + historyDataStorageService.saveHistoryData(request.getDeviceAddr(), entities); + } + } + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/impl/WaterFertilizerService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/impl/WaterFertilizerService.java new file mode 100644 index 00000000..5e4418bb --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/equipmentproducer/service/impl/WaterFertilizerService.java @@ -0,0 +1,332 @@ +package cn.iocoder.yudao.module.farm.manager.equipmentproducer.service.impl; + +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.DeviceListResponse; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.RealTimeDataResponse; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.UnifiedLoginResponse; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.UpdateDeviceResponse; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.devicelist.DevicePageReqVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.devicelist.DevicePageRespVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.login.LoginReqVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.login.LoginRespVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.realtime.RealTimeDeviceDataReqVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.realtime.RealTimeDeviceDataRespVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.updateparams.UpdateDeviceStatusReqVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.dto.wf.updateparams.UpdateDeviceStatusRespVO; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.service.AbstractDeviceService; +import cn.iocoder.yudao.module.farm.manager.equipmentproducer.service.TokenCacheService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @description: 水肥机 + * @author: binda + * @date: 2025/9/25 20:42 + */ +@Service +public class WaterFertilizerService extends AbstractDeviceService { + + @Override + public String getDeviceType() { + return "water_fertilizer"; + } + + @Override + protected UnifiedLoginResponse doLogin(Object loginRequest) { + try { + // 转换请求参数 + LoginReqVO wfRequest = (LoginReqVO) loginRequest; + + // TODO: 2025/9/25 调用水肥机设备厂商API POST 请求方式 + LoginRespVO vendorResponse = callWFVendorApi(wfRequest); + + // 转换为统一响应格式 + return convertToUnifiedResponse(vendorResponse); + + } catch (Exception e) { + return UnifiedLoginResponse.error("水肥机设备登录失败: " + e.getMessage()); + } + } + + @Override + protected DeviceListResponse doGetDeviceList(String token, Object listRequest) { + try { + // 转换请求参数 + DevicePageReqVO wfRequest = (DevicePageReqVO) listRequest; + + // TODO: 2025/9/25 调用水肥机设备厂商API获取设备列表 GET 请求方式 + DevicePageRespVO vendorResponse = callWFDeviceListApi(token, wfRequest); + + // 转换为统一响应格式 + return convertToUnifiedDeviceResponse(vendorResponse); + + } catch (Exception e) { + return DeviceListResponse.error("水肥机设备列表获取失败: " + e.getMessage()); + } + } + + @Override + protected RealTimeDataResponse doGetRealTimeData(String token, Object realTimeRequest) { + try { + // 转换请求参数 + RealTimeDeviceDataReqVO wfRequest = (RealTimeDeviceDataReqVO) realTimeRequest; + + // TODO: 2025/9/26 调用水肥机设备厂商API获取实时数据 + RealTimeDeviceDataRespVO vendorResponse = callWFRealTimeDataApi(token, wfRequest); + + // 直接返回原始响应数据,不进行统一转换 + return RealTimeDataResponse.success(vendorResponse); + + } catch (Exception e) { + return RealTimeDataResponse.error("水肥机设备实时数据获取失败: " + e.getMessage()); + } + } + + @Override + protected UpdateDeviceResponse doUpdateDeviceProperties(String token, Object updateRequest) { + try { + // 转换请求参数 + UpdateDeviceStatusReqVO wfRequest = (UpdateDeviceStatusReqVO) updateRequest; + + // TODO: 2025/9/26 调用水肥机设备厂商API更新设备属性 + UpdateDeviceStatusRespVO vendorResponse = callWFUpdateDeviceApi(token, wfRequest); + + // 转换为统一响应格式 + return convertToUnifiedUpdateResponse(vendorResponse); + + } catch (Exception e) { + return UpdateDeviceResponse.error("水肥机设备属性更新失败: " + e.getMessage()); + } + } + + + + + + + + + + + + private LoginRespVO callWFVendorApi(LoginReqVO request) { + // 模拟调用水肥机设备厂商API + LoginRespVO response = new LoginRespVO(); + response.setCode("200"); + response.setMsg("成功"); + response.setToken("wf-token-" + System.currentTimeMillis()); + return response; + } + + private UnifiedLoginResponse convertToUnifiedResponse(LoginRespVO vendorResponse) { + if (!"200".equals(vendorResponse.getCode())) { + return UnifiedLoginResponse.error(vendorResponse.getMsg()); + } + + // 水肥机响应缺少一些字段,设置默认值 + long currentTime = System.currentTimeMillis(); + UnifiedLoginResponse.LoginData loginData = new UnifiedLoginResponse.LoginData( + "wf-login-sign-" + currentTime, // 生成登录标识 + currentTime, // token生成时间 + currentTime + 3600000 * 2, // 2小时后过期 + vendorResponse.getToken() // 实际token + ); + + return UnifiedLoginResponse.success(loginData); + } + + private DevicePageRespVO callWFDeviceListApi(String token, DevicePageReqVO request) { + // 模拟调用水肥机设备厂商API + DevicePageRespVO response = new DevicePageRespVO(); + response.setCode(200); + response.setMsg("成功"); + response.setTotal(2); + + List rows = new ArrayList<>(); + + // 模拟设备数据 + DevicePageRespVO.Row row1 = new DevicePageRespVO.Row(); + row1.setDeviceId(1L); + row1.setCode("WF_001"); + row1.setName("水肥机设备1"); + row1.setLng(116.3974); + row1.setLat(39.9093); + rows.add(row1); + + DevicePageRespVO.Row row2 = new DevicePageRespVO.Row(); + row2.setDeviceId(2L); + row2.setCode("WF_002"); + row2.setName("水肥机设备2"); + row2.setLng(116.4074); + row2.setLat(39.9193); + rows.add(row2); + + response.setRows(rows); + return response; + } + + private DeviceListResponse convertToUnifiedDeviceResponse(DevicePageRespVO vendorResponse) { + if (vendorResponse.getCode() != 200) { + return DeviceListResponse.error(vendorResponse.getMsg()); + } + + List unifiedDevices = vendorResponse.getRows().stream() + .map(vendorDevice -> { + TokenCacheService.DeviceInfo device = new TokenCacheService.DeviceInfo(); + device.setDeviceCode(vendorDevice.getCode()); + device.setDeviceName(vendorDevice.getName()); + + // 保存原始设备信息到extraInfo + Map extraInfo = new HashMap<>(); + extraInfo.put("deviceId", vendorDevice.getDeviceId()); + extraInfo.put("deptId", vendorDevice.getDeptId()); + extraInfo.put("lng", vendorDevice.getLng()); + extraInfo.put("lat", vendorDevice.getLat()); + extraInfo.put("farmland", vendorDevice.getFarmland()); + device.setExtraInfo(extraInfo); + + return device; + }) + .collect(Collectors.toList()); + + return DeviceListResponse.success(unifiedDevices); + } + + private RealTimeDeviceDataRespVO callWFRealTimeDataApi(String token, RealTimeDeviceDataReqVO request) { + // 模拟调用水肥机设备厂商API获取实时数据 + RealTimeDeviceDataRespVO response = new RealTimeDeviceDataRespVO(); + response.setDeviceId(request.getDeviceId()); + response.setName("水肥机设备-" + request.getDeviceId()); + response.setStateText("在线"); + response.setStateValue("online"); + + List controlProperties = new ArrayList<>(); + + // 模拟控制属性1 - 水泵状态 + RealTimeDeviceDataRespVO.ControlProperty prop1 = new RealTimeDeviceDataRespVO.ControlProperty(); + prop1.setId("pump_switch"); + prop1.setName("水泵开关"); + prop1.setOperateType("switch"); + prop1.setOperateValue("on,off"); + prop1.setValue("on"); + prop1.setFormatValue("开启"); + controlProperties.add(prop1); + + // 模拟控制属性2 - 施肥状态 + RealTimeDeviceDataRespVO.ControlProperty prop2 = new RealTimeDeviceDataRespVO.ControlProperty(); + prop2.setId("fertilizer_switch"); + prop2.setName("施肥开关"); + prop2.setOperateType("switch"); + prop2.setOperateValue("on,off"); + prop2.setValue("off"); + prop2.setFormatValue("关闭"); + controlProperties.add(prop2); + + // 模拟控制属性3 - 流量监测 + RealTimeDeviceDataRespVO.ControlProperty prop3 = new RealTimeDeviceDataRespVO.ControlProperty(); + prop3.setId("flow_rate"); + prop3.setName("水流量"); + prop3.setOperateType("monitor"); + prop3.setOperateValue(""); + prop3.setValue("12.5"); + prop3.setFormatValue("12.5 L/min"); + controlProperties.add(prop3); + + // 模拟控制属性4 - EC值 + RealTimeDeviceDataRespVO.ControlProperty prop4 = new RealTimeDeviceDataRespVO.ControlProperty(); + prop4.setId("ec_value"); + prop4.setName("EC值"); + prop4.setOperateType("monitor"); + prop4.setOperateValue(""); + prop4.setValue("2.1"); + prop4.setFormatValue("2.1 mS/cm"); + controlProperties.add(prop4); + + // 模拟控制属性5 - PH值 + RealTimeDeviceDataRespVO.ControlProperty prop5 = new RealTimeDeviceDataRespVO.ControlProperty(); + prop5.setId("ph_value"); + prop5.setName("PH值"); + prop5.setOperateType("monitor"); + prop5.setOperateValue(""); + prop5.setValue("6.8"); + prop5.setFormatValue("6.8"); + controlProperties.add(prop5); + + response.setControlProperties(controlProperties); + return response; + } + + private UpdateDeviceStatusRespVO callWFUpdateDeviceApi(String token, UpdateDeviceStatusReqVO request) { + // 模拟调用水肥机设备厂商API更新设备属性 + UpdateDeviceStatusRespVO response = new UpdateDeviceStatusRespVO(); + + // 模拟设备控制逻辑 + String deviceId = request.getDeviceId(); + String switchName = request.getParamStr().getValue1(); + String newValue = request.getParamStr().getValue11(); + + System.out.println("更新水肥机设备属性 - 设备ID: " + deviceId + + ", 开关名称: " + switchName + ", 新值: " + newValue); + + // 模拟不同的控制逻辑 + if ("pump_switch".equals(switchName)) { + if ("on".equals(newValue)) { + System.out.println("水泵开关已开启"); + response.setCode(200); + response.setMsg("水泵开启成功"); + } else if ("off".equals(newValue)) { + System.out.println("水泵开关已关闭"); + response.setCode(200); + response.setMsg("水泵关闭成功"); + } else { + response.setCode(400); + response.setMsg("无效的水泵开关值: " + newValue); + } + } else if ("fertilizer_switch".equals(switchName)) { + if ("on".equals(newValue)) { + System.out.println("施肥开关已开启"); + response.setCode(200); + response.setMsg("施肥开启成功"); + } else if ("off".equals(newValue)) { + System.out.println("施肥开关已关闭"); + response.setCode(200); + response.setMsg("施肥关闭成功"); + } else { + response.setCode(400); + response.setMsg("无效的施肥开关值: " + newValue); + } + } else if ("water_flow".equals(switchName)) { + try { + double flowRate = Double.parseDouble(newValue); + if (flowRate > 0 && flowRate <= 100) { + System.out.println("水流量设置为: " + flowRate + " L/min"); + response.setCode(200); + response.setMsg("水流量设置成功"); + } else { + response.setCode(400); + response.setMsg("水流量值超出范围 (0-100 L/min)"); + } + } catch (NumberFormatException e) { + response.setCode(400); + response.setMsg("无效的水流量值: " + newValue); + } + } else { + response.setCode(404); + response.setMsg("不支持的设备开关: " + switchName); + } + + return response; + } + + private UpdateDeviceResponse convertToUnifiedUpdateResponse(UpdateDeviceStatusRespVO vendorResponse) { + if (vendorResponse.getCode() == 200) { + return UpdateDeviceResponse.success(vendorResponse); + } else { + return UpdateDeviceResponse.error(vendorResponse.getMsg()); + } + } +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/baseinfo/BaseInfoServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/baseinfo/BaseInfoServiceImpl.java index 8b9c7ec9..659e7ad9 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/baseinfo/BaseInfoServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/baseinfo/BaseInfoServiceImpl.java @@ -378,6 +378,7 @@ public class BaseInfoServiceImpl implements BaseInfoService { public CommonResult> getBaseInfoList(FarmBaseInfoReqVO req) { LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); wrapperX.eq(BaseInfoDO::getTenantId, req.getTenantId()); + wrapperX.eqIfPresent(BaseInfoDO::getId, req.getBaseId()); wrapperX.eq(BaseInfoDO::getDeleted, CommonConstants.NO_CODE); List list = baseInfoMapper.selectList(wrapperX); diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/deviceinfo/DeviceInfoService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/deviceinfo/DeviceInfoService.java index 5f9b4542..311fcb2e 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/deviceinfo/DeviceInfoService.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/deviceinfo/DeviceInfoService.java @@ -103,6 +103,11 @@ public interface DeviceInfoService { * @return */ List getBaseAndDeviceInfoList(String baseId); + List getBaseAndDeviceInfoList(String baseId,String plotId); Map getDeviceTypeNameMap(String tenantId); + + List getImage(String deviceType); + + DeviceStateRespVO countDeviceState(String baseId, String tenantId); } \ No newline at end of file diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/deviceinfo/DeviceInfoServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/deviceinfo/DeviceInfoServiceImpl.java index 02d9c9d3..19bf2117 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/deviceinfo/DeviceInfoServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/deviceinfo/DeviceInfoServiceImpl.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.farm.service.deviceinfo; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.IdUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.farm.controller.admin.api.vo.*; import cn.iocoder.yudao.module.farm.controller.admin.deviceinfo.vo.DeviceInfoPageReqVO; import cn.iocoder.yudao.module.farm.controller.admin.deviceinfo.vo.DeviceInfoSaveReqVO; @@ -56,8 +57,8 @@ public class DeviceInfoServiceImpl implements DeviceInfoService { private BaseInfoMapper baseInfoMapper; @Resource private PlotInfoMapper plotInfoMapper; - @Resource - private DeviceManager deviceManager; +// @Resource +// private DeviceManager deviceManager; @Override public String createDeviceInfo(DeviceInfoSaveReqVO createReqVO) { @@ -139,9 +140,9 @@ public class DeviceInfoServiceImpl implements DeviceInfoService { target.setDeviceTypeName(map.getOrDefault(target.getDeviceType(), "")); // 从设备商服务 获取设备实时/历史数据 - DeviceInfoDetailV2RespVO realData = deviceManager.getRealData(id); - target.setSoilInfo(realData.getSoilInfo()); - target.setWfInfo(realData.getWfInfo()); +// DeviceInfoDetailV2RespVO realData = deviceManager.getRealData(id); +// target.setSoilInfo(realData.getSoilInfo()); +// target.setWfInfo(realData.getWfInfo()); return target; } @@ -181,7 +182,7 @@ public class DeviceInfoServiceImpl implements DeviceInfoService { dtList.add(new DeviceStateRespVO.DeviceType(v1, v2)); } - DeviceStateRespVO res = deviceInfoMapper.countDeviceState(req.getTenantId()); + DeviceStateRespVO res = deviceInfoMapper.countDeviceState("",req.getTenantId()); res.setDeviceTypeList(dtList); return success(res); } @@ -196,6 +197,17 @@ public class DeviceInfoServiceImpl implements DeviceInfoService { return deviceInfoMapper.selectList(DeviceInfoDO::getBaseId,baseId); } + @Override + public List getBaseAndDeviceInfoList(String baseId, String plotId) { + LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); + wrapperX.eq(DeviceInfoDO::getTenantId, String.valueOf(getLoginUser().getTenantId())); + wrapperX.eq(DeviceInfoDO::getDeleted, CommonConstants.NO_CODE); + + wrapperX.eqIfPresent(DeviceInfoDO::getBaseId, baseId); + wrapperX.eqIfPresent(DeviceInfoDO::getPlotId, plotId); + return deviceInfoMapper.selectList(wrapperX); + } + @Override public Map getDeviceTypeNameMap(String tenantId) { List deviceClassifyDOS = deviceClassifyMapper.selectList(DeviceClassifyDO::getTenantId, tenantId); @@ -204,4 +216,14 @@ public class DeviceInfoServiceImpl implements DeviceInfoService { .collect(Collectors.toMap(e -> e.getId().toString(), DeviceClassifyDO::getName)); } + @Override + public List getImage(String deviceType) { + DeviceClassifyDO dc = deviceClassifyMapper.selectOne(DeviceClassifyDO::getId, deviceType); + return dc.getImageList(); + } + + @Override + public DeviceStateRespVO countDeviceState(String baseId,String tenantId) { + return deviceInfoMapper.countDeviceState(baseId,tenantId); + } } \ No newline at end of file diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/home/HomeServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/home/HomeServiceImpl.java index b807ac19..95aae3a4 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/home/HomeServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/home/HomeServiceImpl.java @@ -250,7 +250,7 @@ public class HomeServiceImpl implements HomeService { private BaseOverviewInfo getCompanyInfo() { LoginUser user = getLoginUser(); int baseCount = baseInfoService.getBaseCount(user.getTenantId()); // 基地数量 - int cropCount = cropFarmingCenterService.getCropCount(user.getTenantId()); // 作物数mong量 + int cropCount = cropFarmingCenterService.getCropCount(user.getTenantId()); // 作物数量 // Double temp = cropFarmingCenterService.getTotalArea(user.getTenantId()); // 总面积 Double temp = baseInfoService.getBaseTotalArea(user.getTenantId().toString()); // 总面积 int totalArea = 0; diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/productionplan/ProductionPlanService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/productionplan/ProductionPlanService.java index bd39b5cd..42f70b82 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/productionplan/ProductionPlanService.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/productionplan/ProductionPlanService.java @@ -8,6 +8,9 @@ import cn.iocoder.yudao.module.farm.controller.admin.productionplan.vo.Productio import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; import java.math.BigDecimal; import java.util.List; @@ -201,4 +204,27 @@ public interface ProductionPlanService { * @return 获取该地块的计划数量 */ int getPlanCount(String plotId); -} \ No newline at end of file + + /** + * 基地维护 统计在种物种,地块,地块面积 + * @param baseId + * @param tenantId + * @return int[0]: 在种作物数量 + * int[1]: 在种地块数量 + * int[2]: 在种地块面积 + */ + CultivatingInfo getCultivatingInfo(String baseId, String tenantId); + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class CultivatingInfo { + // 在种物种数量 + private Integer cultivatingSpeciesCount; + // 在种地块数量 + private Integer cultivatingPlotCount; + // 在种地块面积 +// private Integer cultivatingPlotAreaCount; + + } + } \ No newline at end of file diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/productionplan/ProductionPlanServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/productionplan/ProductionPlanServiceImpl.java index ef0a6cdf..160d32e5 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/productionplan/ProductionPlanServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/productionplan/ProductionPlanServiceImpl.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.farm.dal.dataobject.baseinfo.BaseInfoDO; import cn.iocoder.yudao.module.farm.dal.dataobject.specieslibrary.SpeciesLibraryDO; import cn.iocoder.yudao.module.farm.dal.mysql.baseinfo.BaseInfoMapper; import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper; +import cn.iocoder.yudao.module.farm.enums.CommonConstants; import cn.iocoder.yudao.module.farm.utils.DateUtils; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.apache.commons.lang3.ObjectUtils; @@ -141,6 +142,7 @@ public class ProductionPlanServiceImpl implements ProductionPlanService { QueryWrapper qw = new QueryWrapper<>(); qw.eq("tenant_id", user.getTenantId()); + qw.eq("plan_status", PLAN_STATUS_2); List productionPlanDOS = productionPlanMapper.selectList(qw); // 按基地ID分组 @@ -406,4 +408,13 @@ public class ProductionPlanServiceImpl implements ProductionPlanService { List planDOList = productionPlanMapper.selectList("plot_id", plotId); return planDOList.size(); } + + @Override + public CultivatingInfo getCultivatingInfo(String baseId, String tenantId) { + int cultivatingSpeciesCount = this.getGrowingCropCount(baseId); + int cultivatingPlotCount = this.getGrowingPlotCount(baseId); + return new CultivatingInfo(cultivatingSpeciesCount,cultivatingPlotCount); + } + + } \ No newline at end of file diff --git a/yudao-module-farm/src/main/resources/mapper/deviceinfo/DeviceInfoMapper.xml b/yudao-module-farm/src/main/resources/mapper/deviceinfo/DeviceInfoMapper.xml index 2b6bc3c4..1d445389 100644 --- a/yudao-module-farm/src/main/resources/mapper/deviceinfo/DeviceInfoMapper.xml +++ b/yudao-module-farm/src/main/resources/mapper/deviceinfo/DeviceInfoMapper.xml @@ -36,6 +36,15 @@ SUM(CASE WHEN device_state = 1 THEN 1 ELSE 0 END) as totalOnlineDevices, SUM(CASE WHEN device_state != 1 THEN 1 ELSE 0 END) as totalOfflineDevices FROM farm_device_info - WHERE tenant_id = #{tenantId} AND deleted = b'0' + + deleted = b'0' + + AND base_id = #{baseId} + + + AND tenant_id = #{tenantId} + + + \ No newline at end of file diff --git a/yudao-module-farm/src/main/resources/mapper/farmingrecord/FarmingRecordMapper.xml b/yudao-module-farm/src/main/resources/mapper/farmingrecord/FarmingRecordMapper.xml index d613b620..516dedaf 100644 --- a/yudao-module-farm/src/main/resources/mapper/farmingrecord/FarmingRecordMapper.xml +++ b/yudao-module-farm/src/main/resources/mapper/farmingrecord/FarmingRecordMapper.xml @@ -14,9 +14,9 @@ resultType="cn.iocoder.yudao.module.farm.controller.admin.api.vo.FarmingDistributionRespVO"> SELECT COUNT(*) as totalCount, - SUM(CASE WHEN task_status = 0 THEN 1 ELSE 0 END) as notStart, - SUM(CASE WHEN task_status = 1 THEN 1 ELSE 0 END) as executingStatusCount, - SUM(CASE WHEN task_status = 2 THEN 1 ELSE 0 END) as completedStatusCount + COALESCE(SUM(CASE WHEN task_status = 0 THEN 1 ELSE 0 END),0) as notStart, + COALESCE(SUM(CASE WHEN task_status = 1 THEN 1 ELSE 0 END),0) as executingStatusCount, + COALESCE(SUM(CASE WHEN task_status = 2 THEN 1 ELSE 0 END),0) as completedStatusCount FROM farm_farming_record del_status = 0 diff --git a/yudao-module-farm/src/main/resources/mapper/productionplan/ProductionPlanMapper.xml b/yudao-module-farm/src/main/resources/mapper/productionplan/ProductionPlanMapper.xml index bda27661..dd39796e 100644 --- a/yudao-module-farm/src/main/resources/mapper/productionplan/ProductionPlanMapper.xml +++ b/yudao-module-farm/src/main/resources/mapper/productionplan/ProductionPlanMapper.xml @@ -14,6 +14,7 @@ from farm_production_plan where tenant_id = #{tenantId} and deleted = 0 + and plan_status = 2