From f6f4365a1a0e450bf4cd24703f6b35abc0ab96fa Mon Sep 17 00:00:00 2001 From: rqian <1206436827@qq.com> Date: Fri, 8 May 2026 14:57:37 +0800 Subject: [PATCH] =?UTF-8?q?#=E4=BF=AE=E6=94=B9=E6=A8=A1=E5=9E=8B=E7=9A=84u?= =?UTF-8?q?pdate=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/SysProductController.java | 335 +++++------------- .../impl/SysDeviceModelServiceImpl.java | 2 +- 2 files changed, 84 insertions(+), 253 deletions(-) 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 index 2b3155d..d388d43 100644 --- 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 @@ -1,13 +1,20 @@ package com.maibu.web.controller.system; +import cn.hutool.core.convert.Convert; import com.maibu.core.business.DeviceModel; +import com.maibu.core.business.Product; import com.maibu.core.controller.BaseController; import com.maibu.core.domain.AjaxResult; +import com.maibu.core.page.TableDataInfo; +import com.maibu.service.DeviceProductService; import com.maibu.service.SysDeviceModelService; +import com.maibu.utils.ServletUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -17,268 +24,92 @@ import java.util.List; */ @Api(tags = "厂家模块") @RestController -@RequestMapping("/system/deviceproduct") +@RequestMapping("/system/product") 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)); -// } - + private DeviceProductService productService; /** - * 重置设备状态 + * 分页查询产品列表 */ - /* @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())); - } -*/ + // @PreAuthorize("@ss.hasPermi('iot:product:list')") + @GetMapping("/list") + @ApiOperation("查询产品列表") + public TableDataInfo list(Product product) { + Integer pageNum = Convert.toInt(ServletUtils.getParameter("pageNum"), 1); + Integer pageSize = Convert.toInt(ServletUtils.getParameter("pageSize"), 10); - /* @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); + Page page = new Page<>(pageNum, pageSize); + Page resultPage = productService.selectProductPage(page, product); + + return getDataTable(resultPage.getRecords(), resultPage.getTotal()); } - 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()); + /** + * 新增产品 + */ + //@PreAuthorize("@ss.hasPermi('iot:product:add')") + @PostMapping("/add") + @ApiOperation("新增产品") + public AjaxResult add(@RequestBody Product product) { + // 参数校验 + if (product.getName() == null || product.getName().isEmpty()) { + return AjaxResult.error("产品名称不能为空"); } - 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(); + if (product.getCode() == null || product.getCode().isEmpty()) { + return AjaxResult.error("产品编码不能为空"); } - }*/ + // 检查编码是否重复 + Product existProduct = productService.selectByCode(product.getCode()); + if (existProduct != null) { + return AjaxResult.error("产品编码已存在"); + } + + boolean success = productService.save(product); + return toAjax(success ? 1 : 0); + } + + /** + * 修改产品 + */ + //@PreAuthorize("@ss.hasPermi('iot:product:edit')") + @PostMapping("/update") + @ApiOperation("修改产品") + public AjaxResult edit(@RequestBody Product product) { + if (product.getId() == null) { + return AjaxResult.error("产品ID不能为空"); + } + + // 检查产品是否存在 + Product existProduct = productService.getById(product.getId()); + if (existProduct == null) { + return AjaxResult.error("产品不存在"); + } + + // 如果修改了编码,检查是否重复 + if (product.getCode() != null && !product.getCode().equals(existProduct.getCode())) { + Product duplicate = productService.selectByCode(product.getCode()); + if (duplicate != null) { + return AjaxResult.error("产品编码已存在"); + } + } + + boolean success = productService.updateById(product); + return toAjax(success ? 1 : 0); + } + + /** + * 删除产品 + */ + //@PreAuthorize("@ss.hasPermi('iot:product:remove')") + @DeleteMapping("delete/{id}") + @ApiOperation("删除产品") + public AjaxResult remove(@PathVariable Long id) { + boolean success = productService.removeById(id); + return toAjax(success ? 1 : 0); + } + + } diff --git a/maibu-service/maibu-system-service/src/main/java/com/maibu/service/impl/SysDeviceModelServiceImpl.java b/maibu-service/maibu-system-service/src/main/java/com/maibu/service/impl/SysDeviceModelServiceImpl.java index e33107f..734310b 100644 --- a/maibu-service/maibu-system-service/src/main/java/com/maibu/service/impl/SysDeviceModelServiceImpl.java +++ b/maibu-service/maibu-system-service/src/main/java/com/maibu/service/impl/SysDeviceModelServiceImpl.java @@ -1 +1 @@ -package com.maibu.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.maibu.core.business.DeviceAction; import com.maibu.core.business.DeviceModel; import com.maibu.core.business.DeviceModelProperty; import com.maibu.exception.ServiceException; import com.maibu.mapper.SysDeviceActionMapper; import com.maibu.mapper.SysDeviceModelMapper; import com.maibu.mapper.SysDevicePropertyMapper; import com.maibu.service.SysDeviceModelService; import com.maibu.service.SysDevicePropertyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; /** * @author jsmbz * @description 针对表【iot_device_model(设备模型表)】的数据库操作Service实现 * @createDate 2026-05-07 11:36:11 */ @Service public class SysDeviceModelServiceImpl extends ServiceImpl implements SysDeviceModelService { @Autowired private SysDeviceModelMapper deviceModelMapper; @Autowired private SysDeviceActionMapper actionMapper; @Autowired private SysDevicePropertyMapper propertyMapper; @Override @Transactional(rollbackFor = Exception.class) // ⭐ 关键 public int insertDeviceModel(DeviceModel deviceModel) { // 1. 插入模型主表 deviceModel.setCreateTime(LocalDateTime.now()); deviceModel.setDelFlag(false); int rows = deviceModelMapper.insert(deviceModel); if (rows <= 0) { throw new ServiceException("模型创建失败"); } Long modelId = deviceModel.getId(); // 2. 插入属性列表 if (!CollectionUtils.isEmpty(deviceModel.getSupportProperties())) { LocalDateTime now = LocalDateTime.now(); for (DeviceModelProperty prop : deviceModel.getSupportProperties()) { prop.setModelId(modelId); prop.setCreateTime(now); prop.setDelFlag(false); propertyMapper.insert(prop); } } // 3. 插入动作列表 if (!CollectionUtils.isEmpty(deviceModel.getSupportActions())) { LocalDateTime now = LocalDateTime.now(); for (DeviceAction action : deviceModel.getSupportActions()) { action.setModelId(modelId); action.setCreateTime(now); action.setDelFlag(false); actionMapper.insert(action); } } return 1; } @Override public Page selectDeviceModelPage(Page page, DeviceModel deviceModel) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); if (deviceModel.getName() != null && !deviceModel.getName().isEmpty()) { wrapper.like(DeviceModel::getName, deviceModel.getName()); } if (deviceModel.getConnectType() != null) { wrapper.eq(DeviceModel::getConnectType, deviceModel.getConnectType()); } if (deviceModel.getDeviceType() != null) { wrapper.eq(DeviceModel::getDeviceType, deviceModel.getDeviceType()); } wrapper.eq(DeviceModel::getDelFlag, false); wrapper.orderByDesc(DeviceModel::getCreateTime); Page resultPage = deviceModelMapper.selectPage(page, wrapper); if (!CollectionUtils.isEmpty(resultPage.getRecords())) { resultPage.getRecords().forEach(model -> { List properties = propertyMapper.selectList( new LambdaQueryWrapper() .eq(DeviceModelProperty::getModelId, model.getId()) .eq(DeviceModelProperty::getDelFlag, false) .orderByAsc(DeviceModelProperty::getId) ); model.setSupportProperties(properties); List actions = actionMapper.selectList( new LambdaQueryWrapper() .eq(DeviceAction::getModelId, model.getId()) .eq(DeviceAction::getDelFlag, false) .orderByAsc(DeviceAction::getId) ); model.setSupportActions(actions); }); } return resultPage; } @Override public DeviceModel selectDeviceModelById(Long id) { // 1. 查主表 DeviceModel model = deviceModelMapper.selectById(id); if (model == null) return null; // 2. 查属性 List properties = propertyMapper.selectList( new LambdaQueryWrapper() .eq(DeviceModelProperty::getModelId, id) .eq(DeviceModelProperty::getDelFlag, false) ); model.setSupportProperties(properties); // 3. 查动作 List actions = actionMapper.selectList( new LambdaQueryWrapper() .eq(DeviceAction::getModelId, id) .eq(DeviceAction::getDelFlag, false) ); model.setSupportActions(actions); return model; } @Override @Transactional(rollbackFor = Exception.class) public int updateDeviceModel(DeviceModel deviceModel) { // 1. 更新主表 deviceModel.setUpdateTime(LocalDateTime.now()); deviceModelMapper.updateById(deviceModel); Long modelId = deviceModel.getId(); // 2. 处理属性列表 (智能更新) if (deviceModel.getSupportProperties() != null) { // 2.1 遍历前端传来的列表:有ID则更新,无ID则新增 for (DeviceModelProperty prop : deviceModel.getSupportProperties()) { if (prop.getId() != null && prop.getId() > 0) { prop.setUpdateTime(LocalDateTime.now()); propertyMapper.updateById(prop); } else { prop.setModelId(modelId); prop.setCreateTime(LocalDateTime.now()); propertyMapper.insert(prop); } } // 2.2 删除前端没传的项 (通过 NOT IN) List receivedIds = deviceModel.getSupportProperties().stream() .map(DeviceModelProperty::getId) .filter(id -> id != null && id > 0) .collect(Collectors.toList()); if (!receivedIds.isEmpty()) { propertyMapper.delete( new LambdaQueryWrapper() .eq(DeviceModelProperty::getModelId, modelId) .notIn(DeviceModelProperty::getId, receivedIds) ); } else { // 如果传了空列表,说明要删除所有属性 propertyMapper.delete( new LambdaQueryWrapper() .eq(DeviceModelProperty::getModelId, modelId) ); } } // 3. 处理动作列表 (逻辑同上) if (deviceModel.getSupportActions() != null) { for (DeviceAction action : deviceModel.getSupportActions()) { if (action.getId() != null && action.getId() > 0) { action.setUpdateTime(LocalDateTime.now()); actionMapper.updateById(action); } else { action.setModelId(modelId); action.setCreateTime(LocalDateTime.now()); actionMapper.insert(action); } } List receivedActionIds = deviceModel.getSupportActions().stream() .map(DeviceAction::getId) .filter(id -> id != null && id > 0) .collect(Collectors.toList()); if (!receivedActionIds.isEmpty()) { actionMapper.delete( new LambdaQueryWrapper() .eq(DeviceAction::getModelId, modelId) .notIn(DeviceAction::getId, receivedActionIds) ); } else { actionMapper.delete( new LambdaQueryWrapper() .eq(DeviceAction::getModelId, modelId) ); } } return 1; } } \ No newline at end of file +package com.maibu.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.maibu.core.business.DeviceAction; import com.maibu.core.business.DeviceModel; import com.maibu.core.business.DeviceModelProperty; import com.maibu.exception.ServiceException; import com.maibu.mapper.SysDeviceActionMapper; import com.maibu.mapper.SysDeviceModelMapper; import com.maibu.mapper.SysDevicePropertyMapper; import com.maibu.service.SysDeviceModelService; import com.maibu.service.SysDevicePropertyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; /** * @author jsmbz * @description 针对表【iot_device_model(设备模型表)】的数据库操作Service实现 * @createDate 2026-05-07 11:36:11 */ @Service public class SysDeviceModelServiceImpl extends ServiceImpl implements SysDeviceModelService { @Autowired private SysDeviceModelMapper deviceModelMapper; @Autowired private SysDeviceActionMapper actionMapper; @Autowired private SysDevicePropertyMapper propertyMapper; @Override @Transactional(rollbackFor = Exception.class) // ⭐ 关键 public int insertDeviceModel(DeviceModel deviceModel) { // 1. 插入模型主表 deviceModel.setCreateTime(LocalDateTime.now()); deviceModel.setDelFlag(false); int rows = deviceModelMapper.insert(deviceModel); if (rows <= 0) { throw new ServiceException("模型创建失败"); } Long modelId = deviceModel.getId(); // 2. 插入属性列表 if (!CollectionUtils.isEmpty(deviceModel.getSupportProperties())) { LocalDateTime now = LocalDateTime.now(); for (DeviceModelProperty prop : deviceModel.getSupportProperties()) { prop.setModelId(modelId); prop.setCreateTime(now); prop.setDelFlag(false); propertyMapper.insert(prop); } } // 3. 插入动作列表 if (!CollectionUtils.isEmpty(deviceModel.getSupportActions())) { LocalDateTime now = LocalDateTime.now(); for (DeviceAction action : deviceModel.getSupportActions()) { action.setModelId(modelId); action.setCreateTime(now); action.setDelFlag(false); actionMapper.insert(action); } } return 1; } @Override public Page selectDeviceModelPage(Page page, DeviceModel deviceModel) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); if (deviceModel.getName() != null && !deviceModel.getName().isEmpty()) { wrapper.like(DeviceModel::getName, deviceModel.getName()); } if (deviceModel.getConnectType() != null) { wrapper.eq(DeviceModel::getConnectType, deviceModel.getConnectType()); } if (deviceModel.getDeviceType() != null) { wrapper.eq(DeviceModel::getDeviceType, deviceModel.getDeviceType()); } wrapper.eq(DeviceModel::getDelFlag, false); wrapper.orderByDesc(DeviceModel::getCreateTime); Page resultPage = deviceModelMapper.selectPage(page, wrapper); if (!CollectionUtils.isEmpty(resultPage.getRecords())) { resultPage.getRecords().forEach(model -> { List properties = propertyMapper.selectList( new LambdaQueryWrapper() .eq(DeviceModelProperty::getModelId, model.getId()) .eq(DeviceModelProperty::getDelFlag, false) .orderByAsc(DeviceModelProperty::getId) ); model.setSupportProperties(properties); List actions = actionMapper.selectList( new LambdaQueryWrapper() .eq(DeviceAction::getModelId, model.getId()) .eq(DeviceAction::getDelFlag, false) .orderByAsc(DeviceAction::getId) ); model.setSupportActions(actions); }); } return resultPage; } @Override public DeviceModel selectDeviceModelById(Long id) { // 1. 查主表 DeviceModel model = deviceModelMapper.selectById(id); if (model == null) return null; // 2. 查属性 List properties = propertyMapper.selectList( new LambdaQueryWrapper() .eq(DeviceModelProperty::getModelId, id) .eq(DeviceModelProperty::getDelFlag, false) ); model.setSupportProperties(properties); // 3. 查动作 List actions = actionMapper.selectList( new LambdaQueryWrapper() .eq(DeviceAction::getModelId, id) .eq(DeviceAction::getDelFlag, false) ); model.setSupportActions(actions); return model; } @Override @Transactional(rollbackFor = Exception.class) public int updateDeviceModel(DeviceModel deviceModel) { // 1. 更新模型主表 deviceModel.setUpdateTime(LocalDateTime.now()); deviceModelMapper.updateById(deviceModel); Long modelId = deviceModel.getId(); // 2. 处理属性列表(智能更新) if (deviceModel.getSupportProperties() != null) { // 2.1 遍历前端传来的列表:有 ID 则更新,无 ID 则新增 for (DeviceModelProperty prop : deviceModel.getSupportProperties()) { if (prop.getId() != null && prop.getId() > 0) { // 已有记录 → 执行 UPDATE prop.setUpdateTime(LocalDateTime.now()); propertyMapper.updateById(prop); } else { // 新记录 → 执行 INSERT prop.setModelId(modelId); prop.setCreateTime(LocalDateTime.now()); prop.setUpdateTime(LocalDateTime.now()); prop.setDelFlag(false); propertyMapper.insert(prop); } } // 2.2 删除前端没传的属性(通过 NOT IN) List receivedIds = deviceModel.getSupportProperties().stream() .map(DeviceModelProperty::getId) .filter(id -> id != null && id > 0) .collect(Collectors.toList()); if (!receivedIds.isEmpty()) { propertyMapper.delete( new LambdaQueryWrapper() .eq(DeviceModelProperty::getModelId, modelId) .notIn(DeviceModelProperty::getId, receivedIds) ); } else { // 如果传了空列表,删除所有属性 propertyMapper.delete( new LambdaQueryWrapper() .eq(DeviceModelProperty::getModelId, modelId) ); } } // 3. 处理动作列表(同理) if (deviceModel.getSupportActions() != null) { for (DeviceAction action : deviceModel.getSupportActions()) { if (action.getId() != null && action.getId() > 0) { action.setUpdateTime(LocalDateTime.now()); actionMapper.updateById(action); } else { action.setModelId(modelId); action.setCreateTime(LocalDateTime.now()); action.setUpdateTime(LocalDateTime.now()); action.setDelFlag(false); actionMapper.insert(action); } } List receivedActionIds = deviceModel.getSupportActions().stream() .map(DeviceAction::getId) .filter(id -> id != null && id > 0) .collect(Collectors.toList()); if (!receivedActionIds.isEmpty()) { actionMapper.delete( new LambdaQueryWrapper() .eq(DeviceAction::getModelId, modelId) .notIn(DeviceAction::getId, receivedActionIds) ); } else { actionMapper.delete( new LambdaQueryWrapper() .eq(DeviceAction::getModelId, modelId) ); } } return 1; } } \ No newline at end of file