feat (farm): 微信端-设备列表 , PC端扫描二维码

-
This commit is contained in:
达富斌
2025-09-27 19:27:28 +08:00
parent 91c375f039
commit 05b4b8f088
9 changed files with 185 additions and 29 deletions

View File

@@ -3,14 +3,17 @@ package cn.iocoder.yudao.module.farm.controller.admin.home;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.farm.controller.admin.home.vo.BaseNameVO;
import cn.iocoder.yudao.module.farm.controller.admin.home.vo.HomeInfo;
import cn.iocoder.yudao.module.farm.controller.admin.home.vo.QrDetailsRespVO;
import cn.iocoder.yudao.module.farm.service.home.HomeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -49,5 +52,98 @@ public class HomeController {
return success(homeService.getBaseNameList());
}
@PermitAll
@Operation(summary = "农场首页-扫描二维码")
@GetMapping("/scan-qr")
@Parameter(name = "baseId", description = "基地ID")
public CommonResult<QrDetailsRespVO> scanQrCodes(@RequestParam("baseId") String baseId) {
QrDetailsRespVO mockData = new QrDetailsRespVO();
// 设置基地基本信息
mockData.setBaseName("阳光农业示范基地");
mockData.setBaseManagerName("张伟");
mockData.setBaseArea(500);
mockData.setPlotCount(3);
// 创建地块列表
List<QrDetailsRespVO.PlotInfo> plotInfoList = new ArrayList<>();
// 第一个地块
QrDetailsRespVO.PlotInfo plot1 = new QrDetailsRespVO.PlotInfo();
plot1.setPlotName("蔬菜种植区A");
plot1.setPlotManagerName("李丽");
plot1.setPlotArea(150);
List<QrDetailsRespVO.DeviceInfo> deviceInfos1 = new ArrayList<>();
QrDetailsRespVO.DeviceInfo device1 = new QrDetailsRespVO.DeviceInfo();
device1.setDeviceUniqueId("SENSOR-001-XYZ-2024");
device1.setDeviceTypeName("土壤湿度传感器");
device1.setDeviceStateName(1);
deviceInfos1.add(device1);
QrDetailsRespVO.DeviceInfo device2 = new QrDetailsRespVO.DeviceInfo();
device2.setDeviceUniqueId("CAM-002-ABC-2024");
device2.setDeviceTypeName("高清监控摄像头");
device2.setDeviceStateName(1);
deviceInfos1.add(device2);
plot1.setDeviceInfos(deviceInfos1);
plotInfoList.add(plot1);
// 第二个地块
QrDetailsRespVO.PlotInfo plot2 = new QrDetailsRespVO.PlotInfo();
plot2.setPlotName("水果种植区B");
plot2.setPlotManagerName("王强");
plot2.setPlotArea(200);
List<QrDetailsRespVO.DeviceInfo> deviceInfos2 = new ArrayList<>();
QrDetailsRespVO.DeviceInfo device3 = new QrDetailsRespVO.DeviceInfo();
device3.setDeviceUniqueId("SENSOR-003-DEF-2024");
device3.setDeviceTypeName("温湿度传感器");
device3.setDeviceStateName(2);
deviceInfos2.add(device3);
QrDetailsRespVO.DeviceInfo device4 = new QrDetailsRespVO.DeviceInfo();
device4.setDeviceUniqueId("VALVE-004-GHI-2024");
device4.setDeviceTypeName("智能灌溉阀门");
device4.setDeviceStateName(4);
deviceInfos2.add(device4);
plot2.setDeviceInfos(deviceInfos2);
plotInfoList.add(plot2);
// 第三个地块
QrDetailsRespVO.PlotInfo plot3 = new QrDetailsRespVO.PlotInfo();
plot3.setPlotName("粮食作物区C");
plot3.setPlotManagerName("赵敏");
plot3.setPlotArea(150);
List<QrDetailsRespVO.DeviceInfo> deviceInfos3 = new ArrayList<>();
QrDetailsRespVO.DeviceInfo device5 = new QrDetailsRespVO.DeviceInfo();
device5.setDeviceUniqueId("SENSOR-005-JKL-2024");
device5.setDeviceTypeName("光照强度传感器");
device5.setDeviceStateName(3);
deviceInfos3.add(device5);
QrDetailsRespVO.DeviceInfo device6 = new QrDetailsRespVO.DeviceInfo();
device6.setDeviceUniqueId("WEATHER-006-MNO-2024");
device6.setDeviceTypeName("微型气象站");
device6.setDeviceStateName(1);
deviceInfos3.add(device6);
QrDetailsRespVO.DeviceInfo device7 = new QrDetailsRespVO.DeviceInfo();
device7.setDeviceUniqueId("CAM-007-PQR-2024");
device7.setDeviceTypeName("全景监控摄像头");
device7.setDeviceStateName(0);
deviceInfos3.add(device7);
plot3.setDeviceInfos(deviceInfos3);
plotInfoList.add(plot3);
// 设置地块列表到基地
mockData.setPlotInfo(plotInfoList);
return success(mockData);
}
}

View File

@@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.farm.controller.admin.home.vo;
import cn.iocoder.yudao.module.farm.controller.admin.deviceinfo.vo.v2.DeviceInfoDetailV2RespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @description: 二维码详情
* @author: binda
* @date: 2025/9/27 16:35
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QrDetailsRespVO {
@Schema(description = "基地名称")
private String baseName;
@Schema(description = "基地管理员-姓名")
private String baseManagerName;
@Schema(description = "基地面积")
private Integer baseArea;
@Schema(description = "地块数量")
private Integer plotCount;
@Schema(description = "基地所属地块列表")
private List<PlotInfo> plotInfo;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class PlotInfo {
@Schema(description = "地块名称")
private String plotName;
@Schema(description = "地块管理员-姓名")
private String plotManagerName;
@Schema(description = "地块面积")
private Integer plotArea;
@Schema(description = "地块绑定设备信息列表")
private List<DeviceInfo> deviceInfos;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class DeviceInfo {
@Schema(description = "设备全局唯一标识(设备厂商提供)")
private String deviceUniqueId;
@Schema(description = "设备类型 (设备类型-名称)")
private String deviceTypeName;
@Schema(description = "设备状态:0-未激活,1-在线,2-离线,3-维护中,4-故障")
private Integer deviceStateName;
@Schema(description = "土壤墒情")
private DeviceInfoDetailV2RespVO.SoilInfo soilInfo;
@Schema(description = "水肥机")
private DeviceInfoDetailV2RespVO.WfInfo wfInfo;
}
}

View File

@@ -98,6 +98,7 @@ public class WxController {
int cultivatingSpecies = cultivatingInfo.getCultivatingSpeciesCount(); // 在种物种
int cultivatingPlotCount = cultivatingInfo.getCultivatingPlotCount(); // 在种地块
int plotCount = plotInfos.size();
DeviceStateRespVO ds = deviceInfoService.countDeviceState(baseId, String.valueOf(getLoginUser().getTenantId()));
BaseInfoDO b = baseInfoService.getBaseInfo(baseId);
DeviceInfoRespVO res = new DeviceInfoRespVO();
@@ -108,6 +109,9 @@ public class WxController {
res.setCultivatingPlotCount(cultivatingPlotCount);
res.setPlotCount(plotCount);
res.setCultivatingSpecies(cultivatingSpecies);
res.setTotal(ds.getTotalDevices());
res.setOnlineTotal(ds.getTotalOnlineDevices());
res.setOfflineTotal(ds.getTotalOfflineDevices());
res.setPlotInfos(plotInfos);
return CommonResult.success(res);
}
@@ -134,14 +138,10 @@ public class WxController {
private List<DeviceInfoRespVO.DeviceDetail> getDeviceInfos(String baseId, String plotId) {
Map<String, String> dtMap = deviceInfoService.getDeviceTypeNameMap(String.valueOf(getLoginUser().getTenantId()));
List<DeviceInfoDO> bdList = deviceInfoService.getBaseAndDeviceInfoList(baseId, plotId);
DeviceStateRespVO ds = deviceInfoService.countDeviceState(baseId, String.valueOf(getLoginUser().getTenantId()));
return bdList.stream().map(e -> {
List<String> 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());

View File

@@ -30,6 +30,12 @@ public class DeviceInfoRespVO {
private Integer plotCount;
@Schema(description = "在种物种数量")
private Integer cultivatingSpecies;
@Schema(description = "设备总数")
private Integer total;
@Schema(description = "在线设备数量")
private Integer onlineTotal;
@Schema(description = "离线设备数量")
private Integer offlineTotal;
@Schema(description = "地块列表")
private List<PlotInfo> plotInfos;
@@ -55,13 +61,6 @@ public class DeviceInfoRespVO {
@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;

View File

@@ -87,9 +87,6 @@ public class DeviceConst {
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; // 报警

View File

@@ -28,23 +28,23 @@ public class DeviceConf {
@Data
public static class Global {
private String url21; // 用户登录
private String url21; // 登录获取token POST
private String url22; // 获取登录用户信息
private String url23; // 获取子用户信息
private String url24; // 设备报警通知记录
private String url25; // 获取用户区域
private String url26; // 获取用户设备
private String url26; // 获取设备列表 GET
private String url27; // 批量获取摄像头设备信息
private String url28; // 获取设备实时数据
private String url28; // 获取实时数据 GET
private String url29; // 区域绑定设备
}
@Data
public static class Soil {
private String url41; // 墒情设备, 获取设备全部信息
private String url42; // 墒情设备, 更新设备信息
private String url43; // 墒情设备, 更新节点信息
private String url44; // 墒情设备, 获取历史数据
private String url41; // 土壤墒情设备, 获取设备全部信息
private String url42; // 土壤墒情设备, 更新设备信息
private String url43; // 土壤墒情设备, 更新节点信息
private String url44; // 土壤墒情设备, 获取历史数据 GET
}
@Data
@@ -52,10 +52,10 @@ public class DeviceConf {
private String hosts;
private String username;
private String password;
private String url1;
private String url2;
private String url3;
private String url4;
private String url1; // 登录获取token POST
private String url2; // 获取设备列表 GET
private String url3; // 获取实时数据 GET
private String url4; // 更新设备属性 POST
}

View File

@@ -79,7 +79,7 @@ public class SoilService extends AbstractDeviceService {
// 转换请求参数
RealTimeDataReqVO soilRequest = (RealTimeDataReqVO) realTimeRequest;
// TODO: 2025/9/26 调用土壤设备厂商API获取实时数据
// TODO: 2025/9/26 调用土壤设备厂商API获取实时数据 GET 请求方式
RealTimeDataRespVO vendorResponse = callSoilRealTimeDataApi(token, soilRequest);
// 直接返回原始响应数据,不进行统一转换
@@ -96,7 +96,7 @@ public class SoilService extends AbstractDeviceService {
// 转换请求参数
HistoryDataListPageReqVO soilRequest = (HistoryDataListPageReqVO) historyRequest;
// TODO: 2025/9/26 调用土壤设备厂商API获取历史数据
// TODO: 2025/9/26 调用土壤设备厂商API获取历史数据 GET 请求方式
HistoryDataListPageRespVO vendorResponse = callSoilHistoryDataApi(token, soilRequest);
// TODO: 2025/9/26 模拟保存到MySQL

View File

@@ -75,7 +75,7 @@ public class WaterFertilizerService extends AbstractDeviceService {
// 转换请求参数
RealTimeDeviceDataReqVO wfRequest = (RealTimeDeviceDataReqVO) realTimeRequest;
// TODO: 2025/9/26 调用水肥机设备厂商API获取实时数据
// TODO: 2025/9/26 调用水肥机设备厂商API获取实时数据 GET 请求方式
RealTimeDeviceDataRespVO vendorResponse = callWFRealTimeDataApi(token, wfRequest);
// 直接返回原始响应数据,不进行统一转换
@@ -92,7 +92,7 @@ public class WaterFertilizerService extends AbstractDeviceService {
// 转换请求参数
UpdateDeviceStatusReqVO wfRequest = (UpdateDeviceStatusReqVO) updateRequest;
// TODO: 2025/9/26 调用水肥机设备厂商API更新设备属性
// TODO: 2025/9/26 调用水肥机设备厂商API更新设备属性 POST 请求方式
UpdateDeviceStatusRespVO vendorResponse = callWFUpdateDeviceApi(token, wfRequest);
// 转换为统一响应格式

View File

@@ -284,6 +284,7 @@ yudao:
- /admin-api/system/auth/get-phone-number
- /admin-api/system/auth/api
- /admin-api/farm/remote
- /admin-api/farm/home/scan-qr
ignore-visit-urls:
- /admin-api/system/user/profile/**
- /admin-api/system/auth/**