From f54859f62db72f1f074aeedd7c1c0a45a7bef9c0 Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Wed, 15 Oct 2025 14:14:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E9=9C=80=E6=B1=82=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/AuthController.java | 2 +- .../common/json/handler/DoubleSerializer.java | 28 ++ ruoyi-common/ruoyi-common-mybatis/pom.xml | 1 - .../DeviceBindRecordController.java | 105 +++++ .../fishery/controller/DeviceController.java | 105 +++++ .../org/dromara/fishery/domain/Device.java | 243 +++++++++++ .../fishery/domain/DeviceBindRecord.java | 56 +++ .../fishery/domain/bo/DeviceBindRecordBo.java | 60 +++ .../dromara/fishery/domain/bo/DeviceBo.java | 275 +++++++++++++ .../org/dromara/fishery/domain/bo/PondBo.java | 10 + .../dromara/fishery/domain/vo/AquUserVo.java | 4 + .../fishery/domain/vo/DeviceBindRecordVo.java | 86 ++++ .../fishery/domain/vo/DeviceThresholdVo.java | 4 + .../dromara/fishery/domain/vo/DeviceVo.java | 344 ++++++++++++++++ .../org/dromara/fishery/domain/vo/FishVo.java | 4 + .../org/dromara/fishery/domain/vo/PondVo.java | 39 +- .../mapper/DeviceBindRecordMapper.java | 15 + .../dromara/fishery/mapper/DeviceMapper.java | 16 + .../service/IDeviceBindRecordService.java | 68 +++ .../fishery/service/IDeviceService.java | 68 +++ .../service/impl/AquUserServiceImpl.java | 2 +- .../impl/DeviceBindRecordServiceImpl.java | 236 +++++++++++ .../service/impl/DeviceServiceImpl.java | 389 ++++++++++++++++++ .../impl/DeviceThresholdServiceImpl.java | 3 +- .../fishery/service/impl/PondServiceImpl.java | 256 +++++++++++- .../mapper/fishery/DeviceBindRecordMapper.xml | 6 + .../resources/mapper/fishery/DeviceMapper.xml | 6 + 27 files changed, 2399 insertions(+), 32 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/handler/DoubleSerializer.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/controller/DeviceBindRecordController.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/controller/DeviceController.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/Device.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/DeviceBindRecord.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/DeviceBindRecordBo.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/DeviceBo.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceBindRecordVo.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceVo.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/mapper/DeviceBindRecordMapper.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/mapper/DeviceMapper.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/IDeviceBindRecordService.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/IDeviceService.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceBindRecordServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/resources/mapper/fishery/DeviceBindRecordMapper.xml create mode 100644 ruoyi-modules/ruoyi-fishery/src/main/resources/mapper/fishery/DeviceMapper.xml diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java index 89b9ab6..9ec501a 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java @@ -106,7 +106,7 @@ public class AuthController { Long userId = LoginHelper.getUserId(); scheduledExecutorService.schedule(() -> { SseMessageDto dto = new SseMessageDto(); - dto.setMessage("欢迎登录RuoYi-Vue-Plus后台管理系统"); + dto.setMessage("欢迎登录水产养殖监测平台"); dto.setUserIds(List.of(userId)); SseMessageUtils.publishMessage(dto); }, 5, TimeUnit.SECONDS); diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/handler/DoubleSerializer.java b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/handler/DoubleSerializer.java new file mode 100644 index 0000000..c3fd6ef --- /dev/null +++ b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/handler/DoubleSerializer.java @@ -0,0 +1,28 @@ +package org.dromara.common.json.handler; + +import java.io.IOException; +import java.text.DecimalFormat; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +/** + * Double 类型格式化序列化器 + * 保留两位小数 + * + * @author intc + */ +public class DoubleSerializer extends JsonSerializer { + + private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.00"); + + @Override + public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + if (value == null) { + gen.writeNull(); + } else { + gen.writeNumber(DECIMAL_FORMAT.format(value)); + } + } +} diff --git a/ruoyi-common/ruoyi-common-mybatis/pom.xml b/ruoyi-common/ruoyi-common-mybatis/pom.xml index d79ba28..a82268c 100644 --- a/ruoyi-common/ruoyi-common-mybatis/pom.xml +++ b/ruoyi-common/ruoyi-common-mybatis/pom.xml @@ -41,7 +41,6 @@ com.baomidou mybatis-plus-jsqlparser - p6spy diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/controller/DeviceBindRecordController.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/controller/DeviceBindRecordController.java new file mode 100644 index 0000000..6bf5b8b --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/controller/DeviceBindRecordController.java @@ -0,0 +1,105 @@ +package org.dromara.fishery.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.fishery.domain.vo.DeviceBindRecordVo; +import org.dromara.fishery.domain.bo.DeviceBindRecordBo; +import org.dromara.fishery.service.IDeviceBindRecordService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 设备绑定记录 + * + * @author intc + * @date 2025-10-14 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fishery/deviceBindRecord") +public class DeviceBindRecordController extends BaseController { + + private final IDeviceBindRecordService deviceBindRecordService; + + /** + * 查询设备绑定记录列表 + */ + @SaCheckPermission("fishery:deviceBindRecord:list") + @GetMapping("/list") + public TableDataInfo list(DeviceBindRecordBo bo, PageQuery pageQuery) { + return deviceBindRecordService.queryPageList(bo, pageQuery); + } + + /** + * 导出设备绑定记录列表 + */ + @SaCheckPermission("fishery:deviceBindRecord:export") + @Log(title = "设备绑定记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(DeviceBindRecordBo bo, HttpServletResponse response) { + List list = deviceBindRecordService.queryList(bo); + ExcelUtil.exportExcel(list, "设备绑定记录", DeviceBindRecordVo.class, response); + } + + /** + * 获取设备绑定记录详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fishery:deviceBindRecord:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(deviceBindRecordService.queryById(id)); + } + + /** + * 新增设备绑定记录 + */ + @SaCheckPermission("fishery:deviceBindRecord:add") + @Log(title = "设备绑定记录", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody DeviceBindRecordBo bo) { + return toAjax(deviceBindRecordService.insertByBo(bo)); + } + + /** + * 修改设备绑定记录 + */ + @SaCheckPermission("fishery:deviceBindRecord:edit") + @Log(title = "设备绑定记录", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody DeviceBindRecordBo bo) { + return toAjax(deviceBindRecordService.updateByBo(bo)); + } + + /** + * 删除设备绑定记录 + * + * @param ids 主键串 + */ + @SaCheckPermission("fishery:deviceBindRecord:remove") + @Log(title = "设备绑定记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(deviceBindRecordService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/controller/DeviceController.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/controller/DeviceController.java new file mode 100644 index 0000000..1aa5370 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/controller/DeviceController.java @@ -0,0 +1,105 @@ +package org.dromara.fishery.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.fishery.domain.vo.DeviceVo; +import org.dromara.fishery.domain.bo.DeviceBo; +import org.dromara.fishery.service.IDeviceService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 设备管理 + * + * @author intc + * @date 2025-10-14 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fishery/device") +public class DeviceController extends BaseController { + + private final IDeviceService deviceService; + + /** + * 查询设备管理列表 + */ + @SaCheckPermission("fishery:device:list") + @GetMapping("/list") + public TableDataInfo list(DeviceBo bo, PageQuery pageQuery) { + return deviceService.queryPageList(bo, pageQuery); + } + + /** + * 导出设备管理列表 + */ + @SaCheckPermission("fishery:device:export") + @Log(title = "设备管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(DeviceBo bo, HttpServletResponse response) { + List list = deviceService.queryList(bo); + ExcelUtil.exportExcel(list, "设备管理", DeviceVo.class, response); + } + + /** + * 获取设备管理详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fishery:device:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(deviceService.queryById(id)); + } + + /** + * 新增设备管理 + */ + @SaCheckPermission("fishery:device:add") + @Log(title = "设备管理", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody DeviceBo bo) { + return toAjax(deviceService.insertByBo(bo)); + } + + /** + * 修改设备管理 + */ + @SaCheckPermission("fishery:device:edit") + @Log(title = "设备管理", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody DeviceBo bo) { + return toAjax(deviceService.updateByBo(bo)); + } + + /** + * 删除设备管理 + * + * @param ids 主键串 + */ + @SaCheckPermission("fishery:device:remove") + @Log(title = "设备管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(deviceService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/Device.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/Device.java new file mode 100644 index 0000000..1b4e4ea --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/Device.java @@ -0,0 +1,243 @@ +package org.dromara.fishery.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 设备管理对象 aqu_device + * + * @author intc + * @date 2025-10-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("aqu_device") +public class Device extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 物联网IotId + */ + private String iotId; + + /** + * 设备编号 + */ + private String serialNum; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 设备类型 + */ + private Integer deviceType; + + /** + * 绑定时间 + */ + private Date bindTime; + + /** + * 服务到期 + */ + private Date deadTime; + + /** + * 塘口id + */ + private Long pondId; + + /** + * 溶解氧参数配置开关 + */ + private Integer isOxygenUsed; + + /** + * 溶解氧 + */ + private Double valueDissolvedOxygen; + + /** + * 是否已触发溶解氧报警 + */ + private Integer isOxygenWarnExist; + + /** + * 水温 + */ + private Double valueTemperature; + + /** + * 是否已触发温度报警 + */ + private Integer isTempWarnExist; + + /** + * 饱和度 + */ + private Double valueSaturability; + + /** + * PH + */ + private Double valuePh; + + /** + * 盐度 + */ + private Double valueSalinity; + + /** + * 溶解氧电话告警开关 + */ + private Integer oxyWarnCallOpen; + + /** + * 低溶氧告警免打扰 + */ + private Integer oxyWarnCallNoDis; + + /** + * 上次溶解氧电话告警时间 + */ + private Date oxyWarnCallLastTime; + + /** + * 溶解氧电话告警下限 + */ + private Double oxyWarnLower; + + /** + * 温度电话告警开关 + */ + private Integer tempWarnCallOpen; + + /** + * 温度告警免打扰 + */ + private Integer tempWarnCallNoDis; + + /** + * 上次温度电话告警时间 + */ + private Date tempWarnCallLastTime; + + /** + * 温度电话告警上限 + */ + private Double tempWarnUpper; + + /** + * 温度电话告警下限 + */ + private Double tempWarnLower; + + /** + * 设置的盐度补偿 + */ + private Double salinityCompensation; + + /** + * 输入额定电压 + */ + private Integer inputVoltage; + + /** + * 设备告警状态码 + */ + private Integer warnCode; + + /** + * 物联网卡号 + */ + private String iccId; + + /** + * 相位差 + */ + private Double phaseDifference; + + /** + * 荧光值 + */ + private Double tfluorescence; + + /** + * 参比值 + */ + private Double treference; + + /** + * 线性系数补偿 + */ + private Double phaseCompensation; + + /** + * 相位差补偿 + */ + private Double phasedifCompensation; + + /** + * 温度补偿 + */ + private Double temperatureCompensation; + + /** + * 电压告警开关 + */ + private Integer voltageWarnOpen; + + /** + * 备注 + */ + private String remark; + + /** + * 设备分类 + */ + private String category; + + /** + * 电量电话告警开关 + */ + private Long batteryWarnCallOpen; + + /** + * 电量告警免打扰 + */ + private Long batteryWarnCallNoDis; + + /** + * 上次电量电话告警时间 + */ + private Date batteryWarnCallLastTime; + + /** + * 电量电话告警下限 + */ + private Long batteryWarnLower; + + +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/DeviceBindRecord.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/DeviceBindRecord.java new file mode 100644 index 0000000..c6f3f05 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/DeviceBindRecord.java @@ -0,0 +1,56 @@ +package org.dromara.fishery.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 设备绑定记录对象 aqu_device_bind_record + * + * @author intc + * @date 2025-10-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("aqu_device_bind_record") +public class DeviceBindRecord extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 物联网IotId + */ + private String iotId; + + /** + * 设备类型 + */ + private Long deviceType; + + /** + * 设备编号 + */ + private String serialNum; + + /** + * 用户id + */ + private Long userId; + + /** + * 绑定/解绑 + */ + private Integer isBind; + + +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/DeviceBindRecordBo.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/DeviceBindRecordBo.java new file mode 100644 index 0000000..1abc4cc --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/DeviceBindRecordBo.java @@ -0,0 +1,60 @@ +package org.dromara.fishery.domain.bo; + +import org.dromara.fishery.domain.DeviceBindRecord; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 设备绑定记录业务对象 aqu_device_bind_record + * + * @author intc + * @date 2025-10-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = DeviceBindRecord.class, reverseConvertGenerate = false) +public class DeviceBindRecordBo extends BaseEntity { + + /** + * 主键id + */ +// @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 物联网IotId + */ + @NotBlank(message = "物联网IotId不能为空", groups = { AddGroup.class, EditGroup.class }) + private String iotId; + + /** + * 设备类型 + */ + @NotNull(message = "设备类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long deviceType; + + /** + * 设备编号 + */ + @NotBlank(message = "设备编号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String serialNum; + + /** + * 用户id + */ + @NotNull(message = "用户id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long userId; + + /** + * 绑定/解绑 + */ + @NotNull(message = "绑定/解绑不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer isBind; + + +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/DeviceBo.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/DeviceBo.java new file mode 100644 index 0000000..d82f851 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/DeviceBo.java @@ -0,0 +1,275 @@ +package org.dromara.fishery.domain.bo; + +import org.dromara.fishery.domain.Device; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 设备管理业务对象 aqu_device + * + * @author intc + * @date 2025-10-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = Device.class, reverseConvertGenerate = false) +public class DeviceBo extends BaseEntity { + + /** + * 主键id + */ +// @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 物联网IotId + */ + @NotBlank(message = "物联网IotId不能为空", groups = { AddGroup.class, EditGroup.class }) + private String iotId; + + /** + * 设备编号 + */ + @NotBlank(message = "设备编号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String serialNum; + + /** + * 设备名称 + */ + @NotBlank(message = "设备名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String deviceName; + + /** + * 设备类型 + */ + @NotNull(message = "设备类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer deviceType; + + /** + * 绑定时间 + */ + @NotNull(message = "绑定时间不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date bindTime; + + /** + * 服务到期 + */ + @NotNull(message = "服务到期不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date deadTime; + + /** + * 塘口id + */ + private Long pondId; + + /** + * 溶解氧参数配置开关 + */ +// @NotNull(message = "溶解氧参数配置开关不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer isOxygenUsed; + + /** + * 溶解氧 + */ +// @NotNull(message = "溶解氧不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double valueDissolvedOxygen; + + /** + * 是否已触发溶解氧报警 + */ +// @NotNull(message = "是否已触发溶解氧报警不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer isOxygenWarnExist; + + /** + * 水温 + */ +// @NotNull(message = "水温不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double valueTemperature; + + /** + * 是否已触发温度报警 + */ +// @NotNull(message = "是否已触发温度报警不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer isTempWarnExist; + + /** + * 饱和度 + */ +// @NotNull(message = "饱和度不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double valueSaturability; + + /** + * PH + */ +// @NotNull(message = "PH不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double valuePh; + + /** + * 盐度 + */ +// @NotNull(message = "盐度不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double valueSalinity; + + /** + * 溶解氧电话告警开关 + */ +// @NotNull(message = "溶解氧电话告警开关不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer oxyWarnCallOpen; + + /** + * 低溶氧告警免打扰 + */ +// @NotNull(message = "低溶氧告警免打扰不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer oxyWarnCallNoDis; + + /** + * 上次溶解氧电话告警时间 + */ +// @NotNull(message = "上次溶解氧电话告警时间不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date oxyWarnCallLastTime; + + /** + * 溶解氧电话告警下限 + */ +// @NotNull(message = "溶解氧电话告警下限不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double oxyWarnLower; + + /** + * 温度电话告警开关 + */ +// @NotNull(message = "温度电话告警开关不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer tempWarnCallOpen; + + /** + * 温度告警免打扰 + */ +// @NotNull(message = "温度告警免打扰不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer tempWarnCallNoDis; + + /** + * 上次温度电话告警时间 + */ +// @NotNull(message = "上次温度电话告警时间不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date tempWarnCallLastTime; + + /** + * 温度电话告警上限 + */ +// @NotNull(message = "温度电话告警上限不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double tempWarnUpper; + + /** + * 温度电话告警下限 + */ +// @NotNull(message = "温度电话告警下限不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double tempWarnLower; + + /** + * 设置的盐度补偿 + */ +// @NotNull(message = "设置的盐度补偿不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double salinityCompensation; + + /** + * 输入额定电压 + */ +// @NotNull(message = "输入额定电压不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer inputVoltage; + + /** + * 设备告警状态码 + */ +// @NotNull(message = "设备告警状态码不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer warnCode; + + /** + * 物联网卡号 + */ + private String iccId; + + /** + * 相位差 + */ +// @NotNull(message = "相位差不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double phaseDifference; + + /** + * 荧光值 + */ +// @NotNull(message = "荧光值不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double tfluorescence; + + /** + * 参比值 + */ +// @NotNull(message = "参比值不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double treference; + + /** + * 线性系数补偿 + */ +// @NotNull(message = "线性系数补偿不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double phaseCompensation; + + /** + * 相位差补偿 + */ +// @NotNull(message = "相位差补偿不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double phasedifCompensation; + + /** + * 温度补偿 + */ +// @NotNull(message = "温度补偿不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double temperatureCompensation; + + /** + * 电压告警开关 + */ +// @NotNull(message = "电压告警开关不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer voltageWarnOpen; + + /** + * 备注 + */ + private String remark; + + /** + * 设备分类 + */ + private String category; + + /** + * 电量电话告警开关 + */ + private Long batteryWarnCallOpen; + + /** + * 电量告警免打扰 + */ + private Long batteryWarnCallNoDis; + + /** + * 上次电量电话告警时间 + */ + private Date batteryWarnCallLastTime; + + /** + * 电量电话告警下限 + */ + private Long batteryWarnLower; + + +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/PondBo.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/PondBo.java index e6d0079..be8fc90 100644 --- a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/PondBo.java +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/bo/PondBo.java @@ -74,5 +74,15 @@ public class PondBo extends BaseEntity { */ private String remark; + /** + * 提报时间开始 + */ + private String startTime; + + /** + * 提报时间结束 + */ + private String endTime; + } diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/AquUserVo.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/AquUserVo.java index 722b29a..37c7332 100644 --- a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/AquUserVo.java +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/AquUserVo.java @@ -130,5 +130,9 @@ public class AquUserVo implements Serializable { @ExcelProperty(value = "备注") private String remark; + private Date createTime; + + private Date updateTime; + } diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceBindRecordVo.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceBindRecordVo.java new file mode 100644 index 0000000..95347b8 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceBindRecordVo.java @@ -0,0 +1,86 @@ +package org.dromara.fishery.domain.vo; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.fishery.domain.DeviceBindRecord; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + + + +/** + * 设备绑定记录视图对象 aqu_device_bind_record + * + * @author intc + * @date 2025-10-14 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = DeviceBindRecord.class) +public class DeviceBindRecordVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 物联网IotId + */ + @ExcelProperty(value = "物联网IotId") + private String iotId; + + /** + * 设备类型 + */ + @ExcelProperty(value = "设备类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "aqu_device_type") + private Long deviceType; + + /** + * 设备编号 + */ + @ExcelProperty(value = "设备编号") + private String serialNum; + + /** + * 用户id + */ + @ExcelProperty(value = "用户id") + private Long userId; + + /** + * 绑定/解绑 + */ + @ExcelProperty(value = "绑定/解绑", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "is_bind") + private Integer isBind; + + /** + * 手机号 + */ + @ExcelProperty(value = "手机号") + private String mobilePhone; + + /** + * 用户名 + */ + @ExcelProperty(value = "用户名") + private String userName; + + private Date createTime; + + private Date updateTime; + +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceThresholdVo.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceThresholdVo.java index d959619..a01dbdd 100644 --- a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceThresholdVo.java +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceThresholdVo.java @@ -64,5 +64,9 @@ public class DeviceThresholdVo implements Serializable { @ExcelProperty(value = "备注") private String remark; + private Date createTime; + + private Date updateTime; + } diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceVo.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceVo.java new file mode 100644 index 0000000..54b4dfb --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/DeviceVo.java @@ -0,0 +1,344 @@ +package org.dromara.fishery.domain.vo; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.common.json.handler.DoubleSerializer; +import org.dromara.fishery.domain.Device; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + + + +/** + * 设备管理视图对象 aqu_device + * + * @author intc + * @date 2025-10-14 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = Device.class) +public class DeviceVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 用户id + */ + @ExcelProperty(value = "用户id") + private Long userId; + + /** + * 物联网IotId + */ + @ExcelProperty(value = "物联网IotId") + private String iotId; + + /** + * 设备编号 + */ + @ExcelProperty(value = "设备编号") + private String serialNum; + + /** + * 设备名称 + */ + @ExcelProperty(value = "设备名称") + private String deviceName; + + /** + * 设备类型 + */ + @ExcelProperty(value = "设备类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "aqu_device_type") + private Integer deviceType; + + /** + * 绑定时间 + */ + @ExcelProperty(value = "绑定时间") + private Date bindTime; + + /** + * 服务到期 + */ + @ExcelProperty(value = "服务到期") + private Date deadTime; + + /** + * 塘口id + */ + @ExcelProperty(value = "塘口id") + private Long pondId; + + /** + * 溶解氧参数配置开关 + */ + @ExcelProperty(value = "溶解氧参数配置开关") + private Integer isOxygenUsed; + + /** + * 溶解氧 + */ + @ExcelProperty(value = "溶解氧") + @JsonSerialize(using = DoubleSerializer.class) + private Double valueDissolvedOxygen; + + /** + * 是否已触发溶解氧报警 + */ + @ExcelProperty(value = "是否已触发溶解氧报警") + private Integer isOxygenWarnExist; + + /** + * 水温 + */ + @ExcelProperty(value = "水温") + @JsonSerialize(using = DoubleSerializer.class) + private Double valueTemperature; + + /** + * 是否已触发温度报警 + */ + @ExcelProperty(value = "是否已触发温度报警") + private Integer isTempWarnExist; + + /** + * 饱和度 + */ + @ExcelProperty(value = "饱和度") + @JsonSerialize(using = DoubleSerializer.class) + private Double valueSaturability; + + /** + * PH + */ + @ExcelProperty(value = "PH") + @JsonSerialize(using = DoubleSerializer.class) + private Double valuePh; + + /** + * 盐度 + */ + @ExcelProperty(value = "盐度") + @JsonSerialize(using = DoubleSerializer.class) + private Double valueSalinity; + + /** + * 溶解氧电话告警开关 + */ + @ExcelProperty(value = "溶解氧电话告警开关") + private Integer oxyWarnCallOpen; + + /** + * 低溶氧告警免打扰 + */ + @ExcelProperty(value = "低溶氧告警免打扰") + private Integer oxyWarnCallNoDis; + + /** + * 上次溶解氧电话告警时间 + */ + @ExcelProperty(value = "上次溶解氧电话告警时间") + private Date oxyWarnCallLastTime; + + /** + * 溶解氧电话告警下限 + */ + @ExcelProperty(value = "溶解氧电话告警下限") + @JsonSerialize(using = DoubleSerializer.class) + private Double oxyWarnLower; + + /** + * 温度电话告警开关 + */ + @ExcelProperty(value = "温度电话告警开关") + private Integer tempWarnCallOpen; + + /** + * 温度告警免打扰 + */ + @ExcelProperty(value = "温度告警免打扰") + private Integer tempWarnCallNoDis; + + /** + * 上次温度电话告警时间 + */ + @ExcelProperty(value = "上次温度电话告警时间") + private Date tempWarnCallLastTime; + + /** + * 温度电话告警上限 + */ + @ExcelProperty(value = "温度电话告警上限") + @JsonSerialize(using = DoubleSerializer.class) + private Double tempWarnUpper; + + /** + * 温度电话告警下限 + */ + @ExcelProperty(value = "温度电话告警下限") + @JsonSerialize(using = DoubleSerializer.class) + private Double tempWarnLower; + + /** + * 设置的盐度补偿 + */ + @ExcelProperty(value = "设置的盐度补偿") + @JsonSerialize(using = DoubleSerializer.class) + private Double salinityCompensation; + + /** + * 输入额定电压 + */ + @ExcelProperty(value = "输入额定电压") + private Integer inputVoltage; + + /** + * 设备告警状态码 + */ + @ExcelProperty(value = "设备告警状态码") + private Integer warnCode; + + /** + * 物联网卡号 + */ + @ExcelProperty(value = "物联网卡号") + private String iccId; + + /** + * 相位差 + */ + @ExcelProperty(value = "相位差") + @JsonSerialize(using = DoubleSerializer.class) + private Double phaseDifference; + + /** + * 荧光值 + */ + @ExcelProperty(value = "荧光值") + @JsonSerialize(using = DoubleSerializer.class) + private Double tfluorescence; + + /** + * 参比值 + */ + @ExcelProperty(value = "参比值") + @JsonSerialize(using = DoubleSerializer.class) + private Double treference; + + /** + * 线性系数补偿 + */ + @ExcelProperty(value = "线性系数补偿") + @JsonSerialize(using = DoubleSerializer.class) + private Double phaseCompensation; + + /** + * 相位差补偿 + */ + @ExcelProperty(value = "相位差补偿") + @JsonSerialize(using = DoubleSerializer.class) + private Double phasedifCompensation; + + /** + * 温度补偿 + */ + @ExcelProperty(value = "温度补偿") + @JsonSerialize(using = DoubleSerializer.class) + private Double temperatureCompensation; + + /** + * 电压告警开关 + */ + @ExcelProperty(value = "电压告警开关") + private Integer voltageWarnOpen; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 设备分类 + */ + @ExcelProperty(value = "设备分类") + private String category; + + /** + * 电量电话告警开关 + */ + @ExcelProperty(value = "电量电话告警开关") + private Long batteryWarnCallOpen; + + /** + * 电量告警免打扰 + */ + @ExcelProperty(value = "电量告警免打扰") + private Long batteryWarnCallNoDis; + + /** + * 上次电量电话告警时间 + */ + @ExcelProperty(value = "上次电量电话告警时间") + private Date batteryWarnCallLastTime; + + /** + * 电量电话告警下限 + */ + @ExcelProperty(value = "电量电话告警下限") + private Long batteryWarnLower; + + /** + * 手机号 + */ + @ExcelProperty(value = "手机号") + private String mobilePhone; + + /** + * 用户名 + */ + @ExcelProperty(value = "用户名") + private String userName; + + /** + * 塘口名称 + */ + @ExcelProperty(value = "塘口名称") + private String pondName; + + /** + * 是否过期(0-未过期,1-已过期) + */ + @ExcelProperty(value = "是否过期") + private Integer isExpired; + + /** + * 过期天数(正数表示已过期天数,负数表示距离过期还有多少天) + */ + @ExcelProperty(value = "过期天数") + private Long expiredDays; + + + private Date createTime; + + private Date updateTime; + +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/FishVo.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/FishVo.java index 0b1ed0b..2c5c222 100644 --- a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/FishVo.java +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/FishVo.java @@ -53,5 +53,9 @@ public class FishVo implements Serializable { @ExcelProperty(value = "备注") private String remark; + private Date createTime; + + private Date updateTime; + } diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/PondVo.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/PondVo.java index 25e715b..f200406 100644 --- a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/PondVo.java +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/domain/vo/PondVo.java @@ -1,19 +1,16 @@ package org.dromara.fishery.domain.vo; -import java.util.Date; -import com.fasterxml.jackson.annotation.JsonFormat; -import org.dromara.fishery.domain.Pond; -import cn.idev.excel.annotation.ExcelIgnoreUnannotated; -import cn.idev.excel.annotation.ExcelProperty; -import org.dromara.common.excel.annotation.ExcelDictFormat; -import org.dromara.common.excel.convert.ExcelDictConvert; -import io.github.linpeilie.annotations.AutoMapper; -import lombok.Data; - import java.io.Serial; import java.io.Serializable; import java.util.Date; +import org.dromara.fishery.domain.Pond; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + /** @@ -78,5 +75,27 @@ public class PondVo implements Serializable { @ExcelProperty(value = "夜间防止误关") private Integer keepNightOpen; + /** + * 鱼品种列表 + */ + @ExcelProperty(value = "鱼品种列表") + private String fishKindNames; + + /** + * 用户名 + */ + @ExcelProperty(value = "用户名") + private String userName; + + /** + * 手机号 + */ + @ExcelProperty(value = "手机号") + private String mobilePhone; + + private Date createTime; + + private Date updateTime; + } diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/mapper/DeviceBindRecordMapper.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/mapper/DeviceBindRecordMapper.java new file mode 100644 index 0000000..a01aaa6 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/mapper/DeviceBindRecordMapper.java @@ -0,0 +1,15 @@ +package org.dromara.fishery.mapper; + +import org.dromara.fishery.domain.DeviceBindRecord; +import org.dromara.fishery.domain.vo.DeviceBindRecordVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 设备绑定记录Mapper接口 + * + * @author intc + * @date 2025-10-14 + */ +public interface DeviceBindRecordMapper extends BaseMapperPlus { + +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/mapper/DeviceMapper.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/mapper/DeviceMapper.java new file mode 100644 index 0000000..fd22b11 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/mapper/DeviceMapper.java @@ -0,0 +1,16 @@ +package org.dromara.fishery.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.fishery.domain.Device; +import org.dromara.fishery.domain.vo.DeviceVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 设备管理Mapper接口 + * + * @author intc + * @date 2025-10-14 + */ +public interface DeviceMapper extends BaseMapperPlus { + +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/IDeviceBindRecordService.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/IDeviceBindRecordService.java new file mode 100644 index 0000000..210d562 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/IDeviceBindRecordService.java @@ -0,0 +1,68 @@ +package org.dromara.fishery.service; + +import org.dromara.fishery.domain.vo.DeviceBindRecordVo; +import org.dromara.fishery.domain.bo.DeviceBindRecordBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 设备绑定记录Service接口 + * + * @author intc + * @date 2025-10-14 + */ +public interface IDeviceBindRecordService { + + /** + * 查询设备绑定记录 + * + * @param id 主键 + * @return 设备绑定记录 + */ + DeviceBindRecordVo queryById(Long id); + + /** + * 分页查询设备绑定记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备绑定记录分页列表 + */ + TableDataInfo queryPageList(DeviceBindRecordBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的设备绑定记录列表 + * + * @param bo 查询条件 + * @return 设备绑定记录列表 + */ + List queryList(DeviceBindRecordBo bo); + + /** + * 新增设备绑定记录 + * + * @param bo 设备绑定记录 + * @return 是否新增成功 + */ + Boolean insertByBo(DeviceBindRecordBo bo); + + /** + * 修改设备绑定记录 + * + * @param bo 设备绑定记录 + * @return 是否修改成功 + */ + Boolean updateByBo(DeviceBindRecordBo bo); + + /** + * 校验并批量删除设备绑定记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/IDeviceService.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/IDeviceService.java new file mode 100644 index 0000000..6436ddf --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/IDeviceService.java @@ -0,0 +1,68 @@ +package org.dromara.fishery.service; + +import org.dromara.fishery.domain.vo.DeviceVo; +import org.dromara.fishery.domain.bo.DeviceBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 设备管理Service接口 + * + * @author intc + * @date 2025-10-14 + */ +public interface IDeviceService { + + /** + * 查询设备管理 + * + * @param id 主键 + * @return 设备管理 + */ + DeviceVo queryById(Long id); + + /** + * 分页查询设备管理列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备管理分页列表 + */ + TableDataInfo queryPageList(DeviceBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的设备管理列表 + * + * @param bo 查询条件 + * @return 设备管理列表 + */ + List queryList(DeviceBo bo); + + /** + * 新增设备管理 + * + * @param bo 设备管理 + * @return 是否新增成功 + */ + Boolean insertByBo(DeviceBo bo); + + /** + * 修改设备管理 + * + * @param bo 设备管理 + * @return 是否修改成功 + */ + Boolean updateByBo(DeviceBo bo); + + /** + * 校验并批量删除设备管理信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/AquUserServiceImpl.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/AquUserServiceImpl.java index f526cdb..c910b59 100644 --- a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/AquUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/AquUserServiceImpl.java @@ -73,7 +73,7 @@ public class AquUserServiceImpl implements IAquUserService { private LambdaQueryWrapper buildQueryWrapper(AquUserBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(AquUser::getId); + lqw.orderByDesc(AquUser::getCreateTime); lqw.like(StringUtils.isNotBlank(bo.getUserName()), AquUser::getUserName, bo.getUserName()); lqw.like(StringUtils.isNotBlank(bo.getMobilePhone()), AquUser::getMobilePhone, bo.getMobilePhone()); lqw.eq(StringUtils.isNotBlank(bo.getProvince()), AquUser::getProvince, bo.getProvince()); diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceBindRecordServiceImpl.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceBindRecordServiceImpl.java new file mode 100644 index 0000000..58931c8 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceBindRecordServiceImpl.java @@ -0,0 +1,236 @@ +package org.dromara.fishery.service.impl; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.dromara.fishery.domain.AquUser; +import org.dromara.fishery.domain.bo.DeviceBindRecordBo; +import org.dromara.fishery.domain.vo.DeviceBindRecordVo; +import org.dromara.fishery.domain.DeviceBindRecord; +import org.dromara.fishery.mapper.AquUserMapper; +import org.dromara.fishery.mapper.DeviceBindRecordMapper; +import org.dromara.fishery.service.IDeviceBindRecordService; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Collection; +import java.util.stream.Collectors; + +/** + * 设备绑定记录Service业务层处理 + * + * @author intc + * @date 2025-10-14 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class DeviceBindRecordServiceImpl implements IDeviceBindRecordService { + + private final DeviceBindRecordMapper baseMapper; + private final AquUserMapper aquUserMapper; + + /** + * 查询设备绑定记录 + * + * @param id 主键 + * @return 设备绑定记录 + */ + @Override + public DeviceBindRecordVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询设备绑定记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备绑定记录分页列表 + */ + @Override + public TableDataInfo queryPageList(DeviceBindRecordBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + + // 批量填充用户信息 + enrichRecordListWithUserInfo(result.getRecords()); + + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的设备绑定记录列表 + * + * @param bo 查询条件 + * @return 设备绑定记录列表 + */ + @Override + public List queryList(DeviceBindRecordBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + List recordList = baseMapper.selectVoList(lqw); + + // 批量填充用户信息 + enrichRecordListWithUserInfo(recordList); + + return recordList; + } + + private LambdaQueryWrapper buildQueryWrapper(DeviceBindRecordBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByDesc(DeviceBindRecord::getCreateTime); + lqw.like(StringUtils.isNotBlank(bo.getIotId()), DeviceBindRecord::getIotId, bo.getIotId()); + lqw.eq(bo.getDeviceType() != null, DeviceBindRecord::getDeviceType, bo.getDeviceType()); + lqw.eq(StringUtils.isNotBlank(bo.getSerialNum()), DeviceBindRecord::getSerialNum, bo.getSerialNum()); + lqw.eq(bo.getUserId() != null, DeviceBindRecord::getUserId, bo.getUserId()); + lqw.eq(bo.getIsBind() != null, DeviceBindRecord::getIsBind, bo.getIsBind()); + + // 处理额外的查询参数 + if (params != null && !params.isEmpty()) { + handleExtraParams(lqw, params); + } + + return lqw; + } + + /** + * 处理额外的查询参数 + * + * @param lqw 查询包装器 + * @param params 额外参数 + */ + private void handleExtraParams(LambdaQueryWrapper lqw, Map params) { + // 处理用户搜索关键词(用户名或手机号) + String userKeyword = (String) params.get("userKeyword"); + if (StringUtils.isNotBlank(userKeyword)) { + List matchingUserIds = getMatchingUserIds(userKeyword); + if (matchingUserIds.isEmpty()) { + // 如果没有符合条件的用户,直接返回空结果 + lqw.eq(DeviceBindRecord::getId, -1); // 使用不存在的ID来返回空结果 + return; + } + lqw.in(DeviceBindRecord::getUserId, matchingUserIds); + } + } + + /** + * 新增设备绑定记录 + * + * @param bo 设备绑定记录 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(DeviceBindRecordBo bo) { + DeviceBindRecord add = MapstructUtils.convert(bo, DeviceBindRecord.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改设备绑定记录 + * + * @param bo 设备绑定记录 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(DeviceBindRecordBo bo) { + DeviceBindRecord update = MapstructUtils.convert(bo, DeviceBindRecord.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(DeviceBindRecord entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除设备绑定记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + /** + * 为记录列表批量填充用户信息 + * + * @param recordList 记录列表 + */ + private void enrichRecordListWithUserInfo(List recordList) { + if (recordList == null || recordList.isEmpty()) { + return; + } + + // 收集所有的用户ID + List userIds = recordList.stream() + .map(DeviceBindRecordVo::getUserId) + .filter(userId -> userId != null) + .distinct() + .collect(Collectors.toList()); + + if (userIds.isEmpty()) { + return; + } + + // 批量查询用户信息 + List userList = aquUserMapper.selectBatchIds(userIds); + Map userMap = userList.stream() + .collect(Collectors.toMap(AquUser::getId, user -> user, (existing, replacement) -> existing)); + + // 为每条记录设置用户信息 + for (DeviceBindRecordVo record : recordList) { + if (record.getUserId() != null) { + AquUser user = userMap.get(record.getUserId()); + if (user != null) { + record.setUserName(user.getUserName()); + record.setMobilePhone(user.getMobilePhone()); + } + } + } + } + + /** + * 根据用户关键词查询符合条件的用户ID列表 + * + * @param userKeyword 用户搜索关键词(用户名或手机号) + * @return 符合条件的用户ID列表 + */ + private List getMatchingUserIds(String userKeyword) { + if (StringUtils.isBlank(userKeyword)) { + return Arrays.asList(); + } + + LambdaQueryWrapper userQuery = Wrappers.lambdaQuery(); + userQuery.like(AquUser::getUserName, userKeyword) + .or() + .like(AquUser::getMobilePhone, userKeyword); + + List matchingUsers = aquUserMapper.selectList(userQuery); + return matchingUsers.stream() + .map(AquUser::getId) + .collect(Collectors.toList()); + } +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceServiceImpl.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceServiceImpl.java new file mode 100644 index 0000000..2481109 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceServiceImpl.java @@ -0,0 +1,389 @@ +package org.dromara.fishery.service.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.fishery.domain.AquUser; +import org.dromara.fishery.domain.Device; +import org.dromara.fishery.domain.Pond; +import org.dromara.fishery.domain.bo.DeviceBo; +import org.dromara.fishery.domain.vo.DeviceVo; +import org.dromara.fishery.mapper.AquUserMapper; +import org.dromara.fishery.mapper.DeviceMapper; +import org.dromara.fishery.mapper.PondMapper; +import org.dromara.fishery.service.IDeviceService; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * 设备管理Service业务层处理 + * + * @author intc + * @date 2025-10-14 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class DeviceServiceImpl implements IDeviceService { + + private final DeviceMapper baseMapper; + private final AquUserMapper aquUserMapper; + private final PondMapper pondMapper; + + /** + * 查询设备管理 + * + * @param id 主键 + * @return 设备管理 + */ + @Override + public DeviceVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询设备管理列表 - 批量查询方案(避免N+1问题) + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备管理分页列表 + */ + @Override + public TableDataInfo queryPageList(DeviceBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + + // 批量填充关联数据 + enrichDeviceListWithUserInfo(result.getRecords()); + enrichDeviceListWithPondInfo(result.getRecords()); + // 计算过期信息 + calculateExpirationInfo(result.getRecords()); + + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的设备管理列表 - 批量查询方案(避免N+1问题) + * + * @param bo 查询条件 + * @return 设备管理列表 + */ + @Override + public List queryList(DeviceBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + List deviceList = baseMapper.selectVoList(lqw); + + // 批量填充关联数据 + enrichDeviceListWithUserInfo(deviceList); + enrichDeviceListWithPondInfo(deviceList); + // 计算过期信息 + calculateExpirationInfo(deviceList); + + return deviceList; + } + + private LambdaQueryWrapper buildQueryWrapper(DeviceBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + + // 处理排序逼辑:如果expiredFlag为1,按过期时间倒序,否则按创建时间倒序 + String expiredFlag = params != null ? (String) params.get("expiredFlag") : null; + if ("1".equals(expiredFlag)) { + // 按deadTime倒序(过期时间越早的越靠后,即过期越久的越靠前) + lqw.orderByAsc(Device::getDeadTime); + } else { + lqw.orderByDesc(Device::getCreateTime); + } + + lqw.eq(bo.getUserId() != null, Device::getUserId, bo.getUserId()); + lqw.eq(StringUtils.isNotBlank(bo.getSerialNum()), Device::getSerialNum, bo.getSerialNum()); + lqw.like(StringUtils.isNotBlank(bo.getDeviceName()), Device::getDeviceName, bo.getDeviceName()); + lqw.eq(bo.getDeviceType() != null, Device::getDeviceType, bo.getDeviceType()); + lqw.eq(bo.getBindTime() != null, Device::getBindTime, bo.getBindTime()); + lqw.eq(bo.getPondId() != null, Device::getPondId, bo.getPondId()); + lqw.like(StringUtils.isNotBlank(bo.getIccId()), Device::getIccId, bo.getIccId()); + lqw.eq(StringUtils.isNotBlank(bo.getCategory()), Device::getCategory, bo.getCategory()); + + // 处理额外的查询参数 + if (params != null && !params.isEmpty()) { + handleExtraParams(lqw, params); + } + + return lqw; + } + + /** + * 处理额外的查询参数 + * + * @param lqw 查询包装器 + * @param params 额外参数 + */ + private void handleExtraParams(LambdaQueryWrapper lqw, Map params) { + // 处理用户搜索关键词(用户名或手机号) + String userKeyword = (String) params.get("userKeyword"); + if (StringUtils.isNotBlank(userKeyword)) { + List matchingUserIds = getMatchingUserIds(userKeyword); + if (matchingUserIds.isEmpty()) { + // 如果没有符合条件的用户,直接返回空结果 + lqw.eq(Device::getId, -1); // 使用不存在的ID来返回空结果 + return; + } + lqw.in(Device::getUserId, matchingUserIds); + } + + // 处理塘口搜索关键词(塘口名称) + String pondKeyword = (String) params.get("pondKeyword"); + if (StringUtils.isNotBlank(pondKeyword)) { + List matchingPondIds = getMatchingPondIds(pondKeyword); + if (matchingPondIds.isEmpty()) { + // 如果没有符合条件的塘口,直接返回空结果 + lqw.eq(Device::getId, -1); // 使用不存在的ID来返回空结果 + return; + } + lqw.in(Device::getPondId, matchingPondIds); + } + + // 处理是否过期查询条件 + String isExpiredStr = (String) params.get("isExpired"); + if (StringUtils.isNotBlank(isExpiredStr)) { + try { + Integer isExpired = Integer.parseInt(isExpiredStr); + Date currentDate = new Date(); + if (isExpired == 1) { + // 查询已过期的设备(deadTime < 当前时间) + lqw.lt(Device::getDeadTime, currentDate); + } else if (isExpired == 0) { + // 查询未过期的设备(deadTime >= 当前时间 或 deadTime 为空) + lqw.and(wrapper -> wrapper.ge(Device::getDeadTime, currentDate) + .or() + .isNull(Device::getDeadTime)); + } + } catch (NumberFormatException e) { + log.warn("isExpired参数格式错误: {}", isExpiredStr); + } + } + } + + /** + * 新增设备管理 + * + * @param bo 设备管理 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(DeviceBo bo) { + Device add = MapstructUtils.convert(bo, Device.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改设备管理 + * + * @param bo 设备管理 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(DeviceBo bo) { + Device update = MapstructUtils.convert(bo, Device.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(Device entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除设备管理信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + /** + * 为设备列表批量填充用户信息 + * + * @param deviceList 设备列表 + */ + private void enrichDeviceListWithUserInfo(List deviceList) { + if (deviceList == null || deviceList.isEmpty()) { + return; + } + + // 收集所有的用户ID + List userIds = deviceList.stream() + .map(DeviceVo::getUserId) + .filter(userId -> userId != null) + .distinct() + .collect(Collectors.toList()); + + if (userIds.isEmpty()) { + return; + } + + // 批量查询用户信息 + List userList = aquUserMapper.selectBatchIds(userIds); + Map userMap = userList.stream() + .collect(Collectors.toMap(AquUser::getId, user -> user, (existing, replacement) -> existing)); + + // 为每个设备设置用户信息 + for (DeviceVo device : deviceList) { + if (device.getUserId() != null) { + AquUser user = userMap.get(device.getUserId()); + if (user != null) { + device.setUserName(user.getUserName()); + device.setMobilePhone(user.getMobilePhone()); + } + } + } + } + + /** + * 为设备列表批量填充塘口信息 + * + * @param deviceList 设备列表 + */ + private void enrichDeviceListWithPondInfo(List deviceList) { + if (deviceList == null || deviceList.isEmpty()) { + return; + } + + // 收集所有的塘口ID + List pondIds = deviceList.stream() + .map(DeviceVo::getPondId) + .filter(pondId -> pondId != null) + .distinct() + .collect(Collectors.toList()); + + if (pondIds.isEmpty()) { + return; + } + + // 批量查询塘口信息 + List pondList = pondMapper.selectBatchIds(pondIds); + Map pondMap = pondList.stream() + .collect(Collectors.toMap(Pond::getId, pond -> pond, (existing, replacement) -> existing)); + + // 为每个设备设置塘口信息 + for (DeviceVo device : deviceList) { + if (device.getPondId() != null) { + Pond pond = pondMap.get(device.getPondId()); + if (pond != null) { + device.setPondName(pond.getPondName()); + } + } + } + } + + /** + * 根据用户关键词查询符合条件的用户ID列表 + * + * @param userKeyword 用户搜索关键词(用户名或手机号) + * @return 符合条件的用户ID列表 + */ + private List getMatchingUserIds(String userKeyword) { + if (StringUtils.isBlank(userKeyword)) { + return Arrays.asList(); + } + + LambdaQueryWrapper userQuery = Wrappers.lambdaQuery(); + userQuery.like(AquUser::getUserName, userKeyword) + .or() + .like(AquUser::getMobilePhone, userKeyword); + + List matchingUsers = aquUserMapper.selectList(userQuery); + return matchingUsers.stream() + .map(AquUser::getId) + .collect(Collectors.toList()); + } + + /** + * 根据塘口关键词查询符合条件的塘口ID列表 + * + * @param pondKeyword 塘口搜索关键词(塘口名称) + * @return 符合条件的塘口ID列表 + */ + private List getMatchingPondIds(String pondKeyword) { + if (StringUtils.isBlank(pondKeyword)) { + return Arrays.asList(); + } + + LambdaQueryWrapper pondQuery = Wrappers.lambdaQuery(); + pondQuery.like(Pond::getPondName, pondKeyword); + + List matchingPonds = pondMapper.selectList(pondQuery); + return matchingPonds.stream() + .map(Pond::getId) + .collect(Collectors.toList()); + } + + /** + * 计算设备列表的过期信息 + * + * @param deviceList 设备列表 + */ + private void calculateExpirationInfo(List deviceList) { + if (deviceList == null || deviceList.isEmpty()) { + return; + } + + Date currentDate = new Date(); + long currentTime = currentDate.getTime(); + + for (DeviceVo device : deviceList) { + Date deadTime = device.getDeadTime(); + if (deadTime == null) { + // 如果没有设置到期时间,设置为未过期 + device.setIsExpired(0); + device.setExpiredDays(null); + continue; + } + + long deadTimestamp = deadTime.getTime(); + // 计算时间差(毫秒) + long diffMillis = currentTime - deadTimestamp; + // 转换为天数 + long daysDiff = diffMillis / (24 * 60 * 60 * 1000); + + if (currentTime > deadTimestamp) { + // 已过期 + device.setIsExpired(1); + device.setExpiredDays(daysDiff); // 正数表示已过期天数 + } else { + // 未过期 + device.setIsExpired(0); + device.setExpiredDays(daysDiff); // 负数表示距离过期还有多少天 + } + } + } +} diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceThresholdServiceImpl.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceThresholdServiceImpl.java index 6d6e6ce..aef36ab 100644 --- a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceThresholdServiceImpl.java +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/DeviceThresholdServiceImpl.java @@ -73,7 +73,8 @@ public class DeviceThresholdServiceImpl implements IDeviceThresholdService { private LambdaQueryWrapper buildQueryWrapper(DeviceThresholdBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(DeviceThreshold::getId); + lqw.orderByDesc(DeviceThreshold::getCreateTime); + lqw.orderByAsc(DeviceThreshold::getThresholdType); lqw.eq(bo.getThresholdType() != null, DeviceThreshold::getThresholdType, bo.getThresholdType()); lqw.like(StringUtils.isNotBlank(bo.getThresholdName()), DeviceThreshold::getThresholdName, bo.getThresholdName()); lqw.eq(bo.getLimitUpper() != null, DeviceThreshold::getLimitUpper, bo.getLimitUpper()); diff --git a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/PondServiceImpl.java b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/PondServiceImpl.java index 4d21aaf..deaef5f 100644 --- a/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/PondServiceImpl.java +++ b/ruoyi-modules/ruoyi-fishery/src/main/java/org/dromara/fishery/service/impl/PondServiceImpl.java @@ -1,24 +1,32 @@ package org.dromara.fishery.service.impl; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.fishery.domain.AquUser; +import org.dromara.fishery.domain.Fish; +import org.dromara.fishery.domain.Pond; import org.dromara.fishery.domain.bo.PondBo; import org.dromara.fishery.domain.vo.PondVo; -import org.dromara.fishery.domain.Pond; +import org.dromara.fishery.mapper.AquUserMapper; +import org.dromara.fishery.mapper.FishMapper; import org.dromara.fishery.mapper.PondMapper; import org.dromara.fishery.service.IPondService; +import org.springframework.stereotype.Service; -import java.util.List; -import java.util.Map; -import java.util.Collection; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; /** * 塘口管理Service业务层处理 @@ -33,6 +41,10 @@ public class PondServiceImpl implements IPondService { private final PondMapper baseMapper; + private final FishMapper fishMapper; + + private final AquUserMapper aquUserMapper; + /** * 查询塘口管理 * @@ -55,6 +67,13 @@ public class PondServiceImpl implements IPondService { public TableDataInfo queryPageList(PondBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + + // 填充鱼类名称信息 + enrichPondListWithFishNames(result.getRecords()); + + // 填充用户信息 + enrichPondListWithUserInfo(result.getRecords()); + return TableDataInfo.build(result); } @@ -67,21 +86,92 @@ public class PondServiceImpl implements IPondService { @Override public List queryList(PondBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); + List list = baseMapper.selectVoList(lqw); + + // 填充鱼类名称信息 + enrichPondListWithFishNames(list); + + // 填充用户信息 + enrichPondListWithUserInfo(list); + + return list; } private LambdaQueryWrapper buildQueryWrapper(PondBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(Pond::getId); - lqw.eq(bo.getUserId() != null, Pond::getUserId, bo.getUserId()); - lqw.like(StringUtils.isNotBlank(bo.getPondName()), Pond::getPondName, bo.getPondName()); - lqw.like(StringUtils.isNotBlank(bo.getFishKindIds()), Pond::getFishKindIds, bo.getFishKindIds()); - lqw.eq(bo.getPlaceTime() != null, Pond::getPlaceTime, bo.getPlaceTime()); - lqw.eq(bo.getKeepNightOpen() != null, Pond::getKeepNightOpen, bo.getKeepNightOpen()); + + // 基础条件查询 + lqw.eq(bo.getUserId() != null, Pond::getUserId, bo.getUserId()) + .like(StringUtils.isNotBlank(bo.getPondName()), Pond::getPondName, bo.getPondName()) + .like(StringUtils.isNotBlank(bo.getFishKindIds()), Pond::getFishKindIds, bo.getFishKindIds()) + .eq(bo.getPlaceTime() != null, Pond::getPlaceTime, bo.getPlaceTime()) + .eq(bo.getKeepNightOpen() != null, Pond::getKeepNightOpen, bo.getKeepNightOpen()); + + // 处理额外的查询参数 + if (params != null && !params.isEmpty()) { + handleExtraParams(lqw, params); + } + + // 默认按创建时间升序排列 + lqw.orderByDesc(Pond::getCreateTime); + return lqw; } + /** + * 处理额外的查询参数 + * + * @param lqw 查询包装器 + * @param params 额外参数 + */ + private void handleExtraParams(LambdaQueryWrapper lqw, Map params) { + // 处理用户搜索关键词 + String userKeyword = (String) params.get("userKeyword"); + if (StringUtils.isNotBlank(userKeyword)) { + List matchingUserIds = getMatchingUserIds(userKeyword); + if (matchingUserIds.isEmpty()) { + // 如果没有符合条件的用户,直接返回空结果 + lqw.eq(Pond::getId, -1); // 使用不存在的ID来返回空结果 + return; + } + lqw.in(Pond::getUserId, matchingUserIds); + } + + // 处理时间范围查询 + Object startTimeObj = params.get("startTime"); + Object endTimeObj = params.get("endTime"); + + String startTime = startTimeObj != null ? startTimeObj.toString() : null; + String endTime = endTimeObj != null ? endTimeObj.toString() : null; + + if (StringUtils.isNotBlank(startTime)) { + try { + // 验证日期格式并添加时分秒 + String startDateTime = startTime.trim(); + if (startDateTime.length() == 10) { // yyyy-MM-dd 格式 + startDateTime += " 00:00:00"; + } + lqw.ge(Pond::getCreateTime, startDateTime); + } catch (Exception e) { + log.warn("开始时间格式不正确: {}", startTime, e); + } + } + + if (StringUtils.isNotBlank(endTime)) { + try { + // 验证日期格式并添加时分秒 + String endDateTime = endTime.trim(); + if (endDateTime.length() == 10) { // yyyy-MM-dd 格式 + endDateTime += " 23:59:59"; + } + lqw.le(Pond::getCreateTime, endDateTime); + } catch (Exception e) { + log.warn("结束时间格式不正确: {}", endTime, e); + } + } + } + /** * 新增塘口管理 * @@ -133,4 +223,134 @@ public class PondServiceImpl implements IPondService { } return baseMapper.deleteByIds(ids) > 0; } + + /** + * 为塘口列表填充鱼类名称信息 + * 这个方法替代了原来在查询中的复杂子查询 + * + * @param pondList 塘口列表 + */ + private void enrichPondListWithFishNames(List pondList) { + if (pondList == null || pondList.isEmpty()) { + return; + } + + // 收集所有的鱼类ID + List allFishIds = pondList.stream() + .map(PondVo::getFishKindIds) + .filter(StringUtils::isNotBlank) + .flatMap(fishKindIds -> parseFishIds(fishKindIds).stream()) + .distinct() + .collect(Collectors.toList()); + + if (allFishIds.isEmpty()) { + return; + } + + // 批量查询鱼类信息 + List fishList = fishMapper.selectBatchIds(allFishIds); + Map fishNameMap = fishList.stream() + .collect(Collectors.toMap(Fish::getId, Fish::getFishName, (existing, replacement) -> existing)); + + // 为每个塘口设置鱼类名称(如果PondVo有fishNames字段的话) + // 注意:由于PondVo中没有fishNames字段,这里只是示例代码 + // 实际使用时可能需要扩展PondVo或者通过其他方式返回鱼类名称 + for (PondVo pond : pondList) { + List fishIds = parseFishIds(pond.getFishKindIds()); + List fishNames = fishIds.stream() + .map(id -> fishNameMap.getOrDefault(id, "未知鱼类")) + .collect(Collectors.toList()); + pond.setFishKindNames(String.join(",", fishNames)); // 如果PondVo有这个字段的话 + } + } + + /** + * 解析鱼类ID字符串 + * 支持格式: "[1,2,3]" 或 "1,2,3" + * + * @param fishKindIds 鱼类ID字符串 + * @return 鱼类ID列表 + */ + private List parseFishIds(String fishKindIds) { + if (StringUtils.isBlank(fishKindIds)) { + return Arrays.asList(); + } + + try { + // 移除方括号和空格 + String cleanIds = fishKindIds.replaceAll("[\\[\\]\\s]", ""); + if (StringUtils.isBlank(cleanIds)) { + return Arrays.asList(); + } + + return Arrays.stream(cleanIds.split(",")) + .filter(StringUtils::isNotBlank) + .map(String::trim) + .map(Long::parseLong) + .collect(Collectors.toList()); + } catch (NumberFormatException e) { + log.warn("解析鱼类ID失败: {}", fishKindIds, e); + return Arrays.asList(); + } + } + + /** + * 为塘口列表填充用户信息 + * + * @param pondList 塘口列表 + */ + private void enrichPondListWithUserInfo(List pondList) { + if (pondList == null || pondList.isEmpty()) { + return; + } + + // 收集所有的用户ID + List userIds = pondList.stream() + .map(PondVo::getUserId) + .filter(userId -> userId != null) + .distinct() + .collect(Collectors.toList()); + + if (userIds.isEmpty()) { + return; + } + + // 批量查询用户信息 + List userList = aquUserMapper.selectBatchIds(userIds); + Map userMap = userList.stream() + .collect(Collectors.toMap(AquUser::getId, user -> user, (existing, replacement) -> existing)); + + // 为每个塘口设置用户信息 + for (PondVo pond : pondList) { + if (pond.getUserId() != null) { + AquUser user = userMap.get(pond.getUserId()); + if (user != null) { + pond.setUserName(user.getUserName()); + pond.setMobilePhone(user.getMobilePhone()); + } + } + } + } + + /** + * 根据用户关键词查询符合条件的用户ID列表 + * + * @param userKeyword 用户搜索关键词(用户名或手机号) + * @return 符合条件的用户ID列表 + */ + private List getMatchingUserIds(String userKeyword) { + if (StringUtils.isBlank(userKeyword)) { + return Arrays.asList(); + } + + LambdaQueryWrapper userQuery = Wrappers.lambdaQuery(); + userQuery.like(AquUser::getUserName, userKeyword) + .or() + .like(AquUser::getMobilePhone, userKeyword); + + List matchingUsers = aquUserMapper.selectList(userQuery); + return matchingUsers.stream() + .map(AquUser::getId) + .collect(Collectors.toList()); + } } diff --git a/ruoyi-modules/ruoyi-fishery/src/main/resources/mapper/fishery/DeviceBindRecordMapper.xml b/ruoyi-modules/ruoyi-fishery/src/main/resources/mapper/fishery/DeviceBindRecordMapper.xml new file mode 100644 index 0000000..d4b3683 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/resources/mapper/fishery/DeviceBindRecordMapper.xml @@ -0,0 +1,6 @@ + + + + diff --git a/ruoyi-modules/ruoyi-fishery/src/main/resources/mapper/fishery/DeviceMapper.xml b/ruoyi-modules/ruoyi-fishery/src/main/resources/mapper/fishery/DeviceMapper.xml new file mode 100644 index 0000000..fbe2eb6 --- /dev/null +++ b/ruoyi-modules/ruoyi-fishery/src/main/resources/mapper/fishery/DeviceMapper.xml @@ -0,0 +1,6 @@ + + + +