From e265dea0ec62d2866dd9dff5e5553701839344ac Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Fri, 7 Nov 2025 15:53:13 +0800 Subject: [PATCH] =?UTF-8?q?BJQ6075=20=E8=AE=BE=E5=A4=87=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bjq/AppDeviceBJQ6075Controller.java | 44 +- .../app/domain/dto/DeviceInstructDto.java | 8 +- .../device/DeviceBJQ6075BizService.java | 102 +++ .../impl/DeviceBJQ6075BizServiceImpl.java | 598 ++++++++++++++++++ .../app/domain/vo/AppDevice6075DetailVo.java | 120 ++++ .../app/domain/vo/AppPersonnelInfoVo.java | 1 - 6 files changed, 861 insertions(+), 12 deletions(-) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQ6075BizService.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/web/service/impl/DeviceBJQ6075BizServiceImpl.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDevice6075DetailVo.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/bjq/AppDeviceBJQ6075Controller.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/bjq/AppDeviceBJQ6075Controller.java index ae27a8e..c87d8b7 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/bjq/AppDeviceBJQ6075Controller.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/bjq/AppDeviceBJQ6075Controller.java @@ -3,6 +3,7 @@ package com.fuyuanshen.app.controller.device.bjq; 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.AppDevice6075DetailVo; import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.core.validate.AddGroup; @@ -10,6 +11,7 @@ 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.DeviceBJQ6075BizService; import com.fuyuanshen.web.service.device.DeviceBJQBizService; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; @@ -27,6 +29,7 @@ import org.springframework.web.multipart.MultipartFile; public class AppDeviceBJQ6075Controller extends BaseController { private final DeviceBJQBizService appDeviceService; + private final DeviceBJQ6075BizService appDeviceService6075; /** @@ -35,9 +38,9 @@ public class AppDeviceBJQ6075Controller extends BaseController { * @param id 主键 */ @GetMapping("/{id}") - public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable Long id) { - return R.ok(appDeviceService.getInfo(id)); + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(appDeviceService6075.getInfo(id)); } @@ -45,7 +48,6 @@ public class AppDeviceBJQ6075Controller extends BaseController { * 人员信息登记 */ @PostMapping(value = "/registerPersonInfo") -// @FunctionAccessAnnotation("registerPersonInfo") public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { return toAjax(appDeviceService.registerPersonInfo(bo)); } @@ -84,23 +86,35 @@ public class AppDeviceBJQ6075Controller extends BaseController { return R.ok(); } - /** * 灯光模式 - * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) + * (主光模式) + * 0(关闭灯光),1(强光),2(超强光), 3(工作光), 4(节能光),5(爆闪),6(SOS) + * (辅光模式) + * 0(关闭灯光),1(泛光),2(泛光爆闪), 3(警示灯), 4(警示灯/泛光) */ -// @FunctionAccessAnnotation("lightModeSettings") @PostMapping("/lightModeSettings") public R lightModeSettings(@RequestBody DeviceInstructDto params) { - // params 转 JSONObject appDeviceService.lightModeSettings(params); return R.ok(); } + + /** + * 灯光模式 + * (辅光模式) + * 0(关闭灯光),1(泛光),2(泛光爆闪), 3(警示灯), 4(警示灯/泛光) + */ + @PostMapping("/auxiliaryLightModeSettings") + public R auxiliaryLightModeSettings(@RequestBody DeviceInstructDto params) { + appDeviceService.lightModeSettings(params); + return R.ok(); + } + + /** * 灯光亮度设置 */ -// @FunctionAccessAnnotation("lightBrightnessSettings") @PostMapping("/lightBrightnessSettings") public R lightBrightnessSettings(@RequestBody DeviceInstructDto params) { appDeviceService.lightBrightnessSettings(params); @@ -111,10 +125,20 @@ public class AppDeviceBJQ6075Controller extends BaseController { * 激光模式设置 */ @PostMapping("/laserModeSettings") -// @FunctionAccessAnnotation("laserModeSettings") public R laserModeSettings(@RequestBody DeviceInstructDto params) { appDeviceService.laserModeSettings(params); return R.ok(); } + + /** + * 声光报警模式设置 + * Sound and light alarm + */ + @PostMapping("/salaModeSettings") + public R salaModeSettings(@RequestBody DeviceInstructDto params) { + appDeviceService.laserModeSettings(params); + return R.ok(); + } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/DeviceInstructDto.java b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/DeviceInstructDto.java index 074bed3..75fa57b 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/DeviceInstructDto.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/DeviceInstructDto.java @@ -8,9 +8,15 @@ public class DeviceInstructDto { private Long deviceId; private String deviceImei; + /** - * 下发指令 + * 下发指令 */ private String instructValue; + /** + * 下发指令类型 + */ + private String instructType; + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQ6075BizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQ6075BizService.java new file mode 100644 index 0000000..2e1de5e --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQ6075BizService.java @@ -0,0 +1,102 @@ +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.AppDevice6075DetailVo; +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.*; +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.DeviceType; +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.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.InputStream; +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.*; + + +@Service +public interface DeviceBJQ6075BizService { + + /** + * 获取设备详情 + * + * @param id 设备ID + * @return 设备详情 + */ + public AppDevice6075DetailVo getInfo(Long id); + + public int sendMessage(AppDeviceSendMsgBo bo); + + /** + * 记录设备操作日志 + * + * @param deviceId 设备ID + * @param content 日志内容 + * @param operator 操作人 + */ + public void recordDeviceLog(Long deviceId, String deviceName, String deviceAction, String content, Long operator); + + + public boolean registerPersonInfo(AppPersonnelInfoBo bo); + + public void uploadDeviceLogo2(AppDeviceLogoUploadDto bo); + + public void uploadDeviceLogo(AppDeviceLogoUploadDto bo); + + /** + * 灯光模式 + * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) + */ + + public void lightModeSettings(DeviceInstructDto params); + + // 灯光亮度设置 + public void lightBrightnessSettings(DeviceInstructDto params); + + // 激光模式设置 + public void laserModeSettings(DeviceInstructDto params); + + public String mapReverseGeocoding(DeviceInstructDto params); + + public int sendAlarmMessage(AppDeviceSendMsgBo bo); + + public void messageSending(String deviceImei); + + public boolean getDeviceStatus(String deviceImei); + + public void batchUploadLogo(AppDeviceLogoUploadDto bo); + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/DeviceBJQ6075BizServiceImpl.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/DeviceBJQ6075BizServiceImpl.java new file mode 100644 index 0000000..b88197c --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/DeviceBJQ6075BizServiceImpl.java @@ -0,0 +1,598 @@ +package com.fuyuanshen.web.service.impl; + +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.AppDevice6075DetailVo; +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.*; +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.DeviceType; +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 com.fuyuanshen.web.service.device.DeviceBJQ6075BizService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.InputStream; +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.*; + + +@Slf4j +@Service +@RequiredArgsConstructor +public class DeviceBJQ6075BizServiceImpl implements DeviceBJQ6075BizService { + + private final DeviceMapper deviceMapper; + private final AppPersonnelInfoMapper appPersonnelInfoMapper; + private final AppPersonnelInfoRecordsMapper appPersonnelInfoRecordsMapper; + private final DeviceTypeMapper deviceTypeMapper; + private final MqttGateway mqttGateway; + private final DeviceLogMapper deviceLogMapper; + + + /** + * 获取设备详情 + * + * @param id + * @return + */ + @Override + public AppDevice6075DetailVo getInfo(Long id) { + Device device = deviceMapper.selectById(id); + if (device == null) { + throw new RuntimeException("请先将设备入库!!!"); + } + + AppDevice6075DetailVo vo = new AppDevice6075DetailVo(); + vo.setDeviceId(device.getId()); + vo.setDeviceName(device.getDeviceName()); + vo.setDevicePic(device.getDevicePic()); + vo.setDeviceImei(device.getDeviceImei()); + vo.setDeviceMac(device.getDeviceMac()); + vo.setDeviceStatus(device.getDeviceStatus()); + DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType()); + if (deviceType != null) { + vo.setCommunicationMode(Integer.valueOf(deviceType.getCommunicationMode())); + vo.setTypeName(deviceType.getTypeName()); + } + vo.setBluetoothName(device.getBluetoothName()); + + vo.setSendMsg(device.getSendMsg()); + + QueryWrapper qw = new QueryWrapper() + .eq("device_id", device.getId()); + AppPersonnelInfo appPersonnelInfo = appPersonnelInfoMapper.selectOne(qw); + if (appPersonnelInfo != null) { + AppPersonnelInfoVo personnelInfoVo = MapstructUtils.convert(appPersonnelInfo, AppPersonnelInfoVo.class); + vo.setPersonnelInfo(personnelInfoVo); + } + // 设备在线状态 + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); + // 设备在线状态 + if ("1".equals(onlineStatus)) { + vo.setOnlineStatus(1); + } else if ("2".equals(onlineStatus)) { + vo.setOnlineStatus(2); + } else { + vo.setOnlineStatus(0); + } + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX); + // 获取电量 + if (StringUtils.isNotBlank(deviceStatus)) { + JSONObject jsonObject = JSONObject.parseObject(deviceStatus); + vo.setMainLightMode(jsonObject.getString("mainLightMode")); + vo.setLaserLightMode(jsonObject.getString("laserLightMode")); + vo.setBatteryPercentage(jsonObject.getString("batteryPercentage")); + vo.setChargeState(jsonObject.getString("chargeState")); + vo.setBatteryRemainingTime(jsonObject.getString("batteryRemainingTime")); + } else { + vo.setBatteryPercentage("0"); + } + + String lightModeStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_LIGHT_MODE_KEY_PREFIX); + // 获取电量 + if (StringUtils.isNotBlank(deviceStatus)) { + vo.setMainLightMode(lightModeStatus); + } + + String lightBrightnessStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX); + if (StringUtils.isNotBlank(lightBrightnessStatus)) { + vo.setLightBrightness(lightBrightnessStatus); + } + + String laserLightMode = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_LASER_MODE_KEY_PREFIX); + if (StringUtils.isNotBlank(laserLightMode)) { + vo.setLaserLightMode(laserLightMode); + } + + // 获取经度纬度 + String locationKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX; + String locationInfo = RedisUtils.getCacheObject(locationKey); + if (StringUtils.isNotBlank(locationInfo)) { + JSONObject jsonObject = JSONObject.parseObject(locationInfo); + vo.setLongitude(jsonObject.get("longitude").toString()); + vo.setLatitude(jsonObject.get("latitude").toString()); + vo.setAddress((String) jsonObject.get("address")); + } + + String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX); + if (StringUtils.isNotBlank(alarmStatus)) { + vo.setAlarmStatus(alarmStatus); + } + + String lightBrightness = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX); + if (StringUtils.isNotBlank(lightBrightness)) { + vo.setLightBrightness(lightBrightness); + } + + return vo; + } + + + @Override + public int sendMessage(AppDeviceSendMsgBo bo) { + List deviceIds = bo.getDeviceIds(); + if (deviceIds == null || deviceIds.isEmpty()) { + throw new ServiceException("请选择设备"); + } + for (Long deviceId : deviceIds) { + Device device = deviceMapper.selectById(deviceId); + if (device == null) { + throw new ServiceException("设备不存在" + deviceId); + } + if (getDeviceStatus(device.getDeviceImei())) { + throw new ServiceException(device.getDeviceName() + ",设备已断开连接"); + } + try { + ClassPathResource resource = new ClassPathResource("image/background.png"); + InputStream inputStream = resource.getInputStream(); + + byte[] largeData = ImageWithTextGenerate.generate160x80ImageWithText2(bo.getSendMsg(), inputStream, 25600); + int[] ints = convertHexToDecimal(largeData); + RedisUtils.setCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + ":app_send_message_data", Arrays.toString(ints), Duration.ofSeconds(5 * 60L)); + + String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + ":app_send_message_data"); + + byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); + byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); + log.info("发送信息第0块数据大小: {} 字节", specificChunk.length); + + ArrayList intData = new ArrayList<>(); + intData.add(6); + intData.add(1); + ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk), intData); + intData.add(0); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), 1, JSON.toJSONString(map)); + log.info("发送信息点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), JSON.toJSONString(map)); + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", deviceId) + .set("send_msg", bo.getSendMsg()); + deviceMapper.update(updateWrapper); + + recordDeviceLog(deviceId, device.getDeviceName(), "发送信息", bo.getSendMsg(), AppLoginHelper.getUserId()); + } catch (Exception e) { + log.info("发送信息设备发送信息失败:{}", deviceId); + throw new ServiceException("发送指令失败"); + } + // 发送消息 + messageSending(device.getDeviceImei()); + } + + + return 1; + } + + /** + * 记录设备操作日志 + * + * @param deviceId 设备ID + * @param content 日志内容 + * @param operator 操作人 + */ + @Override + public 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); + } + } + + + @Override + public boolean registerPersonInfo(AppPersonnelInfoBo bo) { + Long deviceId = bo.getDeviceId(); + Device deviceObj = deviceMapper.selectById(deviceId); + if (deviceObj == null) { + throw new RuntimeException("请先将设备入库!!!"); + } + if (getDeviceStatus(deviceObj.getDeviceImei())) { + throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接"); + } + QueryWrapper qw = new QueryWrapper() + .eq("device_id", deviceId); + List appPersonnelInfoVos = appPersonnelInfoMapper.selectVoList(qw); +// unitName,position,name,id + byte[] unitName = generateFixedBitmapData(bo.getUnitName(), 120); + byte[] position = generateFixedBitmapData(bo.getPosition(), 120); + byte[] name = generateFixedBitmapData(bo.getName(), 120); + byte[] id = generateFixedBitmapData(bo.getCode(), 120); + ArrayList intData = new ArrayList<>(); + intData.add(2); + buildArr(convertHexToDecimal(unitName), intData); + buildArr(convertHexToDecimal(name), intData); + buildArr(convertHexToDecimal(position), intData); + buildArr(convertHexToDecimal(id), intData); + intData.add(0); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + 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); + 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); + 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) + .set("name", bo.getName()) + .set("position", bo.getPosition()) + .set("unit_name", bo.getUnitName()) + .set("code", bo.getCode()); + 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; + } + + @Override + 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("发送指令失败"); + } + } + + @Override + public void uploadDeviceLogo(AppDeviceLogoUploadDto bo) { + try { + Device device = deviceMapper.selectById(bo.getDeviceId()); + if (device == null) { + throw new ServiceException("设备不存在"); + } + if (getDeviceStatus(device.getDeviceImei())) { +// throw new ServiceException(device.getDeviceName()+",设备已断开连接"); + log.info(device.getDeviceName() + ",设备已断开连接"); + recordDeviceLog(device.getId(), device.getDeviceName(), "上传开机画面", device.getDeviceName() + ",设备已断开连接", AppLoginHelper.getUserId()); + return; + } + 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)); + + String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX); + + byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); + byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); + log.info("第0块数据大小: {} 字节", specificChunk.length); +// log.info("第0块数据: {}", Arrays.toString(specificChunk)); + + ArrayList intData = new ArrayList<>(); + intData.add(3); + intData.add(1); + ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk), intData); + intData.add(0); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), 1, JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), JSON.toJSONString(map)); + + recordDeviceLog(device.getId(), device.getDeviceName(), "上传开机画面", "上传开机画面", AppLoginHelper.getUserId()); + } catch (Exception e) { + e.printStackTrace(); + throw new ServiceException("发送指令失败"); + } + } + + /** + * 灯光模式 + * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) + */ + @Override + public void lightModeSettings(DeviceInstructDto params) { + try { + Long deviceId = params.getDeviceId(); + Device device = deviceMapper.selectById(deviceId); + if (device == null) { + throw new ServiceException("设备不存在"); + } + if (getDeviceStatus(device.getDeviceImei())) { + throw new ServiceException(device.getDeviceName() + ",设备已断开连接"); + } + Integer instructValue = Integer.parseInt(params.getInstructValue()); + ArrayList intData = new ArrayList<>(); + intData.add(1); + intData.add(instructValue); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), 1, JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), JSON.toJSONString(map)); + LightModeEnum modeEnum = LightModeEnum.getByCode(instructValue); + recordDeviceLog(device.getId(), device.getDeviceName(), "灯光模式", modeEnum != null ? modeEnum.getName() : null, AppLoginHelper.getUserId()); + } catch (Exception e) { + e.printStackTrace(); + throw new ServiceException("发送指令失败"); + } + } + + // 灯光亮度设置 + @Override + public void lightBrightnessSettings(DeviceInstructDto params) { + try { + Long deviceId = params.getDeviceId(); + Device device = deviceMapper.selectById(deviceId); + if (device == null) { + throw new ServiceException("设备不存在"); + } + if (getDeviceStatus(device.getDeviceImei())) { + throw new ServiceException(device.getDeviceName() + ",设备已断开连接"); + } + String instructValue = params.getInstructValue(); + ArrayList intData = new ArrayList<>(); + intData.add(5); + String[] values = instructValue.split("\\."); + String value1 = values[0]; + String value2 = values[1]; + if (StringUtils.isNoneBlank(value1)) { + intData.add(Integer.parseInt(value1)); + } + if (StringUtils.isNoneBlank(value2)) { + intData.add(Integer.parseInt(value2)); + } + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), 1, JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), JSON.toJSONString(map)); + + } catch (Exception e) { + e.printStackTrace(); + throw new ServiceException("发送指令失败"); + } + } + + // 激光模式设置 + @Override + public void laserModeSettings(DeviceInstructDto params) { + try { + Long deviceId = params.getDeviceId(); + Device device = deviceMapper.selectById(deviceId); + if (device == null) { + throw new ServiceException("设备不存在"); + } + if (getDeviceStatus(device.getDeviceImei())) { + throw new ServiceException(device.getDeviceName() + ",设备已断开连接"); + } + Integer instructValue = Integer.parseInt(params.getInstructValue()); + ArrayList intData = new ArrayList<>(); + intData.add(4); + intData.add(instructValue); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), 1, JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), JSON.toJSONString(map)); + // 1代表开启激光灯,此时主灯关闭,主灯控件为关机状态,为0代表关闭激光灯 + if ("1".equals(params.getInstructValue())) { + recordDeviceLog(device.getId(), device.getDeviceName(), "激光模式设置", "开启激光灯", AppLoginHelper.getUserId()); + } else { + recordDeviceLog(device.getId(), device.getDeviceName(), "激光模式设置", "关闭激光灯", AppLoginHelper.getUserId()); + } + } catch (Exception e) { + e.printStackTrace(); + throw new ServiceException("发送指令失败"); + } + } + + @Override + public String mapReverseGeocoding(DeviceInstructDto params) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("device_imei", params.getDeviceImei()); + List devices = deviceMapper.selectList(queryWrapper); + if (ObjectUtils.length(devices) == 0) { + throw new ServiceException("设备不存在"); + } + return RedisUtils.getCacheObject("device:location:" + devices.get(0).getDeviceImei()); + } + + @Override + public int sendAlarmMessage(AppDeviceSendMsgBo bo) { + try { + List deviceIds = bo.getDeviceIds(); + if (deviceIds == null || deviceIds.isEmpty()) { + throw new ServiceException("请选择设备"); + } + + for (Long deviceId : deviceIds) { + Device device = deviceMapper.selectById(deviceId); + if (device == null) { + throw new ServiceException("设备不存在" + deviceId); + } + if (getDeviceStatus(device.getDeviceImei())) { + throw new ServiceException(device.getDeviceName() + ",设备已断开连接"); + } + try { + + ArrayList intData = new ArrayList<>(); + intData.add(7); + intData.add(Integer.parseInt(bo.getInstructValue())); + intData.add(0); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), 1, JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(), JSON.toJSONString(map)); + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", deviceId) + .set("send_msg", bo.getSendMsg()); + deviceMapper.update(updateWrapper); + if ("0".equals(bo.getInstructValue())) { + recordDeviceLog(device.getId(), device.getDeviceName(), "解除告警信息", "关闭设备", AppLoginHelper.getUserId()); + } else { + recordDeviceLog(device.getId(), device.getDeviceName(), "发送告警信息", bo.getSendMsg(), AppLoginHelper.getUserId()); + } + } catch (Exception e) { + log.info("设备发送告警信息信息失败:{}", deviceId); + throw new ServiceException("设备发送告警信息信息失败"); + } + messageSending(device.getDeviceImei()); + } + + } catch (Exception e) { + e.printStackTrace(); + throw new ServiceException("发送告警信息指令失败"); + } + return 1; + } + + @Override + public void messageSending(String deviceImei) { + String sendMessageIng = GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + ":messageSending"; + RedisUtils.setCacheObject(sendMessageIng, "1", Duration.ofDays(1)); + } + + @Override + public boolean getDeviceStatus(String deviceImei) { + String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX; + return RedisUtils.getCacheObject(deviceOnlineStatusRedisKey) == null; + } + + @Override + public void batchUploadLogo(AppDeviceLogoUploadDto bo) { + + List deviceIds = bo.getDeviceIds(); + MultipartFile file = bo.getFile(); + if (deviceIds == null || deviceIds.isEmpty()) { + throw new ServiceException("请选择设备"); + } + for (Long deviceId : deviceIds) { + AppDeviceLogoUploadDto dto = new AppDeviceLogoUploadDto(); + dto.setDeviceId(deviceId); + dto.setFile(file); + uploadDeviceLogo(dto); + } + } + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDevice6075DetailVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDevice6075DetailVo.java new file mode 100644 index 0000000..1dfda61 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDevice6075DetailVo.java @@ -0,0 +1,120 @@ +package com.fuyuanshen.app.domain.vo; + +import cn.idev.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.io.Serial; + +@Data +public class AppDevice6075DetailVo { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 设备ID + */ + @ExcelProperty(value = "设备ID") + private Long deviceId; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 设备IMEI + */ + private String deviceImei; + + /** + * 设备MAC + */ + private String deviceMac; + + /** + * 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙 + */ + private Integer communicationMode; + + /** + * 设备图片 + */ + private String devicePic; + + /** + * 设备类型 + */ + private String typeName; + + /** + * 蓝牙名称 + */ + private String bluetoothName; + + /** + * 设备状态 + * 0 失效 + * 1 正常 + */ + private Integer deviceStatus; + + /** + * 人员信息 + */ + private AppPersonnelInfoVo personnelInfo; + + /** + * 发送信息 + */ + private String sendMsg; + + //"{\"deviceImei\":\"AA\",\"mainLightMode\":\"1\",\"laserLightMode\":\"0\",\"batteryPercentage\":\"60\",\"chargeState\":\"1\",\"batteryRemainingTime\":\"200\",\"timestamp\":1753871635241}" + // 设备主灯档位 + private String mainLightMode; + + // 激光灯档位 + private String laserLightMode; + + // 电量百分比 + private String batteryPercentage; + + // 充电状态(0没有充电,1正在充电,2为已充满) + private String chargeState; + + // 电池剩余续航时间200分钟 + private String batteryRemainingTime; + + /** + * 在线状态(0离线,1在线) + */ + private Integer onlineStatus; + + // 经度 + private String longitude; + + // 纬度 + private String latitude; + + // 逆解析地址 + private String address; + + /** + * 告警状态(0解除告警,1告警) + */ + private String alarmStatus; + + // 灯光亮度 + private String lightBrightness; + + /** + * 海拔高度 + */ + private Double altitude; + + /** + * 相对高度 + */ + private Double relativeAltitude; + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoVo.java index bbbabfa..f35ec26 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoVo.java @@ -64,5 +64,4 @@ public class AppPersonnelInfoVo implements Serializable { @ExcelProperty(value = "ID号") private String code; - }