Compare commits

10 Commits

Author SHA1 Message Date
447aa73ae9 Merge branch 'dyf-device' 2025-08-14 14:22:43 +08:00
bc165f5d60 分享管理 2025-08-09 17:09:26 +08:00
af64984623 修改分享功能 2025-08-09 08:49:37 +08:00
0c932c686d 修改分享查看 2025-08-08 16:32:40 +08:00
47dbd33d56 修改在线上报状态 2025-08-08 15:09:59 +08:00
41c6cb935d Merge branch 'dyf-device' 2025-08-07 18:08:12 +08:00
efed6f3683 修改包名 2025-08-07 15:56:12 +08:00
f67e848256 晶全6710 2025-08-07 15:41:57 +08:00
825e9b329c Merge remote-tracking branch 'origin/main' 2025-08-06 10:39:01 +08:00
67764a733e 设备列表电量显示问题,打印日志优化 2025-08-06 10:38:21 +08:00
27 changed files with 1636 additions and 729 deletions

View File

@ -1,31 +1,20 @@
package com.fuyuanshen.app.controller; package com.fuyuanshen.app.controller;
import cn.hutool.json.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo;
import com.fuyuanshen.app.domain.dto.APPReNameDTO; 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.APPDeviceTypeVo;
import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo;
import com.fuyuanshen.app.service.AppDeviceBizService; import com.fuyuanshen.app.service.AppDeviceBizService;
import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.validate.AddGroup;
import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; 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.query.DeviceQueryCriteria;
import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* APP设备信息管理 * APP设备信息管理
@ -83,95 +72,4 @@ public class AppDeviceController extends BaseController {
appDeviceService.reName(reNameDTO); appDeviceService.reName(reNameDTO);
return R.ok("重命名成功!!!"); return R.ok("重命名成功!!!");
} }
/**
* 获取设备详细信息
*
* @param id 主键
*/
@GetMapping("/{id}")
public R<AppDeviceDetailVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(appDeviceService.getInfo(id));
}
/**
* 人员信息登记
*/
@PostMapping(value = "/registerPersonInfo")
public R<Void> registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) {
return toAjax(appDeviceService.registerPersonInfo(bo));
}
/**
* 发送信息
*/
@PostMapping(value = "/sendMessage")
public R<Void> sendMessage(@RequestBody AppDeviceSendMsgBo bo) {
return toAjax(appDeviceService.sendMessage(bo));
}
/**
* 发送报警信息
*/
@PostMapping(value = "/sendAlarmMessage")
public R<Void> sendAlarmMessage(@RequestBody AppDeviceSendMsgBo bo) {
return toAjax(appDeviceService.sendAlarmMessage(bo));
}
/**
* 上传设备logo图片
*/
@PostMapping("/uploadLogo")
public R<Void> 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();
}
/**
* 灯光模式
* 0关灯1强光模式2弱光模式, 3爆闪模式, 4泛光模式
*/
@PostMapping("/lightModeSettings")
public R<Void> lightModeSettings(@RequestBody DeviceInstructDto params) {
// params 转 JSONObject
appDeviceService.lightModeSettings(params);
return R.ok();
}
/**
* 灯光亮度设置
*
*/
@PostMapping("/lightBrightnessSettings")
public R<Void> lightBrightnessSettings(@RequestBody DeviceInstructDto params) {
appDeviceService.lightBrightnessSettings(params);
return R.ok();
}
/**
* 激光模式设置
*
*/
@PostMapping("/laserModeSettings")
public R<Void> laserModeSettings(@RequestBody DeviceInstructDto params) {
appDeviceService.laserModeSettings(params);
return R.ok();
}
/**
* 地图逆解析
*
*/
@PostMapping("/mapReverseGeocoding")
public R<Void> mapReverseGeocoding(@RequestBody DeviceInstructDto params) {
String mapJson = appDeviceService.mapReverseGeocoding(params);
return R.ok(mapJson);
}
} }

View File

@ -52,7 +52,7 @@ public class AppDeviceShareController extends BaseController {
*/ */
@GetMapping("/deviceShareList") @GetMapping("/deviceShareList")
public TableDataInfo<AppDeviceShareVo> list(AppDeviceShareBo bo, PageQuery pageQuery) { public TableDataInfo<AppDeviceShareVo> list(AppDeviceShareBo bo, PageQuery pageQuery) {
return deviceShareService.queryPageList(bo, pageQuery); return appDeviceShareService.queryPageList(bo, pageQuery);
} }
/** /**
@ -60,7 +60,7 @@ public class AppDeviceShareController extends BaseController {
*/ */
@GetMapping("/otherDeviceShareList") @GetMapping("/otherDeviceShareList")
public TableDataInfo<AppDeviceShareVo> otherDeviceShareList(AppDeviceShareBo bo, PageQuery pageQuery) { public TableDataInfo<AppDeviceShareVo> otherDeviceShareList(AppDeviceShareBo bo, PageQuery pageQuery) {
return deviceShareService.otherDeviceShareList(bo, pageQuery); return appDeviceShareService.otherDeviceShareList(bo, pageQuery);
} }
/** /**

View File

@ -0,0 +1,119 @@
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.app.service.device.AppDeviceBJQBizService;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.validate.AddGroup;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo;
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("/app/bjq/device")
public class AppDeviceBJQController extends BaseController {
private final AppDeviceBJQBizService appDeviceService;
/**
* 获取设备详细信息
*
* @param id 主键
*/
@GetMapping("/{id}")
public R<AppDeviceDetailVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(appDeviceService.getInfo(id));
}
/**
* 人员信息登记
*/
@PostMapping(value = "/registerPersonInfo")
public R<Void> registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) {
return toAjax(appDeviceService.registerPersonInfo(bo));
}
/**
* 发送信息
*/
@PostMapping(value = "/sendMessage")
public R<Void> sendMessage(@RequestBody AppDeviceSendMsgBo bo) {
return toAjax(appDeviceService.sendMessage(bo));
}
/**
* 发送报警信息
*/
@PostMapping(value = "/sendAlarmMessage")
public R<Void> sendAlarmMessage(@RequestBody AppDeviceSendMsgBo bo) {
return toAjax(appDeviceService.sendAlarmMessage(bo));
}
/**
* 上传设备logo图片
*/
@PostMapping("/uploadLogo")
public R<Void> 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();
}
/**
* 灯光模式
* 0关灯1强光模式2弱光模式, 3爆闪模式, 4泛光模式
*/
@PostMapping("/lightModeSettings")
public R<Void> lightModeSettings(@RequestBody DeviceInstructDto params) {
// params 转 JSONObject
appDeviceService.lightModeSettings(params);
return R.ok();
}
/**
* 灯光亮度设置
*
*/
@PostMapping("/lightBrightnessSettings")
public R<Void> lightBrightnessSettings(@RequestBody DeviceInstructDto params) {
appDeviceService.lightBrightnessSettings(params);
return R.ok();
}
/**
* 激光模式设置
*
*/
@PostMapping("/laserModeSettings")
public R<Void> laserModeSettings(@RequestBody DeviceInstructDto params) {
appDeviceService.laserModeSettings(params);
return R.ok();
}
/**
* 地图逆解析
*
*/
@PostMapping("/mapReverseGeocoding")
public R<Void> mapReverseGeocoding(@RequestBody DeviceInstructDto params) {
String mapJson = appDeviceService.mapReverseGeocoding(params);
return R.ok(mapJson);
}
}

View File

@ -0,0 +1,112 @@
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.app.service.AppDeviceBizService;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.validate.AddGroup;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo;
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;
/**
* HBY210设备控制类
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/app/hby/device")
public class AppDeviceHBYController extends BaseController {
private final AppDeviceBizService appDeviceService;
/**
* 获取设备详细信息
*
* @param id 主键
*/
@GetMapping("/{id}")
public R<AppDeviceDetailVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(appDeviceService.getInfo(id));
}
/**
* 人员信息登记
*/
@PostMapping(value = "/registerPersonInfo")
public R<Void> registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) {
return toAjax(appDeviceService.registerPersonInfo(bo));
}
/**
* 发送信息
*/
@PostMapping(value = "/sendMessage")
public R<Void> sendMessage(@RequestBody AppDeviceSendMsgBo bo) {
return toAjax(appDeviceService.sendMessage(bo));
}
/**
* 上传设备logo图片
*/
@PostMapping("/uploadLogo")
public R<Void> 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();
}
/**
* 灯光模式
* 0关灯1强光模式2弱光模式, 3爆闪模式, 4泛光模式
*/
@PostMapping("/lightModeSettings")
public R<Void> lightModeSettings(@RequestBody DeviceInstructDto params) {
// params 转 JSONObject
appDeviceService.lightModeSettings(params);
return R.ok();
}
/**
* 灯光亮度设置
*
*/
@PostMapping("/lightBrightnessSettings")
public R<Void> lightBrightnessSettings(@RequestBody DeviceInstructDto params) {
appDeviceService.lightBrightnessSettings(params);
return R.ok();
}
/**
* 激光模式设置
*
*/
@PostMapping("/laserModeSettings")
public R<Void> laserModeSettings(@RequestBody DeviceInstructDto params) {
appDeviceService.laserModeSettings(params);
return R.ok();
}
/**
* 地图逆解析
*
*/
@PostMapping("/mapReverseGeocoding")
public R<Void> mapReverseGeocoding(@RequestBody DeviceInstructDto params) {
String mapJson = appDeviceService.mapReverseGeocoding(params);
return R.ok(mapJson);
}
}

View File

@ -54,6 +54,7 @@ import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_K
import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.buildArr; 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.Bitmap80x12Generator.generateFixedBitmapData;
import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*;
@Slf4j @Slf4j
@ -101,14 +102,14 @@ public class AppDeviceBizService {
// String backgroundImagePath = "D:\\background.png"; // 替换为实际背景图片路径 // String backgroundImagePath = "D:\\background.png"; // 替换为实际背景图片路径
byte[] largeData = ImageWithTextGenerate.generate160x80ImageWithText2(bo.getSendMsg(), inputStream, 25600); byte[] largeData = ImageWithTextGenerate.generate160x80ImageWithText2(bo.getSendMsg(), inputStream, 25600);
int[] ints = convertHexToDecimal(largeData); int[] ints = convertHexToDecimal(largeData);
RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+"app_send_message_data:" + device.getDeviceImei(), Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_SEND_MESSAGE_KEY_PREFIX , Arrays.toString(ints), Duration.ofSeconds(30 * 60L));
String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+"app_send_message_data:" + device.getDeviceImei()); String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_SEND_MESSAGE_KEY_PREFIX);
byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data);
byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512);
System.out.println("第0块数据大小: " + specificChunk.length + " 字节"); log.info("发送信息第0块数据大小: {} 字节",specificChunk.length);
System.out.println("第0块数据: " + Arrays.toString(specificChunk)); // log.info("第0块数据: {}", Arrays.toString(specificChunk));
ArrayList<Integer> intData = new ArrayList<>(); ArrayList<Integer> intData = new ArrayList<>();
intData.add(6); intData.add(6);
@ -121,7 +122,7 @@ public class AppDeviceBizService {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("instruct", intData); map.put("instruct", intData);
mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); 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)); log.info("发送信息点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map));
UpdateWrapper<Device> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<Device> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", deviceId) updateWrapper.eq("id", deviceId)
@ -129,7 +130,7 @@ public class AppDeviceBizService {
.set("send_msg", bo.getSendMsg()); .set("send_msg", bo.getSendMsg());
deviceMapper.update(updateWrapper); deviceMapper.update(updateWrapper);
} catch (Exception e) { } catch (Exception e) {
log.info("设备发送信息失败:{}" ,deviceId); log.info("发送信息设备发送信息失败:{}" ,deviceId);
} }
} }
@ -149,14 +150,14 @@ public class AppDeviceBizService {
if(item.getCommunicationMode()!=null && item.getCommunicationMode() == 0){ if(item.getCommunicationMode()!=null && item.getCommunicationMode() == 0){
//设备在线状态 //设备在线状态
String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + item.getDeviceImei()); String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX);
if(StringUtils.isNotBlank(onlineStatus)){ if(StringUtils.isNotBlank(onlineStatus)){
item.setOnlineStatus(1); item.setOnlineStatus(1);
}else{ }else{
item.setOnlineStatus(0); item.setOnlineStatus(0);
} }
String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + item.getDeviceImei()); String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX+ item.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX);
// 获取电量 // 获取电量
if(StringUtils.isNotBlank(deviceStatus)){ if(StringUtils.isNotBlank(deviceStatus)){
JSONObject jsonObject = JSONObject.parseObject(deviceStatus); JSONObject jsonObject = JSONObject.parseObject(deviceStatus);
@ -165,14 +166,16 @@ public class AppDeviceBizService {
item.setBattery("0"); item.setBattery("0");
} }
String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + item.getDeviceImei()); String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_LOCATION_KEY_PREFIX);
// 获取电量
if(StringUtils.isNotBlank(location)){ if(StringUtils.isNotBlank(location)){
JSONObject jsonObject = JSONObject.parseObject(location); JSONObject jsonObject = JSONObject.parseObject(location);
item.setLatitude(jsonObject.getString("latitude")); item.setLatitude(jsonObject.getString("latitude"));
item.setLongitude(jsonObject.getString("longitude")); item.setLongitude(jsonObject.getString("longitude"));
}else{ }
item.setBattery("0");
String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_ALARM_KEY_PREFIX);
if(StringUtils.isNotBlank(alarmStatus)){
item.setAlarmStatus(alarmStatus);
} }
} }
}); });
@ -336,13 +339,13 @@ public class AppDeviceBizService {
vo.setPersonnelInfo(personnelInfoVo); vo.setPersonnelInfo(personnelInfoVo);
} }
//设备在线状态 //设备在线状态
String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + device.getDeviceImei()); String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX);
if(StringUtils.isNotBlank(onlineStatus)){ if(StringUtils.isNotBlank(onlineStatus)){
vo.setOnlineStatus(1); vo.setOnlineStatus(1);
}else{ }else{
vo.setOnlineStatus(0); vo.setOnlineStatus(0);
} }
String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + device.getDeviceImei()); String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX);
// 获取电量 // 获取电量
if(StringUtils.isNotBlank(deviceStatus)){ if(StringUtils.isNotBlank(deviceStatus)){
JSONObject jsonObject = JSONObject.parseObject(deviceStatus); JSONObject jsonObject = JSONObject.parseObject(deviceStatus);
@ -356,7 +359,7 @@ public class AppDeviceBizService {
} }
// 获取经度纬度 // 获取经度纬度
String locationKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + device.getDeviceImei(); String locationKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_LOCATION_KEY_PREFIX;
String locationInfo = RedisUtils.getCacheObject(locationKey); String locationInfo = RedisUtils.getCacheObject(locationKey);
if(StringUtils.isNotBlank(locationInfo)){ if(StringUtils.isNotBlank(locationInfo)){
JSONObject jsonObject = JSONObject.parseObject(locationInfo); JSONObject jsonObject = JSONObject.parseObject(locationInfo);
@ -433,19 +436,19 @@ public class AppDeviceBizService {
MultipartFile file = bo.getFile(); MultipartFile file = bo.getFile();
byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600); byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600);
System.out.println("长度:" + largeData.length); log.info("长度:" + largeData.length);
System.out.println("原始数据大小: " + largeData.length + " 字节"); log.info("原始数据大小: {} 字节", largeData.length);
int[] ints = convertHexToDecimal(largeData); int[] ints = convertHexToDecimal(largeData);
RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+"app_logo_data:" + device.getDeviceImei(), Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX, Arrays.toString(ints), Duration.ofSeconds(30 * 60L));
String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+"app_logo_data:" + device.getDeviceImei()); String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX);
byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data);
byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512);
System.out.println("第0块数据大小: " + specificChunk.length + " 字节"); log.info("第0块数据大小: {} 字节", specificChunk.length);
System.out.println("第0块数据: " + Arrays.toString(specificChunk)); // log.info("第0块数据: {}", Arrays.toString(specificChunk));
ArrayList<Integer> intData = new ArrayList<>(); ArrayList<Integer> intData = new ArrayList<>();
intData.add(3); intData.add(3);

View File

@ -1,7 +1,11 @@
package com.fuyuanshen.app.service; package com.fuyuanshen.app.service;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fuyuanshen.app.domain.AppDeviceShare; import com.fuyuanshen.app.domain.AppDeviceShare;
import com.fuyuanshen.app.domain.AppPersonnelInfo; import com.fuyuanshen.app.domain.AppPersonnelInfo;
import com.fuyuanshen.app.domain.bo.AppDeviceShareBo; import com.fuyuanshen.app.domain.bo.AppDeviceShareBo;
@ -16,12 +20,15 @@ import com.fuyuanshen.common.core.exception.ServiceException;
import com.fuyuanshen.common.core.exception.user.CaptchaExpireException; import com.fuyuanshen.common.core.exception.user.CaptchaExpireException;
import com.fuyuanshen.common.core.utils.MessageUtils; import com.fuyuanshen.common.core.utils.MessageUtils;
import com.fuyuanshen.common.core.utils.StringUtils; 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.redis.utils.RedisUtils;
import com.fuyuanshen.common.satoken.utils.AppLoginHelper; import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.DeviceType; import com.fuyuanshen.equipment.domain.DeviceType;
import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper;
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -30,6 +37,9 @@ import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*;
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@ -44,10 +54,51 @@ public class AppDeviceShareService {
private final AppPersonnelInfoMapper appPersonnelInfoMapper; private final AppPersonnelInfoMapper appPersonnelInfoMapper;
public TableDataInfo<AppDeviceShareVo> queryPageList(AppDeviceShareBo bo, PageQuery pageQuery) {
Long userId = AppLoginHelper.getUserId();
bo.setCreateBy(userId);
Page<AppDeviceShareVo> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
Page<AppDeviceShareVo> result = appDeviceShareMapper.selectAppDeviceShareList(bo, page);
List<AppDeviceShareVo> records = result.getRecords();
records.forEach(AppDeviceShareService::buildDeviceStatus);
return TableDataInfo.build(result);
}
private static void buildDeviceStatus(AppDeviceShareVo item) {
//设备在线状态
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);
}
}
public AppDeviceShareDetailVo getInfo(Long id) { public AppDeviceShareDetailVo getInfo(Long id) {
LambdaQueryWrapper<AppDeviceShare> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<AppDeviceShare> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AppDeviceShare::getDeviceId, id); queryWrapper.eq(AppDeviceShare::getId, id);
List<AppDeviceShareVo> appDeviceShareVos = appDeviceShareMapper.selectVoList(queryWrapper); List<AppDeviceShareVo> appDeviceShareVos = appDeviceShareMapper.selectVoList(queryWrapper);
if(appDeviceShareVos==null || appDeviceShareVos.isEmpty()){ if(appDeviceShareVos==null || appDeviceShareVos.isEmpty()){
return null; return null;
@ -81,7 +132,35 @@ public class AppDeviceShareService {
if(appPersonnelInfoVos!=null && !appPersonnelInfoVos.isEmpty()){ if(appPersonnelInfoVos!=null && !appPersonnelInfoVos.isEmpty()){
shareDetailVo.setPersonnelInfo(appPersonnelInfoVos.get(0)); shareDetailVo.setPersonnelInfo(appPersonnelInfoVos.get(0));
} }
//设备在线状态
String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei()+ DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX);
if(StringUtils.isNotBlank(onlineStatus)){
shareDetailVo.setOnlineStatus(1);
}else{
shareDetailVo.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);
shareDetailVo.setMainLightMode(jsonObject.getString("mainLightMode"));
shareDetailVo.setLaserLightMode(jsonObject.getString("laserLightMode"));
shareDetailVo.setBatteryPercentage(jsonObject.getString("batteryPercentage"));
shareDetailVo.setChargeState(jsonObject.getString("chargeState"));
shareDetailVo.setBatteryRemainingTime(jsonObject.getString("batteryRemainingTime"));
}else{
shareDetailVo.setBatteryPercentage("0");
}
// 获取经度纬度
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);
shareDetailVo.setLongitude(jsonObject.get("longitude").toString());
shareDetailVo.setLatitude(jsonObject.get("latitude").toString());
shareDetailVo.setAddress((String)jsonObject.get("address"));
}
return shareDetailVo; return shareDetailVo;
} }
/** /**
@ -132,4 +211,17 @@ public class AppDeviceShareService {
public int remove(Long[] ids) { public int remove(Long[] ids) {
return appDeviceShareMapper.deleteByIds(Arrays.asList(ids)); return appDeviceShareMapper.deleteByIds(Arrays.asList(ids));
} }
public TableDataInfo<AppDeviceShareVo> otherDeviceShareList(AppDeviceShareBo bo, PageQuery pageQuery) {
String username = AppLoginHelper.getUsername();
bo.setPhonenumber(username);
Page<AppDeviceShareVo> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
IPage<AppDeviceShareVo> result = appDeviceShareMapper.otherDeviceShareList(bo, page);
List<AppDeviceShareVo> records = result.getRecords();
records.forEach(AppDeviceShareService::buildDeviceStatus);
return TableDataInfo.build(result);
}
} }

View File

@ -0,0 +1,388 @@
package com.fuyuanshen.app.service.device;
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.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.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.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.DEVICE_BOOT_LOGO_KEY_PREFIX;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
@Slf4j
@Service
@RequiredArgsConstructor
public class AppDeviceBJQBizService {
private final DeviceMapper deviceMapper;
private final AppPersonnelInfoMapper appPersonnelInfoMapper;
private final DeviceTypeMapper deviceTypeMapper;
private final MqttGateway mqttGateway;
public int sendMessage(AppDeviceSendMsgBo bo) {
List<Long> 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);
}
try {
ClassPathResource resource = new ClassPathResource("image/background.png");
InputStream inputStream = resource.getInputStream();
// String backgroundImagePath = "D:\\background.png"; // 替换为实际背景图片路径
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(30 * 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);
// log.info("第0块数据: {}", Arrays.toString(specificChunk));
ArrayList<Integer> 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<String, Object> 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<Device> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", deviceId)
.eq("binding_user_id", AppLoginHelper.getUserId())
.set("send_msg", bo.getSendMsg());
deviceMapper.update(updateWrapper);
} catch (Exception e) {
log.info("发送信息设备发送信息失败:{}" ,deviceId);
}
}
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<AppPersonnelInfo> qw = new QueryWrapper<AppPersonnelInfo>()
.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(StringUtils.isNotBlank(onlineStatus)){
vo.setOnlineStatus(1);
}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 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"));
}
return vo;
}
public boolean registerPersonInfo(AppPersonnelInfoBo bo) {
Long deviceId = bo.getDeviceId();
Device deviceObj = deviceMapper.selectById(deviceId);
if (deviceObj == null) {
throw new RuntimeException("请先将设备入库!!!");
}
QueryWrapper<AppPersonnelInfo> qw = new QueryWrapper<AppPersonnelInfo>()
.eq("device_id", deviceId);
List<AppPersonnelInfoVo> 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<Integer> 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<String, Object> 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<AppPersonnelInfo> 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);
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(30 * 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<Integer> 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<String, Object> 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<Integer> intData = new ArrayList<>();
intData.add(1);
intData.add(instructValue);
intData.add(0);
intData.add(0);
intData.add(0);
Map<String, Object> 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<Integer> 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<String, Object> 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<Integer> intData = new ArrayList<>();
intData.add(4);
intData.add(instructValue);
intData.add(0);
intData.add(0);
intData.add(0);
Map<String, Object> 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) {
QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("device_imei", params.getDeviceImei());
List<Device> devices = deviceMapper.selectList(queryWrapper);
if(ObjectUtils.length( devices) ==0){
throw new ServiceException("设备不存在");
}
return RedisUtils.getCacheObject("device:location:" + devices.get(0).getDeviceImei());
}
public int sendAlarmMessage(AppDeviceSendMsgBo bo) {
try {
List<Long> 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);
}
try {
ArrayList<Integer> 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<String, Object> 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<Device> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", deviceId)
.eq("binding_user_id", AppLoginHelper.getUserId())
.set("send_msg", bo.getSendMsg());
deviceMapper.update(updateWrapper);
} catch (Exception e) {
log.info("设备发送信息失败:{}" ,deviceId);
}
}
} catch (Exception e){
e.printStackTrace();
}
return 1;
}
}

View File

@ -4,12 +4,6 @@ import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.handler.annotation.Header; import org.springframework.messaging.handler.annotation.Header;
/**
* @Author: HarryLin
* @Date: 2025/3/20 17:06
* @Company: 北京红山信息科技研究院有限公司
* @Email: linyun@***.com.cn
**/
@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel") @MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
public interface MqttGateway { public interface MqttGateway {
public abstract void sendMsgToMqtt(@Header(value = MqttHeaders.TOPIC) String topic, String payload); public abstract void sendMsgToMqtt(@Header(value = MqttHeaders.TOPIC) String topic, String payload);

View File

@ -1,12 +1,50 @@
package com.fuyuanshen.global.mqtt.constants; package com.fuyuanshen.global.mqtt.constants;
public class DeviceRedisKeyConstants { public class DeviceRedisKeyConstants {
// 将设备上报状态 public static final String DEVICE_KEY_PREFIX = "device:";
public static final String DEVICE_STATUS_KEY_PREFIX = "device:status:"; // 设备上报状态
public static final String DEVICE_STATUS_KEY_PREFIX = ":status";
// 在线状态 // 在线状态
public static final String DEVICE_ONLINE_STATUS_KEY_PREFIX = "device:onlineStatus:"; public static final String DEVICE_ONLINE_STATUS_KEY_PREFIX = ":onlineStatus";
// 设备状态信息存储到Redis中 // 设备状态信息存储到Redis中
public static final String DEVICE_LOCATION_KEY_PREFIX = "device:location:"; public static final String DEVICE_LOCATION_KEY_PREFIX = ":location";
// 存储到一个列表中,保留历史位置信息 // 存储到一个列表中,保留历史位置信息
public static final String DEVICE_LOCATION_HISTORY_KEY_PREFIX = "device:location:history:"; public static final String DEVICE_LOCATION_HISTORY_KEY_PREFIX = ":location:history";
// 存储设备活跃上报信息
public static final String DEVICE_ACTIVE_REPORTING_KEY_PREFIX = ":activeReporting";
// 存储设备人员信息
public static final String DEVICE_PERSONNEL_INFO_KEY_PREFIX = ":personnelInfo";
// 存储设备发送消息
public static final String DEVICE_SEND_MESSAGE_KEY_PREFIX = ":sendMessage";
// 存储设备启动logo
public static final String DEVICE_BOOT_LOGO_KEY_PREFIX = ":bootLogo";
/**
* 灯模式
*/
public static final String DEVICE_LIGHT_MODE_KEY_PREFIX = ":lightMode";
/**
* 亮度模式
*/
public static final String DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX = ":lightBrightness";
/**
* 激光模式
*/
public static final String DEVICE_LASER_MODE_KEY_PREFIX = ":laserMode";
/**
* 地图逆地理编码
*/
public static final String DEVICE_MAP_REVERSE_GEOCODING_KEY_PREFIX = ":mapReverseGeocoding";
/**
* 告警
*/
public static final String DEVICE_ALARM_KEY_PREFIX = ":alarm";
} }

View File

@ -6,12 +6,7 @@ import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.handler.annotation.Header; import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/**
* @Author: HarryLin
* @Date: 2025/3/20 16:16
* @Company: 北京红山信息科技研究院有限公司
* @Email: linyun@***.com.cn
**/
@Service @Service
public class MqttMessageSender { public class MqttMessageSender {
@Autowired @Autowired

View File

@ -20,6 +20,8 @@ import org.springframework.stereotype.Service;
import java.time.Duration; import java.time.Duration;
import java.util.Objects; import java.util.Objects;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
@Service @Service
@Slf4j @Slf4j
public class ReceiverMessageHandler implements MessageHandler { public class ReceiverMessageHandler implements MessageHandler {
@ -46,7 +48,7 @@ public class ReceiverMessageHandler implements MessageHandler {
String deviceImei = subStr[1]; String deviceImei = subStr[1];
if(StringUtils.isNotBlank(deviceImei)){ if(StringUtils.isNotBlank(deviceImei)){
//在线状态 //在线状态
String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + deviceImei; String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ;
RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(60*15)); RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(60*15));
} }

View File

@ -1,22 +1,22 @@
package com.fuyuanshen.global.mqtt.rule; package com.fuyuanshen.global.mqtt.rule.bjq;
import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.json.utils.JsonUtils; import com.fuyuanshen.common.json.utils.JsonUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.global.mqtt.base.MqttMessageRule; import com.fuyuanshen.global.mqtt.base.MqttMessageRule;
import com.fuyuanshen.global.mqtt.base.MqttRuleContext; import com.fuyuanshen.global.mqtt.base.MqttRuleContext;
import com.fuyuanshen.global.mqtt.config.MqttGateway;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants; import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX;
/** /**
* 主动上报设备数据命令处理 * 主动上报设备数据命令处理
* "第1位为12表示设备主动上报设备硬件状态第2为表示当时设备主灯档位第3位表示当时激光灯档位第4位电量百分比第5位为充电状态0没有充电1正在充电2为已充满 * "第1位为12表示设备主动上报设备硬件状态第2为表示当时设备主灯档位第3位表示当时激光灯档位第4位电量百分比第5位为充电状态0没有充电1正在充电2为已充满
@ -25,10 +25,7 @@ import java.util.concurrent.CompletableFuture;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class ActiveReportingDeviceDataRule implements MqttMessageRule { public class BjqActiveReportingDeviceDataRule implements MqttMessageRule {
private final MqttGateway mqttGateway;
@Override @Override
public String getCommandType() { public String getCommandType() {
@ -80,10 +77,10 @@ public class ActiveReportingDeviceDataRule implements MqttMessageRule {
deviceInfo.put("timestamp", System.currentTimeMillis()); deviceInfo.put("timestamp", System.currentTimeMillis());
// 将设备状态信息存储到Redis中 // 将设备状态信息存储到Redis中
String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + deviceImei; String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + deviceImei + DEVICE_STATUS_KEY_PREFIX;
String deviceInfoJson = JsonUtils.toJsonString(deviceInfo); String deviceInfoJson = JsonUtils.toJsonString(deviceInfo);
// 存储到Redis设置过期时间例如24小时 // 存储到Redis
RedisUtils.setCacheObject(deviceRedisKey, deviceInfoJson); RedisUtils.setCacheObject(deviceRedisKey, deviceInfoJson);
log.info("设备状态信息已异步发送到Redis: device={}, mainLightMode={}, laserLightMode={}, batteryPercentage={}", log.info("设备状态信息已异步发送到Redis: device={}, mainLightMode={}, laserLightMode={}, batteryPercentage={}",

View File

@ -0,0 +1,69 @@
package com.fuyuanshen.global.mqtt.rule.bjq;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.StringUtils;
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.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*;
/**
* 灯光模式订阅设备回传消息
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class BjqAlarmRule implements MqttMessageRule {
@Override
public String getCommandType() {
return LightingCommandTypeConstants.LIGHT_MODE;
}
@Override
public void execute(MqttRuleContext context) {
try {
Object[] convertArr = context.getConvertArr();
String mainLightMode = convertArr[1].toString();
if(StringUtils.isNotBlank(mainLightMode)){
// 异步发送设备状态和位置信息到Redis
asyncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),mainLightMode);
}
} catch (Exception e) {
log.error("处理灯光模式命令时出错", e);
}
}
/**
* 异步发送设备状态信息和位置信息到Redis使用CompletableFuture
*
* @param deviceImei 设备IMEI
*/
public void asyncSendDeviceDataToRedisWithFuture(String deviceImei,Object convertValue) {
CompletableFuture.runAsync(() -> {
try {
// 将设备状态信息存储到Redis中
String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + deviceImei + DEVICE_ALARM_KEY_PREFIX;
// 存储到Redis
RedisUtils.setCacheObject(deviceRedisKey, convertValue.toString());
} catch (Exception e) {
log.error("异步发送设备信息到Redis时出错: device={}, error={}", deviceImei, e.getMessage(), e);
}
});
}
}

View File

@ -1,6 +1,5 @@
package com.fuyuanshen.global.mqtt.rule; package com.fuyuanshen.global.mqtt.rule.bjq;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; import com.fuyuanshen.common.core.utils.ImageToCArrayConverter;
import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.json.utils.JsonUtils; import com.fuyuanshen.common.json.utils.JsonUtils;
@ -15,11 +14,13 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY;
import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; 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;
/** /**
* 人员信息命令处理 * 人员信息命令处理
@ -27,7 +28,7 @@ import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHex
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class DeviceBootLogoRule implements MqttMessageRule { public class BjqBootLogoRule implements MqttMessageRule {
private final MqttGateway mqttGateway; private final MqttGateway mqttGateway;
@ -44,14 +45,14 @@ public class DeviceBootLogoRule implements MqttMessageRule {
return; return;
} }
String data = RedisUtils.getCacheObject(GlobalConstants.GLOBAL_REDIS_KEY+"app_logo_data:" + context.getDeviceImei()); String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() +DEVICE_BOOT_LOGO_KEY_PREFIX);
if (StringUtils.isEmpty(data)) { if (StringUtils.isEmpty(data)) {
return; return;
} }
byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data);
byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512);
System.out.println("" + val2 + "块数据大小: " + specificChunk.length + " 字节"); log.info("第{}块数据大小: {} 字节", val2, specificChunk.length);
// System.out.println("" + val2 + "块数据: " + Arrays.toString(specificChunk)); // System.out.println("" + val2 + "块数据: " + Arrays.toString(specificChunk));
ArrayList<Integer> intData = new ArrayList<>(); ArrayList<Integer> intData = new ArrayList<>();
@ -71,7 +72,7 @@ public class DeviceBootLogoRule implements MqttMessageRule {
MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(),
JsonUtils.toJsonString(map)); JsonUtils.toJsonString(map));
} catch (Exception e) { } catch (Exception e) {
log.error("处理人员信息命令时出错", e); log.error("处理开机LOGO时出错", e);
} }
} }
} }

View File

@ -1,6 +1,5 @@
package com.fuyuanshen.global.mqtt.rule; package com.fuyuanshen.global.mqtt.rule.bjq;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.core.utils.StringUtils;
@ -18,20 +17,22 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX;
/** /**
* 定位数据命令处理 * 定位数据命令处理
*/ */
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class LocationDataRule implements MqttMessageRule { public class BjqLocationDataRule implements MqttMessageRule {
private final MqttGateway mqttGateway; private final MqttGateway mqttGateway;
@ -113,7 +114,7 @@ public class LocationDataRule implements MqttMessageRule {
String[] latArr = latitude.split("\\."); String[] latArr = latitude.split("\\.");
String[] lonArr = longitude.split("\\."); String[] lonArr = longitude.split("\\.");
// 将位置信息存储到Redis中 // 将位置信息存储到Redis中
String redisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + deviceImei; String redisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DEVICE_LOCATION_KEY_PREFIX;
String redisObj = RedisUtils.getCacheObject(redisKey); String redisObj = RedisUtils.getCacheObject(redisKey);
JSONObject jsonOBj = JSONObject.parseObject(redisObj); JSONObject jsonOBj = JSONObject.parseObject(redisObj);
if(jsonOBj != null){ if(jsonOBj != null){
@ -169,7 +170,7 @@ public class LocationDataRule implements MqttMessageRule {
*/ */
public void storeDeviceTrajectoryWithSortedSet(String deviceImei, String locationJson) { public void storeDeviceTrajectoryWithSortedSet(String deviceImei, String locationJson) {
try { try {
String trajectoryKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX + deviceImei; String trajectoryKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + deviceImei + DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX;
// String trajectoryKey = "device:trajectory:zset:" + deviceImei; // String trajectoryKey = "device:trajectory:zset:" + deviceImei;
// String locationJson = JsonUtils.toJsonString(locationInfo); // String locationJson = JsonUtils.toJsonString(locationInfo);
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
@ -181,7 +182,7 @@ public class LocationDataRule implements MqttMessageRule {
// RedisUtils.expire(trajectoryKey, Duration.ofDays(30)); // RedisUtils.expire(trajectoryKey, Duration.ofDays(30));
// 清理30天前的数据冗余保护 // 清理30天前的数据冗余保护
long thirtyDaysAgo = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000); long thirtyDaysAgo = System.currentTimeMillis() - (7L * 24 * 60 * 60 * 1000);
RedisUtils.zRemoveRangeByScore(trajectoryKey, 0, thirtyDaysAgo); RedisUtils.zRemoveRangeByScore(trajectoryKey, 0, thirtyDaysAgo);
} catch (Exception e) { } catch (Exception e) {
log.error("存储设备轨迹到Redis(ZSet)失败: device={}, error={}", deviceImei, e.getMessage(), e); log.error("存储设备轨迹到Redis(ZSet)失败: device={}, error={}", deviceImei, e.getMessage(), e);

View File

@ -0,0 +1,75 @@
package com.fuyuanshen.global.mqtt.rule.bjq;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.StringUtils;
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.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_LIGHT_MODE_KEY_PREFIX;
/**
* 灯光模式订阅设备回传消息
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class BjqModeRule implements MqttMessageRule {
@Override
public String getCommandType() {
return LightingCommandTypeConstants.LIGHT_MODE;
}
@Override
public void execute(MqttRuleContext context) {
try {
Object[] convertArr = context.getConvertArr();
String mainLightMode = convertArr[1].toString();
if(StringUtils.isNotBlank(mainLightMode)){
if("0".equals(mainLightMode)){
String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ context.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ;
RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "0", Duration.ofSeconds(60*15));
}
// 异步发送设备状态和位置信息到Redis
asyncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),mainLightMode);
}
} catch (Exception e) {
log.error("处理灯光模式命令时出错", e);
}
}
/**
* 异步发送设备状态信息和位置信息到Redis使用CompletableFuture
*
* @param deviceImei 设备IMEI
*/
public void asyncSendDeviceDataToRedisWithFuture(String deviceImei,Object convertValue) {
CompletableFuture.runAsync(() -> {
try {
// 将设备状态信息存储到Redis中
String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + deviceImei + DEVICE_LIGHT_MODE_KEY_PREFIX;
// 存储到Redis
RedisUtils.setCacheObject(deviceRedisKey, convertValue.toString());
} catch (Exception e) {
log.error("异步发送设备信息到Redis时出错: device={}, error={}", deviceImei, e.getMessage(), e);
}
});
}
}

View File

@ -1,6 +1,5 @@
package com.fuyuanshen.global.mqtt.rule; package com.fuyuanshen.global.mqtt.rule.bjq;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; import com.fuyuanshen.common.core.utils.ImageToCArrayConverter;
import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.json.utils.JsonUtils; import com.fuyuanshen.common.json.utils.JsonUtils;
@ -18,7 +17,9 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY;
import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
/** /**
* 人员信息命令处理 * 人员信息命令处理
@ -26,7 +27,7 @@ import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHex
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class DeviceSendMessageRule implements MqttMessageRule { public class BjqSendMessageRule implements MqttMessageRule {
private final MqttGateway mqttGateway; private final MqttGateway mqttGateway;
@ -43,14 +44,14 @@ public class DeviceSendMessageRule implements MqttMessageRule {
return; return;
} }
String data = RedisUtils.getCacheObject(GlobalConstants.GLOBAL_REDIS_KEY+"app_send_message_data:" + context.getDeviceImei()); String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() + ":app_send_message_data");
if (StringUtils.isEmpty(data)) { if (StringUtils.isEmpty(data)) {
return; return;
} }
byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data);
byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512);
System.out.println("" + val2 + "块数据大小: " + specificChunk.length + " 字节"); log.info("第{}块数据大小: {} 字节", val2, specificChunk.length);
// System.out.println("" + val2 + "块数据: " + Arrays.toString(specificChunk)); // System.out.println("" + val2 + "块数据: " + Arrays.toString(specificChunk));
ArrayList<Integer> intData = new ArrayList<>(); ArrayList<Integer> intData = new ArrayList<>();
@ -70,7 +71,7 @@ public class DeviceSendMessageRule implements MqttMessageRule {
MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(),
JsonUtils.toJsonString(map)); JsonUtils.toJsonString(map));
} catch (Exception e) { } catch (Exception e) {
log.error("处理人员信息命令时出错", e); log.error("处理发送设备信息时出错", e);
} }
} }
} }

View File

@ -1,61 +1,61 @@
package com.fuyuanshen.web.config; //package com.fuyuanshen.web.config;
//
import cn.hutool.core.lang.UUID; //import cn.hutool.core.lang.UUID;
import com.fuyuanshen.global.mqtt.config.MqttPropertiesConfig; //import com.fuyuanshen.global.mqtt.config.MqttPropertiesConfig;
import com.fuyuanshen.web.handler.mqtt.DeviceReceiverMessageHandler; //import com.fuyuanshen.web.handler.mqtt.DeviceReceiverMessageHandler;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; //import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; //import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator; //import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel; //import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer; //import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory; //import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; //import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter; //import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel; //import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler; //import org.springframework.messaging.MessageHandler;
//
/** ///**
* @author: 默苍璃 // * @author: 默苍璃
* @date: 2025-08-0110:46 // * @date: 2025-08-0110:46
*/ // */
@Configuration //@Configuration
public class CustomMqttInboundConfiguration { //public class CustomMqttInboundConfiguration {
//
@Autowired // @Autowired
private MqttPropertiesConfig mqttPropertiesConfig; // private MqttPropertiesConfig mqttPropertiesConfig;
@Autowired // @Autowired
private MqttPahoClientFactory mqttPahoClientFactory; // private MqttPahoClientFactory mqttPahoClientFactory;
@Autowired // @Autowired
private DeviceReceiverMessageHandler deviceReceiverMessageHandler; // private DeviceReceiverMessageHandler deviceReceiverMessageHandler;
//
//
@Bean // @Bean
public MessageChannel customMqttChannel(){ // public MessageChannel customMqttChannel(){
return new DirectChannel(); // return new DirectChannel();
} // }
//
//
@Bean // @Bean
public MessageProducer customMessageProducer(){ // public MessageProducer customMessageProducer(){
String clientId = "custom_client_" + UUID.fastUUID(); // String clientId = "custom_client_" + UUID.fastUUID();
MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter( // MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(
mqttPropertiesConfig.getUrl(), // mqttPropertiesConfig.getUrl(),
clientId, // clientId,
mqttPahoClientFactory, // mqttPahoClientFactory,
"A/#", "B/#" // 直接指定这两个主题 // "A/#", "B/#" // 直接指定这两个主题
); // );
adapter.setQos(1); // adapter.setQos(1);
adapter.setConverter(new DefaultPahoMessageConverter()); // adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setOutputChannel(customMqttChannel()); // adapter.setOutputChannel(customMqttChannel());
return adapter; // return adapter;
} // }
//
//
@Bean // @Bean
@ServiceActivator(inputChannel = "customMqttChannel") // @ServiceActivator(inputChannel = "customMqttChannel")
public MessageHandler customMessageHandler(){ // public MessageHandler customMessageHandler(){
return deviceReceiverMessageHandler; // return deviceReceiverMessageHandler;
} // }
//
} //}

View File

@ -1,318 +1,318 @@
package com.fuyuanshen.web.handler.mqtt; //package com.fuyuanshen.web.handler.mqtt;
//
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; //import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.JsonNode; //import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; //import com.fasterxml.jackson.databind.ObjectMapper;
import com.fuyuanshen.common.satoken.utils.LoginHelper; //import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.equipment.domain.Device; //import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.DeviceLog; //import com.fuyuanshen.equipment.domain.DeviceLog;
import com.fuyuanshen.equipment.mapper.DeviceLogMapper; //import com.fuyuanshen.equipment.mapper.DeviceLogMapper;
import com.fuyuanshen.equipment.mapper.DeviceMapper; //import com.fuyuanshen.equipment.mapper.DeviceMapper;
import com.fuyuanshen.equipment.utils.map.GetAddressFromLatUtil; //import com.fuyuanshen.equipment.utils.map.GetAddressFromLatUtil;
import com.fuyuanshen.equipment.utils.map.LngLonUtil; //import com.fuyuanshen.equipment.utils.map.LngLonUtil;
import com.fuyuanshen.global.mqtt.constants.TenantsConstant; //import com.fuyuanshen.global.mqtt.constants.TenantsConstant;
import com.fuyuanshen.web.enums.InstructType6170; //import com.fuyuanshen.web.enums.InstructType6170;
import com.fuyuanshen.web.enums.LightModeEnum6170; //import com.fuyuanshen.web.enums.LightModeEnum6170;
import lombok.AllArgsConstructor; //import lombok.AllArgsConstructor;
import lombok.Data; //import lombok.Data;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.Message; //import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler; //import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHeaders; //import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException; //import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
//
/** ///**
* 定义监听主题消息的处理器 // * 定义监听主题消息的处理器
* // *
* @author: 默苍璃 // * @author: 默苍璃
* @date: 2025-08-0110:19 // * @date: 2025-08-0110:19
*/ // */
@Component //@Component
@Data //@Data
@AllArgsConstructor //@AllArgsConstructor
@Slf4j //@Slf4j
public class DeviceReceiverMessageHandler implements MessageHandler { //public class DeviceReceiverMessageHandler implements MessageHandler {
//
private final DeviceMapper deviceMapper; // private final DeviceMapper deviceMapper;
private final DeviceLogMapper deviceLogMapper; // private final DeviceLogMapper deviceLogMapper;
//
// 使用Jackson解析JSON // // 使用Jackson解析JSON
private static final ObjectMapper objectMapper = new ObjectMapper(); // private static final ObjectMapper objectMapper = new ObjectMapper();
//
//
/** // /**
* 处理接收的消息 // * 处理接收的消息
* // *
* @param message // * @param message
* @throws MessagingException // * @throws MessagingException
*/ // */
@Override // @Override
public void handleMessage(Message<?> message) throws MessagingException { // public void handleMessage(Message<?> message) throws MessagingException {
// System.out.println("接收到的消息:" + message.getPayload()); // // System.out.println("接收到的消息:" + message.getPayload());
MessageHeaders headers = message.getHeaders(); // MessageHeaders headers = message.getHeaders();
String receivedTopicName = (String) headers.get("mqtt_receivedTopic"); // String receivedTopicName = (String) headers.get("mqtt_receivedTopic");
System.out.println("消息来自主题:" + receivedTopicName); // System.out.println("消息来自主题:" + receivedTopicName);
//
// String tenantId = LoginHelper.getTenantId(); // // String tenantId = LoginHelper.getTenantId();
String tenantId = TenantsConstant.FU_YUAN_SHENG; // String tenantId = TenantsConstant.FU_YUAN_SHENG;
String payload = message.getPayload().toString(); // String payload = message.getPayload().toString();
//
if (receivedTopicName != null) { // if (receivedTopicName != null) {
// 1. 提取设备ID (从主题中获取) // // 1. 提取设备ID (从主题中获取)
String deviceImei = extractDeviceId(receivedTopicName); // String deviceImei = extractDeviceId(receivedTopicName);
Device device = deviceMapper.selectOne(new QueryWrapper<Device>() // Device device = deviceMapper.selectOne(new QueryWrapper<Device>()
.eq("tenant_id", tenantId) // .eq("tenant_id", tenantId)
.eq("device_imei", deviceImei)); // .eq("device_imei", deviceImei));
if (device == null) { // if (device == null) {
log.info("不存在的设备IMEI: {}", deviceImei); // log.info("不存在的设备IMEI: {}", deviceImei);
} else { // } else {
//
try { // try {
JsonNode root = objectMapper.readTree(payload); // JsonNode root = objectMapper.readTree(payload);
//
DeviceLog record = new DeviceLog(); // DeviceLog record = new DeviceLog();
// 手动设置租户ID // // 手动设置租户ID
record.setTenantId(device.getTenantId()); // 从设备信息中获取租户ID // record.setTenantId(device.getTenantId()); // 从设备信息中获取租户ID
// 设备ID // // 设备ID
record.setDeviceId(device.getId()); // record.setDeviceId(device.getId());
// 设备名称 // // 设备名称
record.setDeviceName(device.getDeviceName()); // record.setDeviceName(device.getDeviceName());
//
// 2. 处理instruct消息 // // 2. 处理instruct消息
if (root.has("instruct")) { // if (root.has("instruct")) {
JsonNode instructNode = root.get("instruct"); // JsonNode instructNode = root.get("instruct");
if (instructNode.isArray()) { // if (instructNode.isArray()) {
boolean b = receivedTopicName.startsWith("B/"); // boolean b = receivedTopicName.startsWith("B/");
record = parseInstruct(device, instructNode, b); // record = parseInstruct(device, instructNode, b);
// 根据不同主题进行不同处理 // // 根据不同主题进行不同处理
if (receivedTopicName.startsWith("A/")) { // if (receivedTopicName.startsWith("A/")) {
// 处理A主题的消息设备上传 // // 处理A主题的消息设备上传
record.setDataSource("设备上报"); // record.setDataSource("设备上报");
} else if (receivedTopicName.startsWith("B/")) { // } else if (receivedTopicName.startsWith("B/")) {
// 处理B主题的消息 (手动上传) // // 处理B主题的消息 (手动上传)
record.setDataSource("客户端操作"); // record.setDataSource("客户端操作");
} // }
} // }
// 确保在插入前设置tenantId和deviceId // // 确保在插入前设置tenantId和deviceId
record.setTenantId(device.getTenantId()); // record.setTenantId(device.getTenantId());
record.setDeviceId(device.getId()); // record.setDeviceId(device.getId());
deviceLogMapper.insert(record); // deviceLogMapper.insert(record);
} // }
//
// 2. 处理 state 消息 // // 2. 处理 state 消息
if (root.has("state")) { // if (root.has("state")) {
JsonNode instructNode = root.get("state"); // JsonNode instructNode = root.get("state");
if (instructNode.isArray()) { // if (instructNode.isArray()) {
boolean b = receivedTopicName.startsWith("B/"); // boolean b = receivedTopicName.startsWith("B/");
record = parseState(device, instructNode, b); // record = parseState(device, instructNode, b);
// 根据不同主题进行不同处理 // // 根据不同主题进行不同处理
if (receivedTopicName.startsWith("A/")) { // if (receivedTopicName.startsWith("A/")) {
// 处理A主题的消息设备上传 // // 处理A主题的消息设备上传
record.setDataSource("设备上报"); // record.setDataSource("设备上报");
} else if (receivedTopicName.startsWith("B/")) { // } else if (receivedTopicName.startsWith("B/")) {
// 处理B主题的消息 (手动上传) // // 处理B主题的消息 (手动上传)
record.setDataSource("客户端操作"); // record.setDataSource("客户端操作");
} // }
} // }
// 确保在插入前设置tenantId和deviceId // // 确保在插入前设置tenantId和deviceId
record.setTenantId(device.getTenantId()); // record.setTenantId(device.getTenantId());
record.setDeviceId(device.getId()); // record.setDeviceId(device.getId());
deviceLogMapper.insert(record); // deviceLogMapper.insert(record);
} // }
//
if (root.has("imei")) { // if (root.has("imei")) {
// 设备行为 // // 设备行为
record.setDeviceAction(InstructType6170.fromCode(0).getDescription()); // record.setDeviceAction(InstructType6170.fromCode(0).getDescription());
record.setDataSource("设备上报"); // record.setDataSource("设备上报");
record.setContent("设备启动"); // record.setContent("设备启动");
// 确保在插入前设置tenantId和deviceId // // 确保在插入前设置tenantId和deviceId
record.setTenantId(device.getTenantId()); // record.setTenantId(device.getTenantId());
record.setDeviceId(device.getId()); // record.setDeviceId(device.getId());
deviceLogMapper.insert(record); // deviceLogMapper.insert(record);
} // }
//
//
// 3. 处理state消息 // // 3. 处理state消息
// else if (root.has("state")) { // // else if (root.has("state")) {
// JsonNode stateNode = root.get("state"); // // JsonNode stateNode = root.get("state");
// if (stateNode.isArray()) { // // if (stateNode.isArray()) {
// StateRecord record = parseState(device, stateNode); // // StateRecord record = parseState(device, stateNode);
// stateRepo.save(record); // // stateRepo.save(record);
// } // // }
// } // // }
} catch (Exception e) { // } catch (Exception e) {
log.error("消息解析失败: {}", payload, e); // log.error("消息解析失败: {}", payload, e);
} // }
//
} // }
//
} // }
} // }
//
//
/** // /**
* 从主题中提取设备ID(IMEI) // * 从主题中提取设备ID(IMEI)
* // *
* @param topic // * @param topic
* @return // * @return
*/ // */
private String extractDeviceId(String topic) { // private String extractDeviceId(String topic) {
// 处理 A/# 或 B/# 格式的主题,例如 B/861556078765285 或 A/861556078765285 // // 处理 A/# 或 B/# 格式的主题,例如 B/861556078765285 或 A/861556078765285
String[] segments = topic.split("/"); // String[] segments = topic.split("/");
if (segments.length >= 2) { // if (segments.length >= 2) {
// 返回第二个段,即 / 后面的部分 // // 返回第二个段,即 / 后面的部分
return segments[1]; // return segments[1];
} // }
// 如果格式不符合预期,返回原主题 // // 如果格式不符合预期,返回原主题
return topic; // return topic;
} // }
//
//
/** // /**
* 解析instruct消息 // * 解析instruct消息
* // *
* @param device // * @param device
* @param array // * @param array
* @param b // * @param b
* @return // * @return
*/ // */
private DeviceLog parseInstruct(Device device, JsonNode array, boolean b) { // private DeviceLog parseInstruct(Device device, JsonNode array, boolean b) {
DeviceLog record = new DeviceLog(); // DeviceLog record = new DeviceLog();
record.setDeviceName(device.getDeviceName()); // record.setDeviceName(device.getDeviceName());
// 设备行为 // // 设备行为
record.setDeviceAction(InstructType6170.fromCode(array.get(0).asInt()).getDescription()); // record.setDeviceAction(InstructType6170.fromCode(array.get(0).asInt()).getDescription());
//
switch (array.get(0).asInt()) { // switch (array.get(0).asInt()) {
case 1: // 灯光模式 // case 1: // 灯光模式
LightModeEnum6170 lightModeEnum6170 = LightModeEnum6170.fromCode(array.get(1).asInt()); // LightModeEnum6170 lightModeEnum6170 = LightModeEnum6170.fromCode(array.get(1).asInt());
record.setContent(lightModeEnum6170.getDescription()); // record.setContent(lightModeEnum6170.getDescription());
break; // break;
//
case 2: // 单位/姓名/职位 // case 2: // 单位/姓名/职位
byte[] unitBytes = new byte[480]; // byte[] unitBytes = new byte[480];
for (int i = 1; i <= 480; i++) { // for (int i = 1; i <= 480; i++) {
unitBytes[i - 1] = (byte) array.get(i).asInt(); // unitBytes[i - 1] = (byte) array.get(i).asInt();
} // }
// record.setUnitData(unitBytes); // // record.setUnitData(unitBytes);
break; // break;
//
case 3: // 开机图片 // case 3: // 开机图片
// record.setImagePage(array.get(1).asInt()); // // record.setImagePage(array.get(1).asInt());
byte[] imageBytes = new byte[512]; // byte[] imageBytes = new byte[512];
for (int i = 2; i <= 513; i++) { // for (int i = 2; i <= 513; i++) {
imageBytes[i - 2] = (byte) array.get(i).asInt(); // imageBytes[i - 2] = (byte) array.get(i).asInt();
} // }
// record.setImageData(imageBytes); // // record.setImageData(imageBytes);
break; // break;
//
case 4: // 激光灯 // case 4: // 激光灯
int anInt = array.get(1).asInt(); // int anInt = array.get(1).asInt();
if (anInt == 0) { // if (anInt == 0) {
record.setContent("关闭激光灯"); // record.setContent("关闭激光灯");
} else if (anInt == 1) { // } else if (anInt == 1) {
record.setContent("开启激光灯"); // record.setContent("开启激光灯");
} else { // } else {
record.setContent("未知操作"); // record.setContent("未知操作");
} // }
break; // break;
//
case 5: // 亮度调节 // case 5: // 亮度调节
record.setContent(+array.get(1).asInt() + "%"); // record.setContent(+array.get(1).asInt() + "%");
break; // break;
//
case 11: // 定位数据 // case 11: // 定位数据
if (b) { // if (b) {
break; // break;
} // }
int i1 = array.get(1).asInt(); // int i1 = array.get(1).asInt();
int i2 = array.get(2).asInt(); // int i2 = array.get(2).asInt();
int i3 = array.get(3).asInt(); // int i3 = array.get(3).asInt();
int i4 = array.get(4).asInt(); // int i4 = array.get(4).asInt();
//
// 优雅的转换方式 Longitude and latitude // // 优雅的转换方式 Longitude and latitude
double latitude = i1 + i2 / 10.0; // double latitude = i1 + i2 / 10.0;
double Longitude = i3 + i4 / 10.0; // double Longitude = i3 + i4 / 10.0;
// 84 ==》 高德 // // 84 ==》 高德
double[] doubles = LngLonUtil.gps84_To_Gcj02(latitude, Longitude); // double[] doubles = LngLonUtil.gps84_To_Gcj02(latitude, Longitude);
String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0])); // String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0]));
record.setContent(address); // record.setContent(address);
break; // break;
} // }
return record; // return record;
} // }
//
//
/** // /**
* 解析 state 消息 // * 解析 state 消息
* // *
* @param device // * @param device
* @param array // * @param array
* @return // * @return
*/ // */
private DeviceLog parseState(Device device, JsonNode array, boolean b) { // private DeviceLog parseState(Device device, JsonNode array, boolean b) {
DeviceLog record = new DeviceLog(); // DeviceLog record = new DeviceLog();
record.setDeviceName(device.getDeviceName()); // record.setDeviceName(device.getDeviceName());
// 设备行为 // // 设备行为
record.setDeviceAction(InstructType6170.fromCode(array.get(0).asInt()).getDescription()); // record.setDeviceAction(InstructType6170.fromCode(array.get(0).asInt()).getDescription());
//
switch (array.get(0).asInt()) { // switch (array.get(0).asInt()) {
case 1: // 灯光模式 // case 1: // 灯光模式
LightModeEnum6170 lightModeEnum6170 = LightModeEnum6170.fromCode(array.get(1).asInt()); // LightModeEnum6170 lightModeEnum6170 = LightModeEnum6170.fromCode(array.get(1).asInt());
record.setContent(lightModeEnum6170.getDescription()); // record.setContent(lightModeEnum6170.getDescription());
break; // break;
//
case 2: // 单位/姓名/职位 // case 2: // 单位/姓名/职位
byte[] unitBytes = new byte[480]; // byte[] unitBytes = new byte[480];
for (int i = 1; i <= 480; i++) { // for (int i = 1; i <= 480; i++) {
unitBytes[i - 1] = (byte) array.get(i).asInt(); // unitBytes[i - 1] = (byte) array.get(i).asInt();
} // }
// record.setUnitData(unitBytes); // // record.setUnitData(unitBytes);
break; // break;
//
case 3: // 开机图片 // case 3: // 开机图片
// record.setImagePage(array.get(1).asInt()); // // record.setImagePage(array.get(1).asInt());
byte[] imageBytes = new byte[512]; // byte[] imageBytes = new byte[512];
for (int i = 2; i <= 513; i++) { // for (int i = 2; i <= 513; i++) {
imageBytes[i - 2] = (byte) array.get(i).asInt(); // imageBytes[i - 2] = (byte) array.get(i).asInt();
} // }
// record.setImageData(imageBytes); // // record.setImageData(imageBytes);
break; // break;
//
case 4: // 激光灯 // case 4: // 激光灯
int anInt = array.get(1).asInt(); // int anInt = array.get(1).asInt();
if (anInt == 0) { // if (anInt == 0) {
record.setContent("关闭激光灯"); // record.setContent("关闭激光灯");
} else if (anInt == 1) { // } else if (anInt == 1) {
record.setContent("开启激光灯"); // record.setContent("开启激光灯");
} else { // } else {
record.setContent("未知操作"); // record.setContent("未知操作");
} // }
break; // break;
//
case 5: // 亮度调节 // case 5: // 亮度调节
record.setContent(+array.get(1).asInt() + "%"); // record.setContent(+array.get(1).asInt() + "%");
break; // break;
//
case 11: // 定位数据 // case 11: // 定位数据
if (b) { // if (b) {
break; // break;
} // }
int i1 = array.get(1).asInt(); // int i1 = array.get(1).asInt();
int i2 = array.get(2).asInt(); // int i2 = array.get(2).asInt();
int i3 = array.get(3).asInt(); // int i3 = array.get(3).asInt();
int i4 = array.get(4).asInt(); // int i4 = array.get(4).asInt();
//
// 优雅的转换方式 Longitude and latitude // // 优雅的转换方式 Longitude and latitude
double latitude = i1 + i2 / 10.0; // double latitude = i1 + i2 / 10.0;
double Longitude = i3 + i4 / 10.0; // double Longitude = i3 + i4 / 10.0;
// 84 ==》 高德 // // 84 ==》 高德
double[] doubles = LngLonUtil.gps84_To_Gcj02(latitude, Longitude); // double[] doubles = LngLonUtil.gps84_To_Gcj02(latitude, Longitude);
String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0])); // String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0]));
record.setContent(address); // record.setContent(address);
break; // break;
} // }
return record; // return record;
} // }
//
} //}

View File

@ -1,163 +1,163 @@
package com.fuyuanshen.web.listener; //package com.fuyuanshen.web.listener;
//
import cn.dev33.satoken.listener.SaTokenListener; //import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.StpUtil; //import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter; //import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.convert.Convert; //import cn.hutool.core.convert.Convert;
import cn.hutool.http.useragent.UserAgent; //import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil; //import cn.hutool.http.useragent.UserAgentUtil;
import lombok.RequiredArgsConstructor; //import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import com.fuyuanshen.common.core.constant.CacheConstants; //import com.fuyuanshen.common.core.constant.CacheConstants;
import com.fuyuanshen.common.core.constant.Constants; //import com.fuyuanshen.common.core.constant.Constants;
import com.fuyuanshen.common.core.domain.dto.UserOnlineDTO; //import com.fuyuanshen.common.core.domain.dto.UserOnlineDTO;
import com.fuyuanshen.common.core.utils.MessageUtils; //import com.fuyuanshen.common.core.utils.MessageUtils;
import com.fuyuanshen.common.core.utils.ServletUtils; //import com.fuyuanshen.common.core.utils.ServletUtils;
import com.fuyuanshen.common.core.utils.SpringUtils; //import com.fuyuanshen.common.core.utils.SpringUtils;
import com.fuyuanshen.common.core.utils.ip.AddressUtils; //import com.fuyuanshen.common.core.utils.ip.AddressUtils;
import com.fuyuanshen.common.log.event.LogininforEvent; //import com.fuyuanshen.common.log.event.LogininforEvent;
import com.fuyuanshen.common.redis.utils.RedisUtils; //import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.common.satoken.utils.LoginHelper; //import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.common.tenant.helper.TenantHelper; //import com.fuyuanshen.common.tenant.helper.TenantHelper;
import com.fuyuanshen.web.service.SysLoginService; //import com.fuyuanshen.web.service.SysLoginService;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
//
import java.time.Duration; //import java.time.Duration;
//
/** ///**
* 用户行为 侦听器的实现 // * 用户行为 侦听器的实现
* // *
* @author Lion Li // * @author Lion Li
*/ // */
@RequiredArgsConstructor //@RequiredArgsConstructor
@Component //@Component
@Slf4j //@Slf4j
public class UserActionListener implements SaTokenListener { //public class UserActionListener implements SaTokenListener {
//
private final SysLoginService loginService; // private final SysLoginService loginService;
//
/** // /**
* 每次登录时触发 // * 每次登录时触发
*/ // */
@Override // @Override
public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginParameter loginParameter) { // public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginParameter loginParameter) {
UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); // UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = ServletUtils.getClientIP(); // String ip = ServletUtils.getClientIP();
UserOnlineDTO dto = new UserOnlineDTO(); // UserOnlineDTO dto = new UserOnlineDTO();
dto.setIpaddr(ip); // dto.setIpaddr(ip);
dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); // dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
dto.setBrowser(userAgent.getBrowser().getName()); // dto.setBrowser(userAgent.getBrowser().getName());
dto.setOs(userAgent.getOs().getName()); // dto.setOs(userAgent.getOs().getName());
dto.setLoginTime(System.currentTimeMillis()); // dto.setLoginTime(System.currentTimeMillis());
dto.setTokenId(tokenValue); // dto.setTokenId(tokenValue);
String username = (String) loginParameter.getExtra(LoginHelper.USER_NAME_KEY); // String username = (String) loginParameter.getExtra(LoginHelper.USER_NAME_KEY);
String tenantId = (String) loginParameter.getExtra(LoginHelper.TENANT_KEY); // String tenantId = (String) loginParameter.getExtra(LoginHelper.TENANT_KEY);
dto.setUserName(username); // dto.setUserName(username);
dto.setClientKey((String) loginParameter.getExtra(LoginHelper.CLIENT_KEY)); // dto.setClientKey((String) loginParameter.getExtra(LoginHelper.CLIENT_KEY));
dto.setDeviceType(loginParameter.getDeviceType()); // dto.setDeviceType(loginParameter.getDeviceType());
dto.setDeptName((String) loginParameter.getExtra(LoginHelper.DEPT_NAME_KEY)); // dto.setDeptName((String) loginParameter.getExtra(LoginHelper.DEPT_NAME_KEY));
TenantHelper.dynamic(tenantId, () -> { // TenantHelper.dynamic(tenantId, () -> {
if(loginParameter.getTimeout() == -1) { // if(loginParameter.getTimeout() == -1) {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); // RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto);
} else { // } else {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(loginParameter.getTimeout())); // RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(loginParameter.getTimeout()));
} // }
}); // });
// 记录登录日志 // // 记录登录日志
LogininforEvent logininforEvent = new LogininforEvent(); // LogininforEvent logininforEvent = new LogininforEvent();
logininforEvent.setTenantId(tenantId); // logininforEvent.setTenantId(tenantId);
logininforEvent.setUsername(username); // logininforEvent.setUsername(username);
logininforEvent.setStatus(Constants.LOGIN_SUCCESS); // logininforEvent.setStatus(Constants.LOGIN_SUCCESS);
logininforEvent.setMessage(MessageUtils.message("user.login.success")); // logininforEvent.setMessage(MessageUtils.message("user.login.success"));
logininforEvent.setRequest(ServletUtils.getRequest()); // logininforEvent.setRequest(ServletUtils.getRequest());
SpringUtils.context().publishEvent(logininforEvent); // SpringUtils.context().publishEvent(logininforEvent);
// 更新登录信息 // // 更新登录信息
loginService.recordLoginInfo((Long) loginParameter.getExtra(LoginHelper.USER_KEY), ip); // loginService.recordLoginInfo((Long) loginParameter.getExtra(LoginHelper.USER_KEY), ip);
log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); // log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
} // }
//
/** // /**
* 每次注销时触发 // * 每次注销时触发
*/ // */
@Override // @Override
public void doLogout(String loginType, Object loginId, String tokenValue) { // public void doLogout(String loginType, Object loginId, String tokenValue) {
String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); // String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY));
TenantHelper.dynamic(tenantId, () -> { // TenantHelper.dynamic(tenantId, () -> {
RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); // RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
}); // });
log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue); // log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
} // }
//
/** // /**
* 每次被踢下线时触发 // * 每次被踢下线时触发
*/ // */
@Override // @Override
public void doKickout(String loginType, Object loginId, String tokenValue) { // public void doKickout(String loginType, Object loginId, String tokenValue) {
String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); // String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY));
TenantHelper.dynamic(tenantId, () -> { // TenantHelper.dynamic(tenantId, () -> {
RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); // RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
}); // });
log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue); // log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue);
} // }
//
/** // /**
* 每次被顶下线时触发 // * 每次被顶下线时触发
*/ // */
@Override // @Override
public void doReplaced(String loginType, Object loginId, String tokenValue) { // public void doReplaced(String loginType, Object loginId, String tokenValue) {
String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); // String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY));
TenantHelper.dynamic(tenantId, () -> { // TenantHelper.dynamic(tenantId, () -> {
RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); // RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
}); // });
log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue); // log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue);
} // }
//
/** // /**
* 每次被封禁时触发 // * 每次被封禁时触发
*/ // */
@Override // @Override
public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) { // public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
} // }
//
/** // /**
* 每次被解封时触发 // * 每次被解封时触发
*/ // */
@Override // @Override
public void doUntieDisable(String loginType, Object loginId, String service) { // public void doUntieDisable(String loginType, Object loginId, String service) {
} // }
//
/** // /**
* 每次打开二级认证时触发 // * 每次打开二级认证时触发
*/ // */
@Override // @Override
public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) { // public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
} // }
//
/** // /**
* 每次创建Session时触发 // * 每次创建Session时触发
*/ // */
@Override // @Override
public void doCloseSafe(String loginType, String tokenValue, String service) { // public void doCloseSafe(String loginType, String tokenValue, String service) {
} // }
//
/** // /**
* 每次创建Session时触发 // * 每次创建Session时触发
*/ // */
@Override // @Override
public void doCreateSession(String id) { // public void doCreateSession(String id) {
} // }
//
/** // /**
* 每次注销Session时触发 // * 每次注销Session时触发
*/ // */
@Override // @Override
public void doLogoutSession(String id) { // public void doLogoutSession(String id) {
} // }
//
/** // /**
* 每次Token续期时触发 // * 每次Token续期时触发
*/ // */
@Override // @Override
public void doRenewTimeout(String tokenValue, Object loginId, long timeout) { // public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
} // }
} //}

View File

@ -4,7 +4,7 @@ spring.servlet.multipart.location: /fys/server/temp
--- # 监控中心配置 --- # 监控中心配置
spring.boot.admin.client: spring.boot.admin.client:
# 增加客户端开关 # 增加客户端开关
enabled: true enabled: false
url: http://localhost:9090/admin url: http://localhost:9090/admin
instance: instance:
service-host-type: IP service-host-type: IP
@ -16,7 +16,7 @@ spring.boot.admin.client:
--- # snail-job 配置 --- # snail-job 配置
snail-job: snail-job:
enabled: true enabled: false
# 需要在 SnailJob 后台组管理创建对应名称的组,然后创建任务的时候选择对应的组,才能正确分派任务 # 需要在 SnailJob 后台组管理创建对应名称的组,然后创建任务的时候选择对应的组,才能正确分派任务
group: "fys_group" group: "fys_group"
# SnailJob 接入验证令牌 详见 script/sql/ry_job.sql `sj_group_config`表 # SnailJob 接入验证令牌 详见 script/sql/ry_job.sql `sj_group_config`表
@ -52,9 +52,9 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://localhost:3306/fys_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true url: jdbc:mysql://47.120.79.150:3306/fys-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root username: root
password: Jz_5623_cl1 password: Jq_123456#
# # 从库数据源 # # 从库数据源
# slave: # slave:
# lazy: true # lazy: true
@ -101,13 +101,13 @@ spring:
spring.data: spring.data:
redis: redis:
# 地址 # 地址
host: localhost host: 47.120.79.150
# 端口默认为6379 # 端口默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
database: 1 database: 1
# redis 密码必须配置 # redis 密码必须配置
password: re_fs_11520631 password: xhYc_djkl382^#780!
# 连接超时时间 # 连接超时时间
timeout: 10s timeout: 10s
# 是否开启ssl # 是否开启ssl
@ -177,11 +177,14 @@ sms:
# 框架定义的厂商名称标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分 # 框架定义的厂商名称标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分
supplier: alibaba supplier: alibaba
# 有些称为accessKey有些称之为apiKey也有称为sdkKey或者appId。 # 有些称为accessKey有些称之为apiKey也有称为sdkKey或者appId。
access-key-id: 您的accessKey access-key-id: LTAI5tJdDNpZootsPQ5hdELx
# 称为accessSecret有些称之为apiSecret # 称为accessSecret有些称之为apiSecret
access-key-secret: 您的accessKeySecret access-key-secret: mU4WtffcCXpHPz5tLwQpaGtLsJXONt
signature: 您的短信签名 #模板ID 非必须配置如果使用sendMessage的快速发送需此配置
sdk-app-id: 您的sdkAppId template-id: SMS_322180518
#模板变量 上述模板的变量
templateName: code
signature: 湖北星汉研创科技
config2: config2:
# 厂商标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分 # 厂商标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分
supplier: tencent supplier: tencent
@ -280,8 +283,8 @@ mqtt:
password: #YtvpSfCNG password: #YtvpSfCNG
url: tcp://47.120.79.150:2883 url: tcp://47.120.79.150:2883
subClientId: fys_subClient subClientId: fys_subClient
subTopic: worker/alert/#,worker/location/# subTopic: A/#,B/#,worker/location/#
pubTopic: worker/location pubTopic: B/#
pubClientId: fys_pubClient pubClientId: fys_pubClient

View File

@ -99,4 +99,9 @@ public class AppDeviceDetailVo {
// 逆解析地址 // 逆解析地址
private String address; private String address;
/**
* 告警状态(0解除告警1告警)
*/
private String alarmStatus;
} }

View File

@ -104,4 +104,38 @@ public class AppDeviceShareDetailVo implements Serializable {
* 发送信息 * 发送信息
*/ */
private String sendMsg; private String sendMsg;
//设备主灯档位
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;
} }

View File

@ -57,6 +57,12 @@ public class AppDeviceShareVo implements Serializable {
@ExcelProperty(value = "手机号") @ExcelProperty(value = "手机号")
private String phonenumber; private String phonenumber;
/**
* 他人分享手机号
*/
@ExcelProperty(value = "手机号")
private String otherPhonenumber;
/** /**
* 功能权限1灯光模式2激光模式3开机画面4人员信息登记5发送信息6产品信息 * 功能权限1灯光模式2激光模式3开机画面4人员信息登记5发送信息6产品信息
以逗号分隔 以逗号分隔
@ -73,4 +79,29 @@ public class AppDeviceShareVo implements Serializable {
// 设备图片 // 设备图片
private String devicePic; private String devicePic;
/**
* 在线状态(0离线1在线)
*/
private Integer onlineStatus;
/**
* 电量 百分比
*/
private String battery;
/**
* 纬度
*/
private String latitude;
/**
* 经度
*/
private String longitude;
/**
* 告警状态(0解除告警1告警)
*/
private String alarmStatus;
} }

View File

@ -1,5 +1,6 @@
package com.fuyuanshen.app.mapper; package com.fuyuanshen.app.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fuyuanshen.app.domain.AppDeviceShare; import com.fuyuanshen.app.domain.AppDeviceShare;
@ -16,4 +17,6 @@ import org.apache.ibatis.annotations.Param;
*/ */
public interface AppDeviceShareMapper extends BaseMapperPlus<AppDeviceShare, AppDeviceShareVo> { public interface AppDeviceShareMapper extends BaseMapperPlus<AppDeviceShare, AppDeviceShareVo> {
IPage<AppDeviceShareVo> otherDeviceShareList(@Param("bo") AppDeviceShareBo bo, Page<AppDeviceShareVo> page); IPage<AppDeviceShareVo> otherDeviceShareList(@Param("bo") AppDeviceShareBo bo, Page<AppDeviceShareVo> page);
Page<AppDeviceShareVo> selectAppDeviceShareList(@Param("bo") AppDeviceShareBo bo,Page<AppDeviceShareVo> page);
} }

View File

@ -5,6 +5,47 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<mapper namespace="com.fuyuanshen.app.mapper.AppDeviceShareMapper"> <mapper namespace="com.fuyuanshen.app.mapper.AppDeviceShareMapper">
<select id="otherDeviceShareList" resultType="com.fuyuanshen.app.domain.vo.AppDeviceShareVo"> <select id="otherDeviceShareList" resultType="com.fuyuanshen.app.domain.vo.AppDeviceShareVo">
SELECT * FROM app_device_share a where a.phonenumber = #{bo.phonenumber} select d.device_name, d.device_name,
d.device_name,
d.device_mac,
d.device_sn,
d.device_imei,
d.device_pic,
dt.type_name,
dt.communication_mode,
d.bluetooth_name,
c.binding_time,
ad.*,u.user_name otherPhonenumber
from
app_device_share ad
left join device d on ad.device_id = d.id
left join app_user u on ad.create_by = u.user_id
inner join device_type dt on d.device_type = dt.id
inner join app_device_bind_record c on d.id = c.device_id
where ad.phonenumber = #{bo.phonenumber}
</select>
<select id="selectAppDeviceShareList" resultType="com.fuyuanshen.app.domain.vo.AppDeviceShareVo">
select d.device_name, d.device_name,
d.device_name,
d.device_mac,
d.device_sn,
d.device_imei,
d.device_pic,
dt.type_name,
dt.communication_mode,
d.bluetooth_name,
c.binding_time,
ad.*,u.user_name otherPhonenumber
from
app_device_share ad
left join device d on ad.device_id = d.id
left join app_user u on ad.create_by = u.user_id
inner join device_type dt on d.device_type = dt.id
inner join app_device_bind_record c on d.id = c.device_id
where ad.create_by = #{bo.createBy}
<if test="bo.deviceId != null">
and ad.device_id = #{bo.deviceId}
</if>
</select> </select>
</mapper> </mapper>

View File

@ -76,4 +76,9 @@ public class AppDeviceVo implements Serializable {
* 经度 * 经度
*/ */
private String longitude; private String longitude;
/**
* 告警状态(0解除告警1告警)
*/
private String alarmStatus;
} }