package com.fuyuanshen.app.service; import cn.hutool.core.collection.CollectionUtil; 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.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.app.domain.AppDeviceBindRecord; import com.fuyuanshen.app.domain.AppPersonnelInfo; import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; import com.fuyuanshen.app.domain.dto.APPReNameDTO; import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; import com.fuyuanshen.app.domain.dto.DeviceInstructDto; import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; import com.fuyuanshen.app.mapper.AppDeviceBindRecordMapper; import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; import com.fuyuanshen.app.mapper.equipment.APPDeviceMapper; 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.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; 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.AppDeviceBo; import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; import com.fuyuanshen.equipment.enums.BindingStatusEnum; import com.fuyuanshen.equipment.enums.CommunicationModeEnum; import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; import com.fuyuanshen.equipment.utils.c.ReliableTextToBitmap; 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; @Slf4j @Service @RequiredArgsConstructor public class AppDeviceBizService { private final APPDeviceMapper appDeviceMapper; private final DeviceMapper deviceMapper; private final AppPersonnelInfoMapper appPersonnelInfoMapper; private final DeviceTypeMapper deviceTypeMapper; private final MqttGateway mqttGateway; private final AppDeviceBindRecordMapper appDeviceBindRecordMapper; public List getTypeList() { Long userId = AppLoginHelper.getUserId(); return appDeviceMapper.getTypeList(userId); } public void reName(APPReNameDTO reNameDTO) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.eq("id", reNameDTO.getId()) .eq("binding_user_id", AppLoginHelper.getUserId()) .set("device_name", reNameDTO.getDeviceName()); deviceMapper.update(updateWrapper); } public int sendMessage(AppDeviceSendMsgBo bo) { List deviceIds = bo.getDeviceIds(); if (deviceIds == null || deviceIds.isEmpty()) { throw new ServiceException("请选择设备"); } for (Long deviceId : deviceIds) { Device deviceObj = deviceMapper.selectById(deviceId); if (deviceObj == null) { throw new ServiceException("设备不存在" + deviceId); } byte[] msg = ReliableTextToBitmap.textToBitmapBytes(bo.getSendMsg()); ArrayList intData = new ArrayList<>(); intData.add(2); buildArr(convertHexToDecimal(msg), intData); 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.getSendMsg()); UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.eq("id", deviceId) .eq("binding_user_id", AppLoginHelper.getUserId()) .set("send_msg", bo.getSendMsg()); deviceMapper.update(updateWrapper); } return 1; } public TableDataInfo queryAppDeviceList(DeviceQueryCriteria bo, PageQuery pageQuery) { if (bo.getBindingUserId() == null) { Long userId = AppLoginHelper.getUserId(); bo.setBindingUserId(userId); } Page result = deviceMapper.queryAppBindDeviceList(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+DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + item.getDeviceImei()); if(StringUtils.isNotBlank(onlineStatus)){ item.setOnlineStatus(1); }else{ item.setOnlineStatus(0); } String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + item.getDeviceImei()); // 获取电量 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+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + item.getDeviceImei()); // 获取电量 if(StringUtils.isNotBlank(location)){ JSONObject jsonObject = JSONObject.parseObject(location); item.setLatitude(jsonObject.getString("latitude")); item.setLongitude(jsonObject.getString("longitude")); }else{ item.setBattery("0"); } } }); } return TableDataInfo.build(result); } public int bindDevice(AppDeviceBo bo) { Integer mode = bo.getCommunicationMode(); Long userId = AppLoginHelper.getUserId(); if (mode == CommunicationModeEnum.FOUR_G.getValue()) { String deviceImei = bo.getDeviceImei(); QueryWrapper qw = new QueryWrapper() .eq("device_imei", deviceImei); List devices = deviceMapper.selectList(qw); if (devices.isEmpty()) { throw new RuntimeException("请先将设备入库!!!"); } Device device = devices.get(0); if (device.getBindingStatus() != null && device.getBindingStatus() == BindingStatusEnum.BOUND.getCode()) { throw new RuntimeException("设备已绑定"); } QueryWrapper bindRecordQueryWrapper = new QueryWrapper<>(); bindRecordQueryWrapper.eq("device_id", device.getId()); AppDeviceBindRecord appDeviceBindRecord = appDeviceBindRecordMapper.selectOne(bindRecordQueryWrapper); if (appDeviceBindRecord != null) { UpdateWrapper deviceUpdateWrapper = new UpdateWrapper<>(); deviceUpdateWrapper.eq("device_id", device.getId()) .set("binding_status", BindingStatusEnum.BOUND.getCode()) .set("binding_user_id", userId) .set("update_time", new Date()) .set("binding_time", new Date()); return appDeviceBindRecordMapper.update(null, deviceUpdateWrapper); } else { AppDeviceBindRecord bindRecord = new AppDeviceBindRecord(); bindRecord.setDeviceId(device.getId()); bindRecord.setBindingUserId(userId); bindRecord.setBindingTime(new Date()); bindRecord.setCreateBy(userId); appDeviceBindRecordMapper.insert(bindRecord); } UpdateWrapper deviceUpdateWrapper = new UpdateWrapper<>(); deviceUpdateWrapper.eq("id", device.getId()) .set("binding_status", BindingStatusEnum.BOUND.getCode()) .set("binding_user_id", userId) .set("binding_time", new Date()); return deviceMapper.update(null, deviceUpdateWrapper); } else if (mode == CommunicationModeEnum.BLUETOOTH.getValue()) { String deviceMac = bo.getDeviceMac(); QueryWrapper qw = new QueryWrapper() .eq("device_mac", deviceMac); List devices = deviceMapper.selectList(qw); if (devices.isEmpty()) { throw new RuntimeException("请先将设备入库!!!"); } Device device = devices.get(0); QueryWrapper bindRecordQueryWrapper = new QueryWrapper<>(); bindRecordQueryWrapper.eq("device_id", device.getId()); bindRecordQueryWrapper.eq("binding_user_id", userId); AppDeviceBindRecord appDeviceBindRecord = appDeviceBindRecordMapper.selectOne(bindRecordQueryWrapper); if (appDeviceBindRecord != null) { UpdateWrapper deviceUpdateWrapper = new UpdateWrapper<>(); deviceUpdateWrapper.eq("device_id", device.getId()) .eq("binding_user_id", userId) .set("binding_user_id", userId) .set("binding_time", new Date()); return appDeviceBindRecordMapper.update(null, deviceUpdateWrapper); } else { AppDeviceBindRecord bindRecord = new AppDeviceBindRecord(); bindRecord.setDeviceId(device.getId()); bindRecord.setBindingUserId(userId); bindRecord.setBindingTime(new Date()); bindRecord.setCreateBy(userId); appDeviceBindRecordMapper.insert(bindRecord); } UpdateWrapper deviceUpdateWrapper = new UpdateWrapper<>(); deviceUpdateWrapper.eq("id", device.getId()) .set("binding_status", BindingStatusEnum.BOUND.getCode()) .set("binding_user_id", userId) .set("binding_time", new Date()); return deviceMapper.update(null, deviceUpdateWrapper); } else { throw new RuntimeException("通讯方式错误"); } } public int unBindDevice(Long id) { return unBindDevice(id, null, 1); } public int unBindDevice(Long id, Long userId, int type) { Device device = deviceMapper.selectById(id); if (device == null) { throw new RuntimeException("请先将设备入库!!!"); } UpdateWrapper deviceUpdateWrapper = new UpdateWrapper<>(); deviceUpdateWrapper.eq("id", device.getId()) .set("binding_user_id", null) .set("binding_status", BindingStatusEnum.UNBOUND.getCode()) .set("binding_time", null); deviceMapper.update(null, deviceUpdateWrapper); if (userId == null) { userId = AppLoginHelper.getUserId(); } QueryWrapper bindRecordQueryWrapper = new QueryWrapper<>(); bindRecordQueryWrapper.eq("device_id", device.getId()); // 设备端解绑 0:设备端解绑 1:web端解绑 if (type == 1) { bindRecordQueryWrapper.eq("binding_user_id", userId); } // AppDeviceBindRecord appDeviceBindRecord = appDeviceBindRecordMapper.selectOne(bindRecordQueryWrapper); // if (appDeviceBindRecord != null) { // return appDeviceBindRecordMapper.deleteById(appDeviceBindRecord.getId()); // } List appDeviceBindRecordList = appDeviceBindRecordMapper.selectList(bindRecordQueryWrapper); if (CollectionUtil.isNotEmpty(appDeviceBindRecordList)) { appDeviceBindRecordList.forEach(appDeviceBindRecord -> appDeviceBindRecordMapper.deleteById(appDeviceBindRecord.getId())); } return 1; } public AppDeviceDetailVo getInfo(Long id) { Device device = deviceMapper.selectById(id); if (device == null) { throw new RuntimeException("请先将设备入库!!!"); } AppDeviceDetailVo vo = new AppDeviceDetailVo(); 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+DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + device.getDeviceImei()); if(StringUtils.isNotBlank(onlineStatus)){ vo.setOnlineStatus(1); }else{ vo.setOnlineStatus(0); } String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + device.getDeviceImei()); // 获取电量 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 locationKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + device.getDeviceImei(); String locationInfo = RedisUtils.getCacheObject(locationKey); if(StringUtils.isNotBlank(locationInfo)){ JSONObject jsonObject = JSONObject.parseObject(locationInfo); vo.setLongitude((String)jsonObject.get("longitude")); vo.setLatitude((String)jsonObject.get("latitude")); vo.setAddress((String)jsonObject.get("address")); } return vo; } public boolean registerPersonInfo(AppPersonnelInfoBo bo) { Long deviceId = bo.getDeviceId(); Device deviceObj = deviceMapper.selectById(deviceId); if (deviceObj == null) { throw new RuntimeException("请先将设备入库!!!"); } 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(position), intData); buildArr(convertHexToDecimal(name), 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); 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; } } public void uploadDeviceLogo(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); System.out.println("长度:" + largeData.length); System.out.println("原始数据大小: " + largeData.length + " 字节"); int[] ints = convertHexToDecimal(largeData); RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+"app_logo_data:" + device.getDeviceImei(), Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+"app_logo_data:" + device.getDeviceImei()); byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); System.out.println("第0块数据大小: " + specificChunk.length + " 字节"); System.out.println("第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)); } catch (Exception e){ e.printStackTrace(); } } /** * 灯光模式 * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) */ public void lightModeSettings(DeviceInstructDto params) { try { Long deviceId = params.getDeviceId(); Device device = deviceMapper.selectById(deviceId); if(device == null){ throw new ServiceException("设备不存在"); } 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)); } catch (Exception e){ e.printStackTrace(); } } //灯光亮度设置 public void lightBrightnessSettings(DeviceInstructDto params) { try { Long deviceId = params.getDeviceId(); Device device = deviceMapper.selectById(deviceId); if(device == null){ throw new ServiceException("设备不存在"); } 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(); } } //激光模式设置 public void laserModeSettings(DeviceInstructDto params) { try { Long deviceId = params.getDeviceId(); Device device = deviceMapper.selectById(deviceId); if(device == null){ throw new ServiceException("设备不存在"); } 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)); } catch (Exception e){ e.printStackTrace(); } } public String mapReverseGeocoding(DeviceInstructDto params) { // Long deviceId = params.getDeviceId(); // Device device = deviceMapper.selectById(deviceId); 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()); } }