From 8668f40a7b1131497af8fe6d71648548b7b49d2f Mon Sep 17 00:00:00 2001 From: rqian <1206436827@qq.com> Date: Fri, 8 May 2026 13:38:33 +0800 Subject: [PATCH] =?UTF-8?q?#=E6=96=B0=E5=A2=9E=E4=BA=A7=E5=93=81=E8=A1=A8?= =?UTF-8?q?=E5=92=8C=E4=BA=A7=E5=93=81=E6=8E=A5=E5=8F=A3=E8=A1=A8=E5=92=8C?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/SysProductController.java | 284 ++++++++++++++++++ .../java/com/maibu/core/business/Product.java | 29 +- .../maibu/core/business/ProductInterface.java | 15 +- 3 files changed, 320 insertions(+), 8 deletions(-) create mode 100644 maibu-admin/src/main/java/com/maibu/web/controller/system/SysProductController.java diff --git a/maibu-admin/src/main/java/com/maibu/web/controller/system/SysProductController.java b/maibu-admin/src/main/java/com/maibu/web/controller/system/SysProductController.java new file mode 100644 index 0000000..2b3155d --- /dev/null +++ b/maibu-admin/src/main/java/com/maibu/web/controller/system/SysProductController.java @@ -0,0 +1,284 @@ +package com.maibu.web.controller.system; + +import com.maibu.core.business.DeviceModel; +import com.maibu.core.controller.BaseController; +import com.maibu.core.domain.AjaxResult; +import com.maibu.service.SysDeviceModelService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 厂家模块 + */ +@Api(tags = "厂家模块") +@RestController +@RequestMapping("/system/deviceproduct") +public class SysProductController extends BaseController { + @Autowired + private SysDeviceModelService deviceModelService; + + /*@Autowired + private DeviceRunStatisticsMapper deviceRunStatisticsMapper;*/ + + + @PostMapping("/add") + @ApiOperation("新增设备模型") + public AjaxResult add(@RequestBody DeviceModel deviceModel) { + // 参数校验 + if (deviceModel.getName() == null || deviceModel.getName().isEmpty()) { + return AjaxResult.error("模型名称不能为空"); + } + + // 至少需要一个属性或动作 + if (CollectionUtils.isEmpty(deviceModel.getSupportProperties()) + && CollectionUtils.isEmpty(deviceModel.getSupportActions())) { + return AjaxResult.error("至少需要定义一个属性或动作"); + } + + int rows = deviceModelService.insertDeviceModel(deviceModel); + return toAjax(rows); + } + + + + //@PreAuthorize("@ss.hasPermi('iot:deviceModel:list')") + /* @GetMapping("/list") + @ApiOperation("查询设备模型列表") + public AjaxResult list(DeviceModel deviceModel) { + List list = deviceModelService.selectDeviceModelList(deviceModel); + return AjaxResult.success(list); + }*/ + + + // @PreAuthorize("@ss.hasPermi('iot:deviceModel:edit')") + @PostMapping("/update") // 或者 @PutMapping + @ApiOperation("修改设备模型") + public AjaxResult edit(@RequestBody DeviceModel deviceModel) { + // 1. 校验 ID + if (deviceModel.getId() == null) { + return AjaxResult.error("模型ID不能为空"); + } + + // 2. 检查是否存在 + DeviceModel existModel = deviceModelService.selectDeviceModelById(deviceModel.getId()); + if (existModel == null) { + return AjaxResult.error("模型不存在"); + } + + // 3. 执行更新 + int rows = deviceModelService.updateDeviceModel(deviceModel); + return toAjax(rows); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// +// /** +// * 查询模型的列表 +// */ +// @PreAuthorize("@ss.hasPermi('system:devicemodel:list')") +// @GetMapping("/list") +// @ApiOperation("设备分页列表") +// public TableDataInfo list(Device device) { +// startPage(); +// return getDataTable(deviceService.selectDeviceList(device)); +// } +// +// +// @GetMapping("/userDevice") +// public AjaxResult userDevice(Device device) { +// return AjaxResult.success(deviceService.selectDeviceList(device)); +// } +// +// +// /** +// * 导出设备列表 +// */ +// @PreAuthorize("@ss.hasPermi('system:devicemodel:export')") +// @Log(title = "设备", businessType = BusinessType.EXPORT) +// @PostMapping("/export") +// @ApiOperation("导出设备") +// public void export(HttpServletResponse response, Device device) { +// List list = deviceService.selectDeviceList(device); +// ExcelUtil util = new ExcelUtil(Device.class); +// util.exportExcel(response, list, "设备数据"); +// } +// +// +// /** +// * 根据设备编号详细信息 +// */ +// @PreAuthorize("@ss.hasPermi('iot:device:query')") +// @GetMapping(value = "/getDeviceBySerialNumber/{serialNumber}") +// @ApiOperation("根据设备编号获取设备详情") +// public AjaxResult getInfoBySerialNumber(@PathVariable("serialNumber") String serialNumber) { +// return AjaxResult.success(deviceService.selectDeviceBySerialNumber(serialNumber)); +// } + + + /** + * 重置设备状态 + */ + /* @PreAuthorize("@ss.hasPermi('iot:device:edit')") + @Log(title = "重置设备状态", businessType = BusinessType.UPDATE) + @PutMapping("/reset/{serialNumber}") + @ApiOperation("重置设备状态") + public AjaxResult resetDeviceStatus(@PathVariable String serialNumber) { + Device device = new Device(); + device.setSerialNumber(serialNumber); + return toAjax(deviceService.resetDeviceStatus(device.getSerialNumber())); + } +*/ + + /* @GetMapping("/getDeviceRunStatistics") + public AjaxResult getDeviceRunStatistics(@RequestParam("deviceId") String deviceId) { + if (StringUtils.isEmpty(deviceId)) { + return error("请选择设备"); + } + LambdaQueryWrapperX queryWrapperX = new LambdaQueryWrapperX<>(); + queryWrapperX.eq(DeviceRunStatistics::getDeviceId, deviceId); + queryWrapperX.orderByDesc(DeviceRunStatistics::getEndTime); + queryWrapperX.last("LIMIT 10"); + return AjaxResult.success(deviceRunStatisticsMapper.selectList(queryWrapperX)); + } +*/ + /* @GetMapping("/getDeviceIntradayData") + public AjaxResult getDeviceIntradayData(@RequestParam("deviceId") String deviceId) { + List resultList = getIntradayData(); + DeviceRunStatistics statistics = null; + if (!CollectionUtils.isEmpty(resultList)) { + statistics = resultList.stream().filter(x -> deviceId.equals(x.getDeviceId())).findFirst().orElse(null); + } + return AjaxResult.success(statistics); + } + + public List getIntradayData() { + LambdaQueryWrapperX wrapper = new LambdaQueryWrapperX<>(); + LocalDateTime start = LocalDate.now().atStartOfDay(); // 今天 00:00:00 + LocalDateTime end = LocalDate.now().plusDays(1).atStartOfDay(); // 明天 00:00:00 + + wrapper.ge(DeviceRunStatistics::getStartTime, start) + .lt(DeviceRunStatistics::getStartTime, end); + + List list = deviceRunStatisticsMapper.selectList(wrapper); + List resultList = new ArrayList<>(); + + if (!CollectionUtils.isEmpty(list)) { + resultList = list.stream() + .collect(Collectors.groupingBy(DeviceRunStatistics::getDeviceId)) + .values() + .stream() + .map(group -> { + DeviceRunStatistics sum = new DeviceRunStatistics(); + sum.setDeviceId(group.get(0).getDeviceId()); + + sum.setWorkArea( + group.stream().mapToDouble(DeviceRunStatistics::getWorkArea).sum() + ); + + sum.setTime( + group.stream().mapToLong(DeviceRunStatistics::getTime).sum() + ); + + return sum; + }) + .collect(Collectors.toList()); + } + List l = resultList.stream().map(DeviceRunStatistics::getDeviceId).collect(Collectors.toList()); + Device d = new Device(); + d.setParams(new HashMap<>()); + List query = deviceService.selectDeviceList(d); + if (!CollectionUtils.isEmpty(query) && !CollectionUtils.isEmpty(l)) { + for (Device device : query) { + if (!l.contains(device.getDeviceName())) { + DeviceRunStatistics statistics = new DeviceRunStatistics(); + statistics.setDeviceId(device.getDeviceName()); + statistics.setTime(0L); + statistics.setWorkArea(0.0); + resultList.add(statistics); + } + } + } + return resultList; + }*/ + +/* @GetMapping("/generateOperationReport") + public void generateOperationReport(HttpServletResponse response) throws UnsupportedEncodingException { + List resultList = getIntradayData(); + // ✅ 4. 响应头(下载) + response.setContentType( + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + + String fileName = URLEncoder.encode("设备统计.xlsx", "UTF-8"); + response.setHeader("Content-Disposition", + "attachment;filename=" + fileName); + try (Workbook workbook = new XSSFWorkbook(); + OutputStream os = response.getOutputStream()) { + + Sheet sheet = workbook.createSheet("当日工作量统计"); + + // ✅ 1. 表头 + Row header = sheet.createRow(0); + header.createCell(0).setCellValue("设备号"); + header.createCell(1).setCellValue("工作面积(m2)"); + header.createCell(2).setCellValue("工作时长(分钟)"); + + // ✅ 2. 数据 + for (int i = 0; i < resultList.size(); i++) { + DeviceRunStatistics d = resultList.get(i); + Row row = sheet.createRow(i + 1); + + row.createCell(0).setCellValue(d.getDeviceId()); + row.createCell(1).setCellValue(d.getWorkArea()); + row.createCell(2).setCellValue(d.getTime()); + } + + // ✅ 3. 自动列宽(可选) + for (int i = 0; i < 3; i++) { + sheet.autoSizeColumn(i); + } + + + // ✅ 5. 写出 + workbook.write(os); + os.flush(); + + } catch (Exception e) { + e.printStackTrace(); + } + + }*/ + +} diff --git a/maibu-common/src/main/java/com/maibu/core/business/Product.java b/maibu-common/src/main/java/com/maibu/core/business/Product.java index 4aab182..4cf2a67 100644 --- a/maibu-common/src/main/java/com/maibu/core/business/Product.java +++ b/maibu-common/src/main/java/com/maibu/core/business/Product.java @@ -1,14 +1,19 @@ package com.maibu.core.business; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.fasterxml.jackson.annotation.JsonInclude; import com.maibu.core.domain.BaseDO; import io.swagger.annotations.ApiModel; import lombok.Data; import lombok.EqualsAndHashCode; +import java.util.List; +import java.util.Map; + @EqualsAndHashCode(callSuper = true) @JsonInclude(JsonInclude.Include.NON_NULL) @@ -20,11 +25,31 @@ public class Product extends BaseDO { @TableId(type = IdType.AUTO) private Long id; + private String code; + private String name; - private String address; + private String manufacturer; - private String remark; + private Long categoryId; + private String protocolCode; + + private String transport; + + private String uploadTopic; + + private String subscribeTopic; + + @TableField(typeHandler = JacksonTypeHandler.class) + private Map thingsModels; + + @TableField(typeHandler = JacksonTypeHandler.class) + private List> deviceActions; + + @TableField(typeHandler = JacksonTypeHandler.class) + private List> events; + + private Integer status; } diff --git a/maibu-common/src/main/java/com/maibu/core/business/ProductInterface.java b/maibu-common/src/main/java/com/maibu/core/business/ProductInterface.java index fe2657d..d34162e 100644 --- a/maibu-common/src/main/java/com/maibu/core/business/ProductInterface.java +++ b/maibu-common/src/main/java/com/maibu/core/business/ProductInterface.java @@ -1,8 +1,10 @@ package com.maibu.core.business; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.fasterxml.jackson.annotation.JsonInclude; import com.maibu.core.domain.BaseDO; import com.maibu.core.enums.ConnectType; @@ -22,17 +24,18 @@ public class ProductInterface extends BaseDO { @TableId(type = IdType.AUTO) private Long id; - private String name; + private Long productId; - private ConnectType type; + private String interfaceType; - private String url; + private String interfaceName; + + private String interfaceUrl; private String method; - private String topic; - - private Map params; + @TableField(typeHandler = JacksonTypeHandler.class) + private Map paramsSchema; private String remark;