From 95aa01e1c253777166836659704963415617abe8 Mon Sep 17 00:00:00 2001 From: DragonWenLong <552045633@qq.com> Date: Fri, 22 Aug 2025 18:09:08 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat(device):=20=E6=96=B0=E5=A2=9E=E6=98=9F?= =?UTF-8?q?=E6=B1=89=E8=AE=BE=E5=A4=87=E6=8E=A7=E5=88=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加星汉设备控制器 AppDeviceXinghanController- 实现星汉设备业务逻辑 DeviceXinghanBizService - 增加开机 LOGO 下发规则 XinghanBootLogoRule - 添加设备发送消息规则 XinghanSendMsgRule - 更新 MQTT 命令类型常量 XingHanCommandTypeConstants - 修改设备状态 JSON 结构 MqttXinghanJson --- .../device/AppDeviceXinghanController.java | 96 +++++++ .../mqtt/base/MqttXinghanCommandType.java | 9 + .../global/mqtt/base/MqttXinghanJson.java | 14 +- .../XingHanCommandTypeConstants.java | 4 + .../rule/xinghan/XinghanBootLogoRule.java | 143 ++++++++++ .../mqtt/rule/xinghan/XinghanSendMsgRule.java | 117 ++++++++ .../device/DeviceXinghanBizService.java | 269 ++++++++++++++++++ 7 files changed, 645 insertions(+), 7 deletions(-) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanBootLogoRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanSendMsgRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java new file mode 100644 index 0000000..b4f53c5 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java @@ -0,0 +1,96 @@ +package com.fuyuanshen.app.controller.device; + +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.web.service.device.DeviceBJQBizService; +import com.fuyuanshen.web.service.device.DeviceXinghanBizService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * HBY670设备控制类 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/app/xinghan/device") +public class AppDeviceXinghanController extends BaseController { + + private final DeviceXinghanBizService appDeviceService; + /** + * 人员信息登记 + */ + @PostMapping(value = "/registerPersonInfo") +// @FunctionAccessAnnotation("registerPersonInfo") + public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { + return toAjax(appDeviceService.registerPersonInfo(bo)); + } + + /** + * 上传设备logo图片 + */ + @PostMapping("/uploadLogo") + @FunctionAccessAnnotation("uploadLogo") + public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { + + MultipartFile file = bo.getFile(); + if(file.getSize()>1024*1024*2){ + return R.warn("图片不能大于2M"); + } + appDeviceService.uploadDeviceLogo(bo); + + return R.ok(); + } + + /** + * 静电预警档位 + * 3,2,1,0,分别表示高档/中档/低挡/关闭 + */ + @PostMapping("/DetectGradeSettings") + public R DetectGradeSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.upDetectGradeSettings(params); + return R.ok(); + } + + /** + * 照明档位 + * 照明档位,2,1,0,分别表示弱光/强光/关闭 + */ + @PostMapping("/LightGradeSettings") + public R LightGradeSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.upLightGradeSettings(params); + return R.ok(); + } + + /** + * SOS档位 + * SOS档位,2,1,0, 分别表示红蓝模式/爆闪模式/关闭 + */ + @PostMapping("/SOSGradeSettings") + public R SOSGradeSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.upSOSGradeSettings(params); + return R.ok(); + } + + /** + * 静止报警状态 + * 静止报警状态,0-未静止报警,1-正在静止报警。 + */ + @PostMapping("/ShakeBitSettings") + public R ShakeBitSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.upShakeBitSettings(params); + return R.ok(); + } + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java index 6f6a6a8..99e7bc7 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java @@ -13,8 +13,17 @@ public final class MqttXinghanCommandType { private MqttXinghanCommandType() {} public enum XinghanCommandTypeEnum { + /** + * 星汉设备主动上报数据 + */ GRADE_INFO(101), + /** + * 星汉开机LOGO + */ PIC_TRANS(102), + /** + * 星汉设备发送消息 (XingHan send msg) + */ TEX_TRANS(103), BREAK_NEWS(104), UNKNOWN(0); diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java index fde03ac..2d49b46 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java @@ -20,37 +20,37 @@ public class MqttXinghanJson { * 第三键值对,SOS档位,2,1,0, 分别表示红蓝模式/爆闪模式/关闭 */ @JsonProperty("sta_SOSGrade") - public int staSOSGrade; + public Integer staSOSGrade; /** * 第四键值对,剩余照明时间,0-5999,单位分钟。 */ @JsonProperty("sta_PowerTime") - public int staPowerTime; + public Integer staPowerTime; /** * 第五键值对,剩余电量百分比,0-100 */ @JsonProperty("sta_PowerPercent") - public int staPowerPercent; + public Integer staPowerPercent; /** * 第六键值对, 近电预警级别, 0-无预警,1-弱预警,2-中预警,3-强预警,4-非常强预警。 */ @JsonProperty("sta_DetectResult") - public int staDetectResult; + public Integer staDetectResult; /** * 第七键值对, 静止报警状态,0-未静止报警,1-正在静止报警。 */ @JsonProperty("staShakeBit") - public int sta_ShakeBit; + public Integer sta_ShakeBit; /** * 第八键值对, 4G信号强度,0-32,数值越大,信号越强。 */ @JsonProperty("sta_4gSinal") - public int sta4gSinal; + public Integer sta4gSinal; /** * 第九键值对,IMIE卡号 */ @JsonProperty("sta_imei") - public int staimei; + public String staimei; /** * 第十键值对,经度 */ diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java index a7f4ba2..0b6f3d7 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java @@ -13,4 +13,8 @@ public class XingHanCommandTypeConstants { * 星汉设备发送消息 (XingHan send msg) */ public static final String XingHan_ESEND_MSG = "Light_103"; + /** + * 星汉设备发送紧急通知 (XingHan break news) + */ + public static final String XingHan_BREAK_NEWS = "Light_104"; } diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanBootLogoRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanBootLogoRule.java new file mode 100644 index 0000000..96faf30 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanBootLogoRule.java @@ -0,0 +1,143 @@ +package com.fuyuanshen.global.mqtt.rule.xinghan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.json.utils.JsonUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.global.mqtt.base.MqttMessageRule; +import com.fuyuanshen.global.mqtt.base.MqttRuleContext; +import com.fuyuanshen.global.mqtt.config.MqttGateway; +import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants; +import com.fuyuanshen.global.mqtt.constants.MqttConstants; +import com.fuyuanshen.global.mqtt.constants.XingHanCommandTypeConstants; +import com.fuyuanshen.global.mqtt.listener.domain.FunctionAccessStatus; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.time.Duration; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.zip.CRC32; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; +import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_BOOT_LOGO_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + +/** + * 星汉设备开机 LOGO 下发规则: + *

+ * 1. 设备上行 sta_PicTarns=great! => 仅标记成功
+ * 2. 设备上行 sta_PicTarns=数字 => 下发第 N 块数据(256B/块,带 CRC32) + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class XinghanBootLogoRule implements MqttMessageRule { + + private final MqttGateway mqttGateway; + private final ObjectMapper objectMapper; + + @Override + public String getCommandType() { + return XingHanCommandTypeConstants.XingHan_BOOT_LOGO; + } + + @Override + public void execute(MqttRuleContext ctx) { + final String functionAccessKey = FUNCTION_ACCESS_KEY + ctx.getDeviceImei(); + try { + MqttXinghanLogoJson payload = objectMapper.convertValue( + ctx.getPayloadDict(), MqttXinghanLogoJson.class); + + String respText = payload.getStaPicTrans(); + log.warn("设备上报LOGO:{}", respText); + + // 1. great! —— 成功标记 + if ("great!".equalsIgnoreCase(respText)) { + RedisUtils.setCacheObject(functionAccessKey, + FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); + log.info("设备 {} 开机 LOGO 写入成功", ctx.getDeviceImei()); + return; + } + + // 2. 数字 —— 下发数据块 + int blockIndex; + try { + blockIndex = Integer.parseInt(respText); + } catch (NumberFormatException ex) { + log.warn("设备 {} LOGO 上报非法块号:{}", ctx.getDeviceImei(), respText); + return; + } + String hexImage = RedisUtils.getCacheObject( + GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + ctx.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX); + if (StringUtils.isEmpty(hexImage)) { + return; + } + + byte[] fullBin = ImageToCArrayConverter.convertStringToByteArray(hexImage); + byte[] chunk = ImageToCArrayConverter.getChunk(fullBin, blockIndex - 1, CHUNK_SIZE); + log.info("设备 {} 第 {} 块数据长度: {} bytes", ctx.getDeviceImei(), blockIndex, chunk.length); + + // 组装下发数据 + ArrayList dataFrame = new ArrayList<>(); + dataFrame.add(blockIndex); // 块号 + ImageToCArrayConverter.buildArr(convertHexToDecimal(chunk), dataFrame); + dataFrame.addAll(crc32AsList(chunk)); // CRC32 + + Map pub = new HashMap<>(); + pub.put("ins_PicTrans", dataFrame); + + String topic = MqttConstants.GLOBAL_PUB_KEY + ctx.getDeviceImei(); + String json = JsonUtils.toJsonString(pub); + mqttGateway.sendMsgToMqtt(topic, 1, json); + + log.info("下发开机 LOGO 数据 => topic:{}, payload:{}", topic, json); + + } catch (Exception e) { + log.error("处理设备 {} 开机 LOGO 失败", ctx.getDeviceImei(), e); + RedisUtils.setCacheObject(functionAccessKey, + FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); + } + } + + /* ---------- 内部工具 ---------- */ + + private static final int CHUNK_SIZE = 256; + + private static ArrayList crc32AsList(byte[] data) { + CRC32 crc = new CRC32(); + crc.update(data); + byte[] crcBytes = ByteBuffer.allocate(4) + .order(ByteOrder.BIG_ENDIAN) + .putInt((int) crc.getValue()) + .array(); + ArrayList list = new ArrayList<>(4); + for (byte b : crcBytes) { + list.add(Byte.toUnsignedInt(b)); + } + return list; + } + + /* ---------- DTO ---------- */ + + @Data + private static class MqttXinghanLogoJson { + /** + * 设备上行: + * 数字 -> 请求对应块号 + * great! -> 写入成功 + */ + @JsonProperty("sta_PicTrans") + private String staPicTrans; + } +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanSendMsgRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanSendMsgRule.java new file mode 100644 index 0000000..68acb09 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanSendMsgRule.java @@ -0,0 +1,117 @@ +package com.fuyuanshen.global.mqtt.rule.xinghan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fuyuanshen.common.json.utils.JsonUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.global.mqtt.base.MqttMessageRule; +import com.fuyuanshen.global.mqtt.base.MqttRuleContext; +import com.fuyuanshen.global.mqtt.config.MqttGateway; +import com.fuyuanshen.global.mqtt.constants.MqttConstants; +import com.fuyuanshen.global.mqtt.constants.XingHanCommandTypeConstants; +import com.fuyuanshen.global.mqtt.listener.domain.FunctionAccessStatus; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.nio.charset.Charset; +import java.time.Duration; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + +/** + * 星汉设备发送消息 下发规则: + *

+ * 1. 设备上行 sta_TexTarns=genius! => 仅标记成功
+ * 2. 设备上行 sta_TexTarns=数字 => GBK编码,每行文字为一包,一共4包,第一字节为包序号 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class XinghanSendMsgRule implements MqttMessageRule { + + private final MqttGateway mqttGateway; + private final ObjectMapper objectMapper; + + @Override + public String getCommandType() { + return XingHanCommandTypeConstants.XingHan_ESEND_MSG; + } + + @Override + public void execute(MqttRuleContext ctx) { + String functionAccess = FUNCTION_ACCESS_KEY + ctx.getDeviceImei(); + try { + XinghanSendMsgRule.MqttXinghanMsgJson payload = objectMapper.convertValue( + ctx.getPayloadDict(), XinghanSendMsgRule.MqttXinghanMsgJson.class); + + String respText = payload.getStaTexTrans(); + log.info("设备上报人员信息: {} ", respText); + + // 1. genius! —— 成功标记 + if ("genius!".equalsIgnoreCase(respText)) { + RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); + log.info("设备 {} 发送消息完成", ctx.getDeviceImei()); + return; + } + // 2. 数字 —— 下发数据块 + int blockIndex; + try { + blockIndex = Integer.parseInt(respText); + } catch (NumberFormatException ex) { + log.warn("设备 {} 消息上报非法块号:{}", ctx.getDeviceImei(), respText); + return; + } + // 将发送的信息原文本以List形式存储在Redis中 + List data = RedisUtils.getCacheList(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + ctx.getDeviceImei() + ":app_send_message_data"); + if (data.isEmpty()) { + return; + } + // + ArrayList intData = new ArrayList<>(); + intData.add(blockIndex); + // 获取块原内容 转成GBK 再转成无符号十进制整数 + String blockTxt = data.get(blockIndex-1); + // 再按 GBK 编码把字符串转成字节数组,并逐个转为无符号十进制整数 + for (byte b : blockTxt.getBytes(GBK)) { + intData.add(b & 0xFF); // b & 0xFF 得到 0~255 的整数 + } + + Map map = new HashMap<>(); + map.put("ins_TexTrans", intData); + + String topic = MqttConstants.GLOBAL_PUB_KEY + ctx.getDeviceImei(); + String json = JsonUtils.toJsonString(map); + mqttGateway.sendMsgToMqtt(topic, 1, json); + log.info("发送设备信息数据到设备消息=>topic:{},payload:{}", + MqttConstants.GLOBAL_PUB_KEY + ctx.getDeviceImei(), + JsonUtils.toJsonString(map)); + + } catch (Exception e) { + log.error("处理发送设备信息时出错", e); + RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); + } + } + + private static final Charset GBK = Charset.forName("GBK"); + + /* ---------- DTO ---------- */ + + @Data + private static class MqttXinghanMsgJson { + /** + * 设备上行: + * 数字 -> 请求对应块号 + * genius! -> 写入成功 + */ + @JsonProperty("sta_TexTrans") + private String staTexTrans; + } +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java new file mode 100644 index 0000000..40c2d7a --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java @@ -0,0 +1,269 @@ +package com.fuyuanshen.web.service.device; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.fuyuanshen.app.domain.AppPersonnelInfo; +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; +import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; +import com.fuyuanshen.common.core.constant.GlobalConstants; +import com.fuyuanshen.common.core.exception.ServiceException; +import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; +import com.fuyuanshen.common.core.utils.MapstructUtils; +import com.fuyuanshen.common.core.utils.ObjectUtils; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.json.utils.JsonUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.common.satoken.utils.AppLoginHelper; +import com.fuyuanshen.equipment.domain.Device; +import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.equipment.enums.LightModeEnum; +import com.fuyuanshen.equipment.mapper.DeviceLogMapper; +import com.fuyuanshen.equipment.mapper.DeviceMapper; +import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; +import com.fuyuanshen.global.mqtt.config.MqttGateway; +import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; +import com.fuyuanshen.global.mqtt.constants.MqttConstants; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.time.Duration; +import java.util.*; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; +import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.buildArr; +import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.generateFixedBitmapData; +import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_BOOT_LOGO_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DeviceXinghanBizService { + + private final DeviceMapper deviceMapper; + private final AppPersonnelInfoMapper appPersonnelInfoMapper; + private final DeviceTypeMapper deviceTypeMapper; + private final MqttGateway mqttGateway; + private final DeviceLogMapper deviceLogMapper; + + /** + * 所有档位的描述表 + * key : 指令类型,如 "ins_DetectGrade"、"ins_LightGrade" …… + * value : Map 值 -> 描述 + */ + private static final Map> GRADE_DESC = Map.of( + "ins_DetectGrade", Map.of(1, "低档", 2, "中档", 3, "高档"), + "ins_LightGrade", Map.of(1, "强光", 2, "弱光"), + "ins_SOSGrade", Map.of(1, "爆闪模式", 2, "红蓝模式"), + "ins_ShakeBit", Map.of(0, "未静止报警", 1, "正在静止报警") + // 再加 4、5、6…… 档,直接往 Map 里塞即可 + ); + + /** + * 根据指令类型和值,返回中文描述 + */ + private static String resolveGradeDesc(String type, int value) { + return GRADE_DESC.getOrDefault(type, Map.of()) + .getOrDefault(value, "关闭"); + } + + /** + * 设置静电预警档位 + */ + public void upDetectGradeSettings(DeviceInstructDto dto) { + sendCommand(dto, "ins_DetectGrade","静电预警档位"); + } + + /** + * 设置照明档位 + */ + public void upLightGradeSettings(DeviceInstructDto dto) { + sendCommand(dto, "ins_LightGrade","照明档位"); + } + + /** + * 设置SOS档位 + */ + public void upSOSGradeSettings(DeviceInstructDto dto) { + sendCommand(dto, "ins_SOSGrade","SOS档位"); + } + + /** + * 设置强制报警 + */ + public void upShakeBitSettings(DeviceInstructDto dto) { + sendCommand(dto, "ins_ShakeBit","强制报警"); + } + + /** + * 上传设备logo + */ + public void uploadDeviceLogo(AppDeviceLogoUploadDto bo) { + try { + Device device = deviceMapper.selectById(bo.getDeviceId()); + if (device == null) { + throw new ServiceException("设备不存在"); + } + if (isDeviceOffline(device.getDeviceImei())) { + throw new ServiceException("设备已断开连接:" + device.getDeviceName()); + } + MultipartFile file = bo.getFile(); + + byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600); + log.info("长度:" + largeData.length); + + log.info("原始数据大小: {} 字节", largeData.length); + + int[] ints = convertHexToDecimal(largeData); + RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() +DEVICE_BOOT_LOGO_KEY_PREFIX, Arrays.toString(ints), Duration.ofSeconds(5 * 60L)); + + Map payload = Map.of("ins_PicTrans", + Collections.singletonList(0)); + String topic = MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(); + String json = JsonUtils.toJsonString(payload); + + try { + mqttGateway.sendMsgToMqtt(topic, 1, json); + } catch (Exception e) { + log.error("上传开机画面失败, topic={}, payload={}", topic, json, e); + throw new ServiceException("上传LOGO失败:" + e.getMessage()); + } + log.info("发送上传开机画面到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),json); + + recordDeviceLog(device.getId(), device.getDeviceName(), "上传开机画面", "上传开机画面", AppLoginHelper.getUserId()); + } catch (Exception e){ + throw new ServiceException("发送指令失败"); + } + } + + /** + * 人员登记 + * @param bo + */ + public boolean registerPersonInfo(AppPersonnelInfoBo bo) { + Long deviceId = bo.getDeviceId(); + Device deviceObj = deviceMapper.selectById(deviceId); + if (deviceObj == null) { + throw new RuntimeException("请先将设备入库!!!"); + } + if (isDeviceOffline(deviceObj.getDeviceImei())) { + throw new ServiceException("设备已断开连接:" + deviceObj.getDeviceName()); + } + QueryWrapper qw = new QueryWrapper() + .eq("device_id", deviceId); + List appPersonnelInfoVos = appPersonnelInfoMapper.selectVoList(qw); + + List list = new ArrayList<>(); + list.add(bo.getUnitName()); + list.add(bo.getName()); + list.add(bo.getPosition()); + list.add(bo.getCode()); + RedisUtils.setCacheList(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + deviceObj.getDeviceImei() + ":app_send_message_data", list); + + Map payload = Map.of("ins_TexTrans", + Collections.singletonList(0)); + String topic = MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(); + String json = JsonUtils.toJsonString(payload); + + try { + mqttGateway.sendMsgToMqtt(topic, 1, json); + } catch (Exception e) { + log.error("人员信息登记失败, topic={}, payload={}", topic, json, e); + throw new ServiceException("人员信息登记失败:" + e.getMessage()); + } + log.info("发送人员信息登记到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), bo); + + recordDeviceLog(deviceId, deviceObj.getDeviceName(), "人员信息登记", JSON.toJSONString(bo), AppLoginHelper.getUserId()); + if (ObjectUtils.length(appPersonnelInfoVos) == 0) { + AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); + return appPersonnelInfoMapper.insertOrUpdate(appPersonnelInfo); + } else { + UpdateWrapper uw = new UpdateWrapper<>(); + uw.eq("device_id", deviceId) + .set("name", bo.getName()) + .set("position", bo.getPosition()) + .set("unit_name", bo.getUnitName()) + .set("code", bo.getCode()); + return appPersonnelInfoMapper.update(null, uw) > 0; + } + } + + /* ---------------------------------- 私有通用方法 ---------------------------------- */ + + private void sendCommand(DeviceInstructDto dto, + String payloadKey,String deviceAction) { + long deviceId = dto.getDeviceId(); + Device device = deviceMapper.selectById(deviceId); + if (device == null) { + throw new ServiceException("设备不存在"); + } + if (isDeviceOffline(device.getDeviceImei())) { + throw new ServiceException("设备已断开连接:" + device.getDeviceName()); + } + + Integer value = Integer.parseInt(dto.getInstructValue()); + + Map payload = Map.of(payloadKey, + Collections.singletonList(value)); + + String topic = MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(); + String json = JsonUtils.toJsonString(payload); + + try { + mqttGateway.sendMsgToMqtt(topic, 1, json); + } catch (Exception e) { + log.error("发送指令失败, topic={}, payload={}", topic, json, e); + throw new ServiceException("发送指令失败:" + e.getMessage()); + } + + log.info("发送指令成功 => topic:{}, payload:{}", topic, json); + String content = resolveGradeDesc("ins_DetectGrade", value); + recordDeviceLog(device.getId(), + device.getDeviceName(), + deviceAction, + content, + AppLoginHelper.getUserId()); + } + + private boolean isDeviceOffline(String imei) { + // 原方法名语义相反,这里取反,使含义更清晰 + return getDeviceStatus(imei); + } + + /** + * 记录设备操作日志 + * @param deviceId 设备ID + * @param content 日志内容 + * @param operator 操作人 + */ + private void recordDeviceLog(Long deviceId,String deviceName, String deviceAction, String content, Long operator) { + try { + // 创建设备日志实体 + com.fuyuanshen.equipment.domain.DeviceLog deviceLog = new com.fuyuanshen.equipment.domain.DeviceLog(); + deviceLog.setDeviceId(deviceId); + deviceLog.setDeviceAction(deviceAction); + deviceLog.setContent(content); + deviceLog.setCreateBy(operator); + deviceLog.setDeviceName(deviceName); + deviceLog.setCreateTime(new Date()); + + // 插入日志记录 + deviceLogMapper.insert(deviceLog); + } catch (Exception e) { + log.error("记录设备操作日志失败: {}", e.getMessage(), e); + } + } + + private boolean getDeviceStatus(String deviceImei) { + String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ; + return StringUtils.isBlank(deviceOnlineStatusRedisKey); + } + +} From 8811c30a9730cfe07b0856507436735c5869fec0 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Sat, 23 Aug 2025 16:39:30 +0800 Subject: [PATCH 2/6] =?UTF-8?q?web=E7=AB=AF=E6=8E=A7=E5=88=B6=E4=B8=AD?= =?UTF-8?q?=E5=BF=832?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/device/TestController.java | 47 ++++ .../domain/dto/AppDeviceLogoUploadDto.java | 1 + .../device/DeviceBJQController.java | 2 +- .../device/DeviceControlCenterController.java | 222 +++++------------- .../device/WEBDeviceController.java | 61 +---- .../service/device/DeviceBJQBizService.java | 63 ++++- .../web/service/device/DeviceBizService.java | 42 ++++ .../core/utils/ImageToCArrayConverter.java | 18 ++ .../AppPersonnelInfoRecordsController.java | 105 +++++++++ .../app/domain/AppPersonnelInfoRecords.java | 66 ++++++ .../domain/bo/AppPersonnelInfoRecordsBo.java | 67 ++++++ .../domain/vo/AppPersonnelInfoRecordsVo.java | 80 +++++++ .../mapper/AppPersonnelInfoRecordsMapper.java | 15 ++ .../IAppPersonnelInfoRecordsService.java | 68 ++++++ .../AppPersonnelInfoRecordsServiceImpl.java | 138 +++++++++++ .../app/AppPersonnelInfoRecordsMapper.xml | 7 + .../domain/query/DeviceQueryCriteria.java | 6 + .../equipment/domain/vo/WebDeviceVo.java | 95 ++++++++ .../equipment/mapper/DeviceMapper.java | 3 + .../mapper/equipment/DeviceMapper.xml | 41 ++++ 20 files changed, 914 insertions(+), 233 deletions(-) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/controller/device/TestController.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppPersonnelInfoRecordsController.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppPersonnelInfoRecords.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoRecordsBo.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoRecordsVo.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppPersonnelInfoRecordsMapper.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/IAppPersonnelInfoRecordsService.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/impl/AppPersonnelInfoRecordsServiceImpl.java create mode 100644 fys-modules/fys-app/src/main/resources/mapper/app/AppPersonnelInfoRecordsMapper.xml create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/TestController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/TestController.java new file mode 100644 index 0000000..a9afd17 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/TestController.java @@ -0,0 +1,47 @@ +package com.fuyuanshen.app.controller.device; + +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessBatcAnnotation; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.web.service.device.DeviceBJQBizService; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * BJQ6170设备控制类 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/test") +public class TestController extends BaseController { + + private final DeviceBJQBizService appDeviceService; + + /** + * 上传设备logo图片 + */ + @PostMapping("/uploadLogo") + @FunctionAccessAnnotation("uploadLogo") + public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { + + MultipartFile file = bo.getFile(); + if(file.getSize()>1024*1024*2){ + return R.warn("图片不能大于2M"); + } + appDeviceService.uploadDeviceLogo2(bo); + + return R.ok(); + } + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java index 26db3c1..1841dad 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java @@ -14,4 +14,5 @@ public class AppDeviceLogoUploadDto { */ private MultipartFile file; + private Integer chunkSize; } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java index d42d522..e053630 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java @@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; /** - * BJQ6170设备控制类 + * web后台:设备控制类 */ @Validated @RequiredArgsConstructor diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java index 13b3471..76e3935 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java @@ -1,9 +1,22 @@ package com.fuyuanshen.web.controller.device; +import com.fuyuanshen.app.domain.dto.APPReNameDTO; +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; +import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; +import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; +import com.fuyuanshen.web.service.device.DeviceBizService; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.Date; @@ -12,199 +25,74 @@ import java.util.List; import java.util.Map; /** - * @author: 默苍璃 - * @date: 2025-08-0810:40 + * web后台:设备控制中心 */ @Slf4j -@Tag(name = "web后台:设备控制中心", description = "web后台:设备控制中心") @RestController @RequiredArgsConstructor @RequestMapping("/api/device/controlCenter") -public class DeviceControlCenterController { +public class DeviceControlCenterController extends BaseController { + private final DeviceBizService appDeviceService; /** - * 获取设备基本信息 - * @param deviceId 设备ID - * @return 设备基本信息 + * 查询设备列表 */ - @GetMapping("/info/{deviceId}") - public ResponseEntity> getDeviceInfo(@PathVariable String deviceId) { - // 实际应用中这里会从数据库查询设备信息 - Map deviceInfo = new HashMap<>(); - deviceInfo.put("deviceName", "6170零零一"); - deviceInfo.put("deviceModel", "BJQ6170"); - deviceInfo.put("deviceId", deviceId); - deviceInfo.put("status", "在线"); - deviceInfo.put("batteryLevel", 85); - - return ResponseEntity.ok(deviceInfo); + @GetMapping("/list") + public TableDataInfo list(DeviceQueryCriteria bo, PageQuery pageQuery) { + return appDeviceService.queryWebDeviceList(bo, pageQuery); } /** - * 设置灯光模式 - * @param lightModeRequest 灯光模式请求 - * @return 操作结果 + * 绑定设备 */ - @PostMapping("/light-mode") - public ResponseEntity> setLightMode(@RequestBody LightModeRequest lightModeRequest) { - // 实际应用中这里会控制设备灯光 - Map response = new HashMap<>(); - response.put("code", 200); - // response.put("message", "灯光模式已设置为: " + lightModeRequest.getMode()); - // response.put("deviceId", lightModeRequest.getDeviceId()); - // response.put("mode", lightModeRequest.getMode()); + @PostMapping("/bind") + public R bind(@RequestBody AppDeviceBo bo) { + return toAjax(appDeviceService.bindDevice(bo)); + } - return ResponseEntity.ok(response); + + /** + * 解绑设备 + */ + @DeleteMapping("/unBind") + public R unBind(Long id) { + return toAjax(appDeviceService.unBindDevice(id)); } /** - * 更新人员信息 - * @param personInfo 人员信息 - * @return 操作结果 + * 查询设备类型列表 */ - @PostMapping("/person-info") - public ResponseEntity> updatePersonInfo(@RequestBody PersonInfo personInfo) { - // 实际应用中这里会更新数据库 - Map response = new HashMap<>(); - response.put("code", 200); - response.put("message", "人员信息已更新"); - // response.put("unit", personInfo.getUnit()); - // response.put("position", personInfo.getPosition()); - - return ResponseEntity.ok(response); + @GetMapping(value = "/typeList") + public R> getTypeList() { + List typeList = appDeviceService.getTypeList(); + return R.ok(typeList); } /** - * 管理开机画面内容 - * @param bootScreenRequest 开机画面请求 - * @return 操作结果 + * 重命名设备 + * + * @param reNameDTO + * @return */ - @PostMapping("/boot-screen") - public ResponseEntity> manageBootScreen(@RequestBody BootScreenRequest bootScreenRequest) { - // 实际应用中这里会更新设备开机画面 - Map response = new HashMap<>(); - response.put("code", 200); - response.put("message", "开机画面内容已更新"); - // response.put("deviceId", bootScreenRequest.getDeviceId()); - // response.put("screens", bootScreenRequest.getScreens()); + @PostMapping(value = "/reName") + public R reName(@Validated @RequestBody APPReNameDTO reNameDTO) { + appDeviceService.reName(reNameDTO); + return R.ok("重命名成功!!!"); + } - return ResponseEntity.ok(response); + + @GetMapping("/realTimeStatus") + public R> getRealTimeStatus(AppRealTimeStatusDto statusDto) { + Map status = appDeviceService.getRealTimeStatus(statusDto); + return R.ok(status); } /** - * 设置灯光亮度 - * @param brightnessRequest 亮度请求 - * @return 操作结果 + * 根据mac查询设备信息 */ - @PostMapping("/brightness") - public ResponseEntity> setBrightness(@RequestBody BrightnessRequest brightnessRequest) { - // 实际应用中这里会控制设备亮度 - Map response = new HashMap<>(); - response.put("code", 200); - // response.put("message", "灯光亮度已设置为: " + brightnessRequest.getBrightness() + "%"); - // response.put("deviceId", brightnessRequest.getDeviceId()); - // response.put("brightness", brightnessRequest.getBrightness()); - // response.put("forceAlarm", brightnessRequest.isForceAlarm()); - - return ResponseEntity.ok(response); - } - - /** - * 获取设备位置信息 - * @param deviceId 设备ID - * @return 位置信息 - */ - @GetMapping("/location/{deviceId}") - public ResponseEntity> getLocation(@PathVariable String deviceId) { - // 实际应用中这里会从设备获取实时位置 - Map locationInfo = new HashMap<>(); - locationInfo.put("deviceId", deviceId); - locationInfo.put("longitude", "114°7'E"); - locationInfo.put("latitude", "30'28'N"); - locationInfo.put("address", "湖北省武汉市洪山区光谷大道国际企业中心"); - locationInfo.put("timestamp", new Date()); - - return ResponseEntity.ok(locationInfo); - } - - /** - * 发送紧急消息 - * @param messageRequest 消息请求 - * @return 操作结果 - */ - @PostMapping("/send-message") - public ResponseEntity> sendMessage(@RequestBody MessageRequest messageRequest) { - // 实际应用中这里会向设备发送消息 - Map response = new HashMap<>(); - response.put("code", 200); - response.put("message", "消息已发送"); - // response.put("deviceId", messageRequest.getDeviceId()); - // response.put("content", messageRequest.getContent()); - response.put("timestamp", new Date()); - - return ResponseEntity.ok(response); - } - - /** - * 管理操作视频 - * @param videoRequest 视频请求 - * @return 操作结果 - */ - @PostMapping("/operation-video") - public ResponseEntity> manageOperationVideo(@RequestBody VideoRequest videoRequest) { - // 实际应用中这里会更新设备操作视频 - Map response = new HashMap<>(); - response.put("code", 200); - response.put("message", "操作视频已更新"); - // response.put("deviceId", videoRequest.getDeviceId()); - // response.put("videoUrl", videoRequest.getVideoUrl()); - - return ResponseEntity.ok(response); - } - - // 请求对象类定义 - public static class LightModeRequest { - private String deviceId; - private String mode; // 强光、弱光、爆闪、泛光、激光 - - // Getters and Setters - } - - public static class PersonInfo { - private String deviceId; - private String unit; // 单位 - private String position; // 职位 - - // Getters and Setters - } - - public static class BootScreenRequest { - private String deviceId; - private List screens; // 产品参数、操作说明等 - - // Getters and Setters - } - - public static class BrightnessRequest { - private String deviceId; - private int brightness; // 0-100 - private boolean forceAlarm; // 强制报警 - - // Getters and Setters - } - - public static class MessageRequest { - private String deviceId; - private String content; // 消息内容 - - // Getters and Setters - } - - public static class VideoRequest { - private String deviceId; - private String videoUrl; // 视频链接 - - // Getters and Setters + @GetMapping("/getDeviceInfoByDeviceMac") + public R getDeviceInfo(String deviceMac) { + return R.ok(appDeviceService.getDeviceInfo(deviceMac)); } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java index 71be510..4519b2e 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java @@ -36,7 +36,7 @@ import java.util.Map; public class WEBDeviceController extends BaseController { private final WEBDeviceService deviceService; - private final DeviceBizService appDeviceService; + /** @@ -53,66 +53,7 @@ public class WEBDeviceController extends BaseController { } - /** - * 查询设备列表 - */ - @GetMapping("/list") - public TableDataInfo list(DeviceQueryCriteria bo, PageQuery pageQuery) { - return appDeviceService.queryAppDeviceList(bo, pageQuery); - } - /** - * 绑定设备 - */ - @PostMapping("/bind") - public R bind(@RequestBody AppDeviceBo bo) { - return toAjax(appDeviceService.bindDevice(bo)); - } - - - /** - * 解绑设备 - */ - @DeleteMapping("/unBind") - public R unBind(Long id) { - return toAjax(appDeviceService.unBindDevice(id)); - } - - /** - * 查询设备类型列表 - */ - @GetMapping(value = "/typeList") - public R> getTypeList() { - List typeList = appDeviceService.getTypeList(); - return R.ok(typeList); - } - - /** - * 重命名设备 - * - * @param reNameDTO - * @return - */ - @PostMapping(value = "/reName") - public R reName(@Validated @RequestBody APPReNameDTO reNameDTO) { - appDeviceService.reName(reNameDTO); - return R.ok("重命名成功!!!"); - } - - - @GetMapping("/realTimeStatus") - public R> getRealTimeStatus(AppRealTimeStatusDto statusDto) { - Map status = appDeviceService.getRealTimeStatus(statusDto); - return R.ok(status); - } - - /** - * 根据mac查询设备信息 - */ - @GetMapping("/getDeviceInfoByDeviceMac") - public R getDeviceInfo(String deviceMac) { - return R.ok(appDeviceService.getDeviceInfo(deviceMac)); - } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java index 60c80d7..9ee8236 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java @@ -1,16 +1,19 @@ package com.fuyuanshen.web.service.device; +import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.fuyuanshen.app.domain.AppPersonnelInfo; +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; import com.fuyuanshen.app.domain.dto.DeviceInstructDto; import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; +import com.fuyuanshen.app.mapper.AppPersonnelInfoRecordsMapper; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.exception.ServiceException; import com.fuyuanshen.common.core.utils.*; @@ -50,6 +53,7 @@ public class DeviceBJQBizService { private final DeviceMapper deviceMapper; private final AppPersonnelInfoMapper appPersonnelInfoMapper; + private final AppPersonnelInfoRecordsMapper appPersonnelInfoRecordsMapper; private final DeviceTypeMapper deviceTypeMapper; private final MqttGateway mqttGateway; private final DeviceLogMapper deviceLogMapper; @@ -242,11 +246,18 @@ public class DeviceBJQBizService { map.put("instruct", intData); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), 1, JSON.toJSONString(map)); log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), bo); - - recordDeviceLog(deviceId, deviceObj.getDeviceName(), "人员信息登记", JSON.toJSONString(bo), AppLoginHelper.getUserId()); + String logContent = "单位:"+bo.getUnitName()+",职位:"+bo.getPosition()+",姓名:"+bo.getName()+",ID:"+bo.getCode(); + recordDeviceLog(deviceId, deviceObj.getDeviceName(), "人员信息登记", logContent, AppLoginHelper.getUserId()); if (ObjectUtils.length(appPersonnelInfoVos) == 0) { AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); - return appPersonnelInfoMapper.insertOrUpdate(appPersonnelInfo); + appPersonnelInfoMapper.insertOrUpdate(appPersonnelInfo); + + AppPersonnelInfoRecords appPersonnelInfoRecords = new AppPersonnelInfoRecords(); + BeanUtil.copyProperties(appPersonnelInfo, appPersonnelInfoRecords); + appPersonnelInfoRecords.setId(null); + appPersonnelInfoRecords.setPersonnelId(appPersonnelInfo.getId()); + + appPersonnelInfoRecordsMapper.insert(appPersonnelInfoRecords); } else { UpdateWrapper uw = new UpdateWrapper<>(); uw.eq("device_id", deviceId) @@ -254,10 +265,52 @@ public class DeviceBJQBizService { .set("position", bo.getPosition()) .set("unit_name", bo.getUnitName()) .set("code", bo.getCode()); - return appPersonnelInfoMapper.update(null, uw) > 0; + appPersonnelInfoMapper.update(null, uw); + + AppPersonnelInfoVo personnelInfoVo = appPersonnelInfoVos.get(0); + AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); + AppPersonnelInfoRecords appPersonnelInfoRecords = new AppPersonnelInfoRecords(); + BeanUtil.copyProperties(appPersonnelInfo, appPersonnelInfoRecords); + appPersonnelInfoRecords.setId(null); + appPersonnelInfoRecords.setPersonnelId(personnelInfoVo.getId()); + appPersonnelInfoRecordsMapper.insert(appPersonnelInfoRecords); + } + return true; + } + public void uploadDeviceLogo2(AppDeviceLogoUploadDto bo) { + try { + Device device = deviceMapper.selectById(bo.getDeviceId()); + if (device == null) { + throw new ServiceException("设备不存在"); + } + MultipartFile file = bo.getFile(); + + byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600); + + log.info("长度:" + largeData.length); + // 在获取 largeData 后,将其与前缀合并 + byte[] prefix = new byte[]{0x50, 0x49, 0x43, 0x54, 0x55, 0x52, 0x45}; // "PICTURE" + byte[] combinedData = new byte[prefix.length + largeData.length]; + System.arraycopy(prefix, 0, combinedData, 0, prefix.length); + System.arraycopy(largeData, 0, combinedData, prefix.length, largeData.length); + + // 将 combinedData 转换为十六进制表示 + String[] hexArray = new String[combinedData.length]; + for (int i = 0; i < combinedData.length; i++) { + hexArray[i] = String.format("0x%02X", combinedData[i]); + } +// Map map = new HashMap<>(); +// map.put("instruct", combinedData); + String[] specificChunk = ImageToCArrayConverter.getChunk2(hexArray, 0, bo.getChunkSize()); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , Arrays.toString(specificChunk)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),Arrays.toString(specificChunk)); + + recordDeviceLog(device.getId(), device.getDeviceName(), "上传开机画面", "上传开机画面", AppLoginHelper.getUserId()); + } catch (Exception e){ + e.printStackTrace(); + throw new ServiceException("发送指令失败"); } } - public void uploadDeviceLogo(AppDeviceLogoUploadDto bo) { try { Device device = deviceMapper.selectById(bo.getDeviceId()); diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java index 3c0d9be..9011446 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java @@ -28,6 +28,7 @@ import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import com.fuyuanshen.equipment.enums.BindingStatusEnum; import com.fuyuanshen.equipment.enums.CommunicationModeEnum; import com.fuyuanshen.equipment.mapper.DeviceLogMapper; @@ -123,6 +124,47 @@ public class DeviceBizService { return TableDataInfo.build(result); } + public TableDataInfo queryWebDeviceList(DeviceQueryCriteria bo, PageQuery pageQuery) { + Page result = deviceMapper.queryWebDeviceList(pageQuery.build(), bo); + List records = result.getRecords(); + if(records != null && !records.isEmpty()){ + records.forEach(item -> { + if(item.getCommunicationMode()!=null && item.getCommunicationMode() == 0){ + + //设备在线状态 + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); + if(StringUtils.isNotBlank(onlineStatus)){ + + item.setOnlineStatus(1); + }else{ + item.setOnlineStatus(0); + } + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX+ item.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX); + // 获取电量 + if(StringUtils.isNotBlank(deviceStatus)){ + JSONObject jsonObject = JSONObject.parseObject(deviceStatus); + item.setBattery(jsonObject.getString("batteryPercentage")); + }else{ + item.setBattery("0"); + } + + String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_LOCATION_KEY_PREFIX); + if(StringUtils.isNotBlank(location)){ + JSONObject jsonObject = JSONObject.parseObject(location); + item.setLatitude(jsonObject.getString("latitude")); + item.setLongitude(jsonObject.getString("longitude")); + } + + String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_ALARM_KEY_PREFIX); + if(StringUtils.isNotBlank(alarmStatus)){ + item.setAlarmStatus(alarmStatus); + } + } + }); + } + return TableDataInfo.build(result); + } + public int bindDevice(AppDeviceBo bo) { Integer mode = bo.getCommunicationMode(); Long userId = AppLoginHelper.getUserId(); diff --git a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/ImageToCArrayConverter.java b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/ImageToCArrayConverter.java index 8823ad0..eedfead 100644 --- a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/ImageToCArrayConverter.java +++ b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/ImageToCArrayConverter.java @@ -88,6 +88,24 @@ public class ImageToCArrayConverter { return chunk; } + public static String[] getChunk2(String[] data, int chunkIndex, int chunkSize) { + if (data == null || chunkSize <= 0 || chunkIndex < 0) { + return new String[0]; + } + + int start = chunkIndex * chunkSize; + if (start >= data.length) { + return new String[0]; // 索引超出范围 + } + + int end = Math.min(start + chunkSize, data.length); + int length = end - start; + + String[] chunk = new String[length]; + System.arraycopy(data, start, chunk, 0, length); + return chunk; + } + public static void buildArr(int[] data,List intData){ for (int datum : data) { intData.add(datum); diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppPersonnelInfoRecordsController.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppPersonnelInfoRecordsController.java new file mode 100644 index 0000000..b7f9dd6 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppPersonnelInfoRecordsController.java @@ -0,0 +1,105 @@ +package com.fuyuanshen.app.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 com.fuyuanshen.common.idempotent.annotation.RepeatSubmit; +import com.fuyuanshen.common.log.annotation.Log; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.core.validate.EditGroup; +import com.fuyuanshen.common.log.enums.BusinessType; +import com.fuyuanshen.common.excel.utils.ExcelUtil; +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoRecordsVo; +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoRecordsBo; +import com.fuyuanshen.app.service.IAppPersonnelInfoRecordsService; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; + +/** + * 人员信息登记记录 + * + * @author CYT + * @date 2025-08-22 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/app/personnelInfoRecords") +public class AppPersonnelInfoRecordsController extends BaseController { + + private final IAppPersonnelInfoRecordsService appPersonnelInfoRecordsService; + + /** + * 查询人员信息登记记录列表 + */ + @SaCheckPermission("app:personnelInfoRecords:list") + @GetMapping("/list") + public TableDataInfo list(AppPersonnelInfoRecordsBo bo, PageQuery pageQuery) { + return appPersonnelInfoRecordsService.queryPageList(bo, pageQuery); + } + + /** + * 导出人员信息登记记录列表 + */ + @SaCheckPermission("app:personnelInfoRecords:export") + @Log(title = "人员信息登记记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(AppPersonnelInfoRecordsBo bo, HttpServletResponse response) { + List list = appPersonnelInfoRecordsService.queryList(bo); + ExcelUtil.exportExcel(list, "人员信息登记记录", AppPersonnelInfoRecordsVo.class, response); + } + + /** + * 获取人员信息登记记录详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("app:personnelInfoRecords:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(appPersonnelInfoRecordsService.queryById(id)); + } + + /** + * 新增人员信息登记记录 + */ + @SaCheckPermission("app:personnelInfoRecords:add") + @Log(title = "人员信息登记记录", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoRecordsBo bo) { + return toAjax(appPersonnelInfoRecordsService.insertByBo(bo)); + } + + /** + * 修改人员信息登记记录 + */ + @SaCheckPermission("app:personnelInfoRecords:edit") + @Log(title = "人员信息登记记录", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody AppPersonnelInfoRecordsBo bo) { + return toAjax(appPersonnelInfoRecordsService.updateByBo(bo)); + } + + /** + * 删除人员信息登记记录 + * + * @param ids 主键串 + */ + @SaCheckPermission("app:personnelInfoRecords:remove") + @Log(title = "人员信息登记记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(appPersonnelInfoRecordsService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppPersonnelInfoRecords.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppPersonnelInfoRecords.java new file mode 100644 index 0000000..848bd37 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppPersonnelInfoRecords.java @@ -0,0 +1,66 @@ +package com.fuyuanshen.app.domain; + +import com.fuyuanshen.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 人员信息登记记录对象 app_personnel_info_records + * + * @author CYT + * @date 2025-08-22 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("app_personnel_info_records") +public class AppPersonnelInfoRecords extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "id") + private Long id; + + /** + * 设备id + */ + private Long deviceId; + + /** + * 主键 + */ + private Long personnelId; + + /** + * 人员姓名 + */ + private String name; + + /** + * 职位 + */ + private String position; + + /** + * 单位名称 + */ + private String unitName; + + /** + * ID号 + */ + private String code; + + /** + * 发送信息 + */ + private String sendMsg; + + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoRecordsBo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoRecordsBo.java new file mode 100644 index 0000000..70e2426 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoRecordsBo.java @@ -0,0 +1,67 @@ +package com.fuyuanshen.app.domain.bo; + +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.core.validate.EditGroup; +import com.fuyuanshen.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 人员信息登记记录业务对象 app_personnel_info_records + * + * @author CYT + * @date 2025-08-22 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = AppPersonnelInfoRecords.class, reverseConvertGenerate = false) +public class AppPersonnelInfoRecordsBo extends BaseEntity { + + /** + * 主键 + */ + @NotNull(message = "主键不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 设备id + */ + @NotNull(message = "设备id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long deviceId; + + /** + * 主键 + */ + @NotNull(message = "主键不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long personnelId; + + /** + * 人员姓名 + */ + private String name; + + /** + * 职位 + */ + private String position; + + /** + * 单位名称 + */ + private String unitName; + + /** + * ID号 + */ + private String code; + + /** + * 发送信息 + */ + private String sendMsg; + + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoRecordsVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoRecordsVo.java new file mode 100644 index 0000000..1d05a0c --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoRecordsVo.java @@ -0,0 +1,80 @@ +package com.fuyuanshen.app.domain.vo; + +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.fuyuanshen.common.excel.annotation.ExcelDictFormat; +import com.fuyuanshen.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; + + + +/** + * 人员信息登记记录视图对象 app_personnel_info_records + * + * @author CYT + * @date 2025-08-22 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = AppPersonnelInfoRecords.class) +public class AppPersonnelInfoRecordsVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long id; + + /** + * 设备id + */ + @ExcelProperty(value = "设备id") + private Long deviceId; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long personnelId; + + /** + * 人员姓名 + */ + @ExcelProperty(value = "人员姓名") + private String name; + + /** + * 职位 + */ + @ExcelProperty(value = "职位") + private String position; + + /** + * 单位名称 + */ + @ExcelProperty(value = "单位名称") + private String unitName; + + /** + * ID号 + */ + @ExcelProperty(value = "ID号") + private String code; + + /** + * 发送信息 + */ + @ExcelProperty(value = "发送信息") + private String sendMsg; + + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppPersonnelInfoRecordsMapper.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppPersonnelInfoRecordsMapper.java new file mode 100644 index 0000000..bffca13 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppPersonnelInfoRecordsMapper.java @@ -0,0 +1,15 @@ +package com.fuyuanshen.app.mapper; + +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoRecordsVo; +import com.fuyuanshen.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 人员信息登记记录Mapper接口 + * + * @author CYT + * @date 2025-08-22 + */ +public interface AppPersonnelInfoRecordsMapper extends BaseMapperPlus { + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/IAppPersonnelInfoRecordsService.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/IAppPersonnelInfoRecordsService.java new file mode 100644 index 0000000..a845a85 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/IAppPersonnelInfoRecordsService.java @@ -0,0 +1,68 @@ +package com.fuyuanshen.app.service; + +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoRecordsVo; +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoRecordsBo; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 人员信息登记记录Service接口 + * + * @author CYT + * @date 2025-08-22 + */ +public interface IAppPersonnelInfoRecordsService { + + /** + * 查询人员信息登记记录 + * + * @param id 主键 + * @return 人员信息登记记录 + */ + AppPersonnelInfoRecordsVo queryById(Long id); + + /** + * 分页查询人员信息登记记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 人员信息登记记录分页列表 + */ + TableDataInfo queryPageList(AppPersonnelInfoRecordsBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的人员信息登记记录列表 + * + * @param bo 查询条件 + * @return 人员信息登记记录列表 + */ + List queryList(AppPersonnelInfoRecordsBo bo); + + /** + * 新增人员信息登记记录 + * + * @param bo 人员信息登记记录 + * @return 是否新增成功 + */ + Boolean insertByBo(AppPersonnelInfoRecordsBo bo); + + /** + * 修改人员信息登记记录 + * + * @param bo 人员信息登记记录 + * @return 是否修改成功 + */ + Boolean updateByBo(AppPersonnelInfoRecordsBo bo); + + /** + * 校验并批量删除人员信息登记记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/impl/AppPersonnelInfoRecordsServiceImpl.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/impl/AppPersonnelInfoRecordsServiceImpl.java new file mode 100644 index 0000000..b330ded --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/impl/AppPersonnelInfoRecordsServiceImpl.java @@ -0,0 +1,138 @@ +package com.fuyuanshen.app.service.impl; + +import com.fuyuanshen.common.core.utils.MapstructUtils; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import com.fuyuanshen.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 com.fuyuanshen.app.domain.bo.AppPersonnelInfoRecordsBo; +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoRecordsVo; +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; +import com.fuyuanshen.app.mapper.AppPersonnelInfoRecordsMapper; +import com.fuyuanshen.app.service.IAppPersonnelInfoRecordsService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 人员信息登记记录Service业务层处理 + * + * @author CYT + * @date 2025-08-22 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class AppPersonnelInfoRecordsServiceImpl implements IAppPersonnelInfoRecordsService { + + private final AppPersonnelInfoRecordsMapper baseMapper; + + /** + * 查询人员信息登记记录 + * + * @param id 主键 + * @return 人员信息登记记录 + */ + @Override + public AppPersonnelInfoRecordsVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询人员信息登记记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 人员信息登记记录分页列表 + */ + @Override + public TableDataInfo queryPageList(AppPersonnelInfoRecordsBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的人员信息登记记录列表 + * + * @param bo 查询条件 + * @return 人员信息登记记录列表 + */ + @Override + public List queryList(AppPersonnelInfoRecordsBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(AppPersonnelInfoRecordsBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(AppPersonnelInfoRecords::getId); + lqw.eq(bo.getDeviceId() != null, AppPersonnelInfoRecords::getDeviceId, bo.getDeviceId()); + lqw.eq(bo.getPersonnelId() != null, AppPersonnelInfoRecords::getPersonnelId, bo.getPersonnelId()); + lqw.like(StringUtils.isNotBlank(bo.getName()), AppPersonnelInfoRecords::getName, bo.getName()); + lqw.eq(StringUtils.isNotBlank(bo.getPosition()), AppPersonnelInfoRecords::getPosition, bo.getPosition()); + lqw.like(StringUtils.isNotBlank(bo.getUnitName()), AppPersonnelInfoRecords::getUnitName, bo.getUnitName()); + lqw.eq(StringUtils.isNotBlank(bo.getCode()), AppPersonnelInfoRecords::getCode, bo.getCode()); + lqw.eq(StringUtils.isNotBlank(bo.getSendMsg()), AppPersonnelInfoRecords::getSendMsg, bo.getSendMsg()); + return lqw; + } + + /** + * 新增人员信息登记记录 + * + * @param bo 人员信息登记记录 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(AppPersonnelInfoRecordsBo bo) { + AppPersonnelInfoRecords add = MapstructUtils.convert(bo, AppPersonnelInfoRecords.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改人员信息登记记录 + * + * @param bo 人员信息登记记录 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(AppPersonnelInfoRecordsBo bo) { + AppPersonnelInfoRecords update = MapstructUtils.convert(bo, AppPersonnelInfoRecords.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(AppPersonnelInfoRecords entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除人员信息登记记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/fys-modules/fys-app/src/main/resources/mapper/app/AppPersonnelInfoRecordsMapper.xml b/fys-modules/fys-app/src/main/resources/mapper/app/AppPersonnelInfoRecordsMapper.xml new file mode 100644 index 0000000..28b50d9 --- /dev/null +++ b/fys-modules/fys-app/src/main/resources/mapper/app/AppPersonnelInfoRecordsMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java index d8a9505..caafe10 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java @@ -66,8 +66,14 @@ public class DeviceQueryCriteria extends BaseEntity { /* app绑定用户id */ private Long bindingUserId; + /** + * 使用人员 + */ + private String personnelBy; /* 是否为管理员 */ private Boolean isAdmin = false; + + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java new file mode 100644 index 0000000..bcbc71a --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java @@ -0,0 +1,95 @@ +package com.fuyuanshen.equipment.domain.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +public class WebDeviceVo implements Serializable { + + private Long id; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 设备IMEI + */ + private String deviceImei; + + /** + * 设备MAC + */ + private String deviceMac; + + /** + * 通讯方式 0:4G;1:蓝牙 + */ + private Integer communicationMode; + + /** + * 设备图片 + */ + private String devicePic; + + /** + * 设备类型 + */ + private String typeName; + + /** + * 蓝牙名称 + */ + private String bluetoothName; + + /** + * 使用人员 + */ + private String personnelBy; + + /** + * 设备状态 + * 0 失效 + * 1 正常 + */ + private Integer deviceStatus; + + /** + * 绑定时间 + */ + private Date bindingTime; + + /** + * 在线状态(0离线,1在线) + */ + private Integer onlineStatus; + + /** + * 电量 百分比 + */ + private String battery; + + /** + * 纬度 + */ + private String latitude; + + /** + * 经度 + */ + private String longitude; + + /** + * 告警状态(0解除告警,1告警) + */ + private String alarmStatus; + + /** + * 设备详情页面 + */ + private String detailPageUrl; + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java index 96bbfce..3989653 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -68,4 +69,6 @@ public interface DeviceMapper extends BaseMapper { List findByOriginalDeviceId(Long originalDeviceId); AppDeviceVo getDeviceInfo(@Param("deviceMac") String deviceMac); + + Page queryWebDeviceList(Page build, DeviceQueryCriteria bo); } diff --git a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml index 3439362..51f0a63 100644 --- a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml +++ b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml @@ -232,5 +232,46 @@ inner join device_type dt on d.device_type = dt.id where d.device_mac = #{deviceMac} + \ No newline at end of file From 1246ac5cf70e51fbaf8ed332d4bcedf83bf5dc09 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Sat, 23 Aug 2025 17:33:35 +0800 Subject: [PATCH 3/6] @Schema(title = "ID", hidden = true) --- .../fuyuanshen/equipment/domain/Device.java | 46 +++++++++---------- .../equipment/domain/DeviceType.java | 22 ++++----- .../equipment/domain/bo/DeviceGroupBo.java | 10 ++-- .../equipment/domain/form/DeviceForm.java | 2 +- .../equipment/domain/form/DeviceTypeForm.java | 14 +++--- .../domain/query/DeviceTypeQueryCriteria.java | 14 +++--- .../equipment/domain/vo/CustomerVo.java | 4 +- 7 files changed, 56 insertions(+), 56 deletions(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java index 902874c..d166aac 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java @@ -22,10 +22,10 @@ public class Device extends TenantEntity { * id */ @TableId(value = "id", type = IdType.AUTO) - @Schema(name = "ID") + @Schema(title = "ID") private Long id; - @Schema(name = "设备记录ID") + @Schema(title = "设备记录ID") @TableField(exist = false) private Long assignId; @@ -33,76 +33,76 @@ public class Device extends TenantEntity { * 设备分组 * group_id */ - @Schema(name = "设备分组") + @Schema(title = "设备分组") private Long groupId; /** * device_type */ - @Schema(name = "设备类型") + @Schema(title = "设备类型") private Long deviceType; - @Schema(name = "设备类型名称") + @Schema(title = "设备类型名称") private String typeName; - @Schema(name = "客户号") + @Schema(title = "客户号") private Long customerId; - @Schema(name = "所属客户") + @Schema(title = "所属客户") private String customerName; /** * 当前所有者 * current_owner_id */ - @Schema(name = "当前所有者") + @Schema(title = "当前所有者") private Long currentOwnerId; /** * 原始所有者(创建者) * original_owner_id */ - @Schema(name = "原始所有者(创建者)") + @Schema(title = "原始所有者(创建者)") private Long originalOwnerId; /** * 原始设备 */ - @Schema(name = "原始设备") + @Schema(title = "原始设备") private Long originalDeviceId; - @Schema(name = "设备编号") + @Schema(title = "设备编号") private String deviceNo; - @Schema(name = "设备名称") + @Schema(title = "设备名称") private String deviceName; - @Schema(name = "设备图片") + @Schema(title = "设备图片") private String devicePic; - @Schema(name = "设备MAC") + @Schema(title = "设备MAC") private String deviceMac; - @Schema(name = "蓝牙名称") + @Schema(title = "蓝牙名称") private String bluetoothName; /** * 设备IMEI * device_imei */ - @Schema(name = "设备IMEI") + @Schema(title = "设备IMEI") private String deviceImei; - @Schema(name = "设备SN") + @Schema(title = "设备SN") private String deviceSn; - @Schema(name = "经度") + @Schema(title = "经度") private String longitude; - @Schema(name = "纬度") + @Schema(title = "纬度") private String latitude; - @Schema(name = "备注") + @Schema(title = "备注") private String remark; /** @@ -110,7 +110,7 @@ public class Device extends TenantEntity { * 0 失效 * 1 正常 */ - @Schema(name = "设备状态") + @Schema(title = "设备状态") private Integer deviceStatus; /** @@ -118,7 +118,7 @@ public class Device extends TenantEntity { * 0 未绑定 * 1 已绑定 */ - @Schema(name = "绑定状态") + @Schema(title = "绑定状态") private Integer bindingStatus; /** @@ -151,7 +151,7 @@ public class Device extends TenantEntity { * 出厂日期 * production_date */ - @Schema(name = "出厂日期") + @Schema(title = "出厂日期") private Date productionDate; } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java index 32bd32e..fe1db44 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java @@ -18,42 +18,42 @@ import lombok.Data; public class DeviceType extends TenantEntity { @TableId(value = "id", type = IdType.AUTO) - @Schema(name = "ID", hidden = true) + @Schema(title = "ID", hidden = true) private Long id; - @Schema(name = "客户号") + @Schema(title = "客户号") private Long customerId; - @Schema(name = "创建该类型的客户") + @Schema(title = "创建该类型的客户") private Long ownerCustomerId; /** * 原始所有者(创建者) * original_owner_id */ - @Schema(name = "原始所有者(创建者)") + @Schema(title = "原始所有者(创建者)") private Long originalOwnerId; /** * 原始设备 */ - @Schema(name = "原始设备类型") + @Schema(title = "原始设备类型") private Long originalDeviceId; @NotBlank(message = "设备类型名称不能为空") - @Schema(name = "类型名称", required = true) + @Schema(title = "类型名称", required = true) private String typeName; - @Schema(name = "是否支持蓝牙") + @Schema(title = "是否支持蓝牙") private Boolean isSupportBle; - @Schema(name = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗") + @Schema(title = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗") private String locateMode; - @Schema(name = "联网方式", example = "0:无;1:4G;2:WIFI") + @Schema(title = "联网方式", example = "0:无;1:4G;2:WIFI") private String networkWay; - @Schema(name = "通讯方式", example = "0:4G;1:蓝牙") + @Schema(title = "通讯方式", example = "0:4G;1:蓝牙") private String communicationMode; /** @@ -68,7 +68,7 @@ public class DeviceType extends TenantEntity { /** * 型号字典用于APP页面跳转 */ - @Schema(name = "型号字典用于APP页面跳转") + @Schema(title = "型号字典用于APP页面跳转") private String modelDictionary; diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java index 064c5aa..e0ac783 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java @@ -30,21 +30,21 @@ public class DeviceGroupBo extends BaseEntity { /** * 分组名称 */ - @Schema(name = "分组名称") + @Schema(title = "分组名称") @NotBlank(message = "分组名称不能为空", groups = { AddGroup.class, EditGroup.class }) private String groupName; /** * 状态:0-禁用,1-正常 */ - @Schema(name = "状态:0-禁用,1-正常") + @Schema(title = "状态:0-禁用,1-正常") // @NotNull(message = "状态:0-禁用,1-正常不能为空", groups = { AddGroup.class, EditGroup.class }) private Long status; /** * 父分组ID */ - @Schema(name = "父分组ID") + @Schema(title = "父分组ID") private Long parentId; /** @@ -59,10 +59,10 @@ public class DeviceGroupBo extends BaseEntity { private Long isDeleted; - @Schema(name = "页码", example = "1") + @Schema(title = "页码", example = "1") private Integer pageNum = 1; - @Schema(name = "每页数据量", example = "10") + @Schema(title = "每页数据量", example = "10") private Integer pageSize = 10; } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java index 2de4ca3..a51e13b 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java @@ -40,7 +40,7 @@ public class DeviceForm { @Schema(title = "设备MAC") private String deviceMac; - @Schema(name = "蓝牙名称") + @Schema(title = "蓝牙名称") private String bluetoothName; diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java index 7fc8a10..d5e1df7 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java @@ -11,28 +11,28 @@ import lombok.Data; @Data public class DeviceTypeForm { - @Schema(name = "ID", hidden = true) + @Schema(title = "ID", hidden = true) private Long id; - @Schema(name = "类型名称", required = true) + @Schema(title = "类型名称", required = true) private String typeName; - @Schema(name = "是否支持蓝牙") + @Schema(title = "是否支持蓝牙") private Boolean isSupportBle; - @Schema(name = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗") + @Schema(title = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗") private String locateMode; - @Schema(name = "联网方式", example = "0:无;1:4G;2:WIFI") + @Schema(title = "联网方式", example = "0:无;1:4G;2:WIFI") private String networkWay; - @Schema(name = "通讯方式", example = "0:4G;1:蓝牙") + @Schema(title = "通讯方式", example = "0:4G;1:蓝牙") private String communicationMode; /** * 型号字典用于APP页面跳转 */ - @Schema(name = "型号字典用于APP页面跳转") + @Schema(title = "型号字典用于APP页面跳转") private String modelDictionary; } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java index 2beea69..5080edc 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java @@ -15,25 +15,25 @@ import java.util.Set; @Data public class DeviceTypeQueryCriteria extends BaseEntity implements Serializable { - @Schema(name = "设备类型id") + @Schema(title = "设备类型id") private Long deviceTypeId; - @Schema(name = "型号名称") + @Schema(title = "型号名称") private String typeName; - @Schema(name = "所属客户") + @Schema(title = "所属客户") private Set customerIds; - @Schema(name = "所属客户") + @Schema(title = "所属客户") private Long customerId; - @Schema(name = "com.fuyuanshen") + @Schema(title = "com.fuyuanshen") private Long tenantId; - @Schema(name = "页码", example = "1") + @Schema(title = "页码", example = "1") private Integer pageNum = 1; - @Schema(name = "每页数据量", example = "10") + @Schema(title = "每页数据量", example = "10") private Integer pageSize = 10; diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/CustomerVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/CustomerVo.java index b2ff048..3debd67 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/CustomerVo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/CustomerVo.java @@ -16,11 +16,11 @@ import java.util.List; @Validated public class CustomerVo { - @Schema(name = "客户ID") + @Schema(title = "客户ID") @NotNull(message = "客户ID不能为空") private Long customerId; - @Schema(name = "设备ID") + @Schema(title = "设备ID") @NotNull(message = "设备ID不能为空") private List deviceIds; From d962c6ead51d913c1223cba1f813d1b748893eee Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Mon, 25 Aug 2025 10:19:57 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/WEBDeviceController.java | 16 +++++++++- .../web/service/WEBDeviceService.java | 9 ++++++ .../service/impl/WEBDeviceServiceImpl.java | 29 +++++++++++++++++-- .../equipment/domain/vo/WebDeviceVo.java | 5 ++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java index 4519b2e..700ff0d 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java @@ -8,9 +8,11 @@ import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import com.fuyuanshen.web.service.WEBDeviceService; import com.fuyuanshen.web.service.device.DeviceBizService; import io.swagger.v3.oas.annotations.Operation; @@ -38,7 +40,6 @@ public class WEBDeviceController extends BaseController { private final WEBDeviceService deviceService; - /** * @param id * @return @@ -53,6 +54,19 @@ public class WEBDeviceController extends BaseController { } + /** + * 设备详情 + * + * @param id + * @return + */ + @Operation(summary = "设备详情") + @GetMapping(value = "/detail/{id}") + public R getDevice(@PathVariable Long id) { + WebDeviceVo device = deviceService.getDevice(id); + return R.ok(device); + } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/WEBDeviceService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/WEBDeviceService.java index 0274717..fe84f3b 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/WEBDeviceService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/WEBDeviceService.java @@ -10,6 +10,7 @@ import com.fuyuanshen.equipment.domain.form.DeviceForm; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; import com.fuyuanshen.equipment.domain.vo.CustomerVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import java.io.IOException; import java.util.List; @@ -29,4 +30,12 @@ public interface WEBDeviceService extends IService { */ int webUnBindDevice(Long id, Long userId); + /** + * WEB端设备详情 + * + * @param id + * @return + */ + WebDeviceVo getDevice(Long id); + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java index 7e328b8..0d5097c 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java @@ -1,12 +1,17 @@ package com.fuyuanshen.web.service.impl; +import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fuyuanshen.app.domain.AppDeviceBindRecord; +import com.fuyuanshen.app.domain.AppDeviceShare; +import com.fuyuanshen.app.domain.vo.AppDeviceShareVo; import com.fuyuanshen.app.mapper.AppDeviceBindRecordMapper; +import com.fuyuanshen.app.mapper.AppDeviceShareMapper; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.DeviceAssignments; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import com.fuyuanshen.equipment.enums.BindingStatusEnum; import com.fuyuanshen.equipment.mapper.DeviceAssignmentsMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper; @@ -27,13 +32,12 @@ import org.springframework.transaction.annotation.Transactional; @RequiredArgsConstructor public class WEBDeviceServiceImpl extends ServiceImpl implements WEBDeviceService { - private final DeviceBizService appDeviceService; - private final DeviceAssignmentsMapper deviceAssignmentsMapper; private final AppDeviceBindRecordMapper appDeviceBindRecordMapper; private final DeviceMapper deviceMapper; + private final AppDeviceShareMapper appDeviceShareMapper; /** @@ -70,4 +74,25 @@ public class WEBDeviceServiceImpl extends ServiceImpl impl } + /** + * WEB端设备详情 + * + * @param id + * @return + */ + @Override + public WebDeviceVo getDevice(Long id) { + Device device = deviceMapper.selectById(id); + if (device != null) { + WebDeviceVo webDeviceVo = new WebDeviceVo(); + BeanUtil.copyProperties(device, webDeviceVo); + // 查询分享用户数 + Long count = appDeviceShareMapper.selectCount(new QueryWrapper().eq("device_id", id)); + webDeviceVo.setShareUsersNumber(Math.toIntExact(count)); + return webDeviceVo; + } + return null; + } + + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java index bcbc71a..94b20e8 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java @@ -92,4 +92,9 @@ public class WebDeviceVo implements Serializable { */ private String detailPageUrl; + /** + * 分享用户数量 + */ + private Integer shareUsersNumber; + } From 9b476e98ba7903c55f610db10332c3414e1ccc30 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Mon, 25 Aug 2025 11:40:59 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E5=9E=8B=E5=8F=B7=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E7=94=A8=E4=BA=8EPC=E9=A1=B5=E9=9D=A2=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fuyuanshen/equipment/domain/DeviceType.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java index fe1db44..d0ab5b0 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java @@ -67,9 +67,17 @@ public class DeviceType extends TenantEntity { /** * 型号字典用于APP页面跳转 + * app_model_dictionary */ @Schema(title = "型号字典用于APP页面跳转") - private String modelDictionary; + private String appModelDictionary; + + /** + * 型号字典用于PC页面跳转 + * pc_model_dictionary + */ + @Schema(title = "型号字典用于PC页面跳转") + private String pcModelDictionary; } From 74cefe9cc3bc538c92021de2f2e8adac97faebb0 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Mon, 25 Aug 2025 13:42:24 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fuyuanshen/web/controller/device/WEBDeviceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java index 700ff0d..86ec7ed 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java @@ -61,7 +61,7 @@ public class WEBDeviceController extends BaseController { * @return */ @Operation(summary = "设备详情") - @GetMapping(value = "/detail/{id}") + @GetMapping(value = "/pc/detail/{id}") public R getDevice(@PathVariable Long id) { WebDeviceVo device = deviceService.getDevice(id); return R.ok(device);