Merge pull request 'feat(device): 新增设备类型查询与设备添加功能' (#14) from liwenlong/fys-Multi-tenant:jingquan into jingquan
Reviewed-on: #14
This commit is contained in:
@ -9,15 +9,24 @@ import com.fuyuanshen.common.log.annotation.Log;
|
||||
import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation;
|
||||
import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessBatcAnnotation;
|
||||
import com.fuyuanshen.common.web.core.BaseController;
|
||||
import com.fuyuanshen.customer.mapper.CustomerMapper;
|
||||
import com.fuyuanshen.equipment.domain.DeviceType;
|
||||
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo;
|
||||
import com.fuyuanshen.equipment.domain.form.DeviceForm;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.equipment.service.DeviceService;
|
||||
import com.fuyuanshen.equipment.service.DeviceTypeService;
|
||||
import com.fuyuanshen.web.domain.Dto.DeviceXinghanInstructDto;
|
||||
import com.fuyuanshen.web.service.device.DeviceBJQBizService;
|
||||
import com.fuyuanshen.web.service.device.DeviceXinghanBizService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* HBY670设备控制类
|
||||
*/
|
||||
@ -28,6 +37,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
public class AppDeviceXinghanController extends BaseController {
|
||||
|
||||
private final DeviceXinghanBizService appDeviceService;
|
||||
private final DeviceService deviceService;
|
||||
/**
|
||||
* 人员信息登记
|
||||
*/
|
||||
@ -113,4 +123,23 @@ public class AppDeviceXinghanController extends BaseController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@GetMapping(value = "/typeAll")
|
||||
@Operation(summary = "查询所有设备类型")
|
||||
public R<List<DeviceType>> queryDeviceTypes() {
|
||||
List<DeviceType> deviceTypes = appDeviceService.queryDeviceTypes();
|
||||
return R.ok(deviceTypes);
|
||||
}
|
||||
|
||||
// @Log("新增设备")
|
||||
@Operation(summary = "新增设备")
|
||||
@PostMapping(value = "/add")
|
||||
public R<Void> addDevice(@RequestBody DeviceForm deviceForm) {
|
||||
try {
|
||||
appDeviceService.addDevice(deviceForm);
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ public class XinghanBootLogoRule implements MqttMessageRule {
|
||||
|
||||
// --- 去重 START ---
|
||||
String dedupKey = "xd:MSG:LOGO:" + ctx.getDeviceImei() + ":" + respText;
|
||||
boolean first = RedisUtils.setObjectIfAbsent(dedupKey, "1", Duration.ofSeconds(10));
|
||||
boolean first = RedisUtils.setObjectIfAbsent(dedupKey, "1", Duration.ofSeconds(3));
|
||||
if (!first) {
|
||||
log.warn("重复消息丢弃 {}", dedupKey);
|
||||
return;
|
||||
|
||||
@ -57,7 +57,7 @@ public class XinghanSendAlarmMessageRule implements MqttMessageRule {
|
||||
log.info("设备上报紧急通知握手: {} ", respText);
|
||||
// --- 去重 START ---
|
||||
String dedupKey = "xd:ALARM:dedup:" + ctx.getDeviceImei() + ":" + respText;
|
||||
boolean first = RedisUtils.setObjectIfAbsent(dedupKey, "1", Duration.ofSeconds(10));
|
||||
boolean first = RedisUtils.setObjectIfAbsent(dedupKey, "1", Duration.ofSeconds(3));
|
||||
if (!first) {
|
||||
log.warn("重复消息丢弃 {}", dedupKey);
|
||||
return;
|
||||
|
||||
@ -57,7 +57,7 @@ public class XinghanSendMsgRule implements MqttMessageRule {
|
||||
|
||||
// --- 去重 START ---
|
||||
String dedupKey = "xd:MSG:dedup:" + ctx.getDeviceImei() + ":" + respText;
|
||||
boolean first = RedisUtils.setObjectIfAbsent(dedupKey, "1", Duration.ofSeconds(10));
|
||||
boolean first = RedisUtils.setObjectIfAbsent(dedupKey, "1", Duration.ofSeconds(3));
|
||||
if (!first) {
|
||||
log.warn("重复消息丢弃 {}", dedupKey);
|
||||
return;
|
||||
|
||||
@ -61,7 +61,7 @@ public class DeviceDebugController extends BaseController {
|
||||
@Log(title = "批量上传文件")
|
||||
@PostMapping("/addFile")
|
||||
public R<Void> uploadFile(@Validated @ModelAttribute AppFileDto bo) throws IOException {
|
||||
return toAjax(deviceDebugService.addFileHash(bo));
|
||||
return toAjax(deviceDebugService.addFileHash(bo,true));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,7 +113,7 @@ public class DeviceDebugController extends BaseController {
|
||||
appFileDto.setDeviceIds(new Long[]{ bo.getDeviceId() });
|
||||
appFileDto.setFileType(1L);
|
||||
appFileDto.setFiles(bo.getExplanationFiles());
|
||||
deviceDebugService.addFileHash(appFileDto);
|
||||
deviceDebugService.addFileHash(appFileDto,false);
|
||||
}
|
||||
// 修改上传设备参数
|
||||
if (bo.getParameterFiles() != null) {
|
||||
@ -121,8 +121,9 @@ public class DeviceDebugController extends BaseController {
|
||||
appFileDto.setDeviceIds(new Long[]{ bo.getDeviceId() });
|
||||
appFileDto.setFileType(2L);
|
||||
appFileDto.setFiles(bo.getParameterFiles());
|
||||
deviceDebugService.addFileHash(appFileDto);
|
||||
deviceDebugService.addFileHash(appFileDto,false);
|
||||
}
|
||||
deviceDebugService.delFile(bo.getFileIds());
|
||||
// 修改操作视频
|
||||
if (bo.getVideoUrl().isEmpty()) {
|
||||
AppOperationVideoBo appOperationVideoBo = new AppOperationVideoBo();
|
||||
|
||||
@ -31,4 +31,6 @@ public class DeviceDebugEditDto {
|
||||
* 视频链接
|
||||
*/
|
||||
private String videoUrl;
|
||||
|
||||
private List<Long> fileIds;
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ public class DeviceDebugService {
|
||||
* @throws IOException
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean addFileHash(AppFileDto bo) throws IOException {
|
||||
public Boolean addFileHash(AppFileDto bo,Boolean isBatch) throws IOException {
|
||||
MultipartFile[] files = bo.getFiles();
|
||||
if (files == null || files.length == 0) {
|
||||
throw new ServiceException("请选择要上传的文件");
|
||||
@ -100,7 +100,7 @@ public class DeviceDebugService {
|
||||
if (CollUtil.isEmpty(bizList)) { // 空集合直接返回
|
||||
throw new ServiceException("请选择要上传的文件");
|
||||
}
|
||||
return appBusinessFileService.insertBatch(bizList);
|
||||
return appBusinessFileService.insertBatch(bizList,isBatch);
|
||||
}
|
||||
|
||||
public Boolean addVideoList(AppOperationVideoBo bo){
|
||||
@ -124,6 +124,13 @@ public class DeviceDebugService {
|
||||
}
|
||||
return appOperationVideoService.insertBatch(bizList);
|
||||
}
|
||||
// 删除文件
|
||||
public void delFile(List<Long> ids) {
|
||||
// 3. 删除旧图片
|
||||
if(ids != null){
|
||||
appBusinessFileService.deleteWithValidByIds(ids, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备详情
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.fuyuanshen.web.service.device;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
@ -19,6 +21,10 @@ import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo;
|
||||
import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper;
|
||||
import com.fuyuanshen.app.mapper.AppPersonnelInfoRecordsMapper;
|
||||
import com.fuyuanshen.common.core.constant.GlobalConstants;
|
||||
import com.fuyuanshen.common.core.domain.R;
|
||||
import com.fuyuanshen.common.core.domain.model.AppLoginUser;
|
||||
import com.fuyuanshen.common.core.domain.model.LoginUser;
|
||||
import com.fuyuanshen.common.core.exception.BadRequestException;
|
||||
import com.fuyuanshen.common.core.exception.ServiceException;
|
||||
import com.fuyuanshen.common.core.utils.ImageToCArrayConverter;
|
||||
import com.fuyuanshen.common.core.utils.MapstructUtils;
|
||||
@ -27,20 +33,26 @@ import com.fuyuanshen.common.core.utils.StringUtils;
|
||||
import com.fuyuanshen.common.json.utils.JsonUtils;
|
||||
import com.fuyuanshen.common.redis.utils.RedisUtils;
|
||||
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
|
||||
import com.fuyuanshen.equipment.domain.Device;
|
||||
import com.fuyuanshen.equipment.domain.DeviceLog;
|
||||
import com.fuyuanshen.equipment.domain.DeviceType;
|
||||
import com.fuyuanshen.common.satoken.utils.LoginHelper;
|
||||
import com.fuyuanshen.equipment.domain.*;
|
||||
import com.fuyuanshen.equipment.domain.bo.DeviceAlarmBo;
|
||||
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo;
|
||||
import com.fuyuanshen.equipment.domain.form.DeviceForm;
|
||||
import com.fuyuanshen.equipment.domain.query.DeviceTypeQueryCriteria;
|
||||
import com.fuyuanshen.equipment.enums.DeviceActiveStatusEnum;
|
||||
import com.fuyuanshen.equipment.enums.LightModeEnum;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceLogMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceTypeGrantsMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
|
||||
import com.fuyuanshen.equipment.service.DeviceAssignmentsService;
|
||||
import com.fuyuanshen.equipment.service.IDeviceAlarmService;
|
||||
import com.fuyuanshen.global.mqtt.base.MqttXinghanJson;
|
||||
import com.fuyuanshen.global.mqtt.config.MqttGateway;
|
||||
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
|
||||
import com.fuyuanshen.global.mqtt.constants.MqttConstants;
|
||||
import com.fuyuanshen.system.domain.vo.SysOssVo;
|
||||
import com.fuyuanshen.system.domain.vo.SysRoleVo;
|
||||
import com.fuyuanshen.web.domain.Dto.DeviceDebugLogoUploadDto;
|
||||
import com.fuyuanshen.web.domain.Dto.DeviceXinghanInstructDto;
|
||||
import com.fuyuanshen.web.domain.vo.DeviceXinghanDetailVo;
|
||||
@ -50,17 +62,19 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.equipment.service.impl.DeviceServiceImpl.USER_ID_SEPARATOR;
|
||||
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*;
|
||||
|
||||
@Slf4j
|
||||
@ -75,6 +89,8 @@ public class DeviceXinghanBizService {
|
||||
private final DeviceLogMapper deviceLogMapper;
|
||||
private final AppPersonnelInfoRecordsMapper appPersonnelInfoRecordsMapper;
|
||||
private final IDeviceAlarmService deviceAlarmService;
|
||||
private final DeviceTypeGrantsMapper deviceTypeGrantsMapper;
|
||||
private final DeviceAssignmentsService deviceAssignmentsService;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@ -324,9 +340,9 @@ public class DeviceXinghanBizService {
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add(bo.getUnitName());
|
||||
list.add(bo.getName());
|
||||
list.add(bo.getPosition());
|
||||
list.add(bo.getUnitName());
|
||||
list.add(bo.getCode());
|
||||
RedisUtils.setCacheList(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + deviceObj.getDeviceImei() + ":app_send_message_data", list);
|
||||
RedisUtils.expire(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + deviceObj.getDeviceImei() + ":app_send_message_data", Duration.ofSeconds(5 * 60L));
|
||||
@ -677,4 +693,76 @@ public class DeviceXinghanBizService {
|
||||
return RedisUtils.getCacheObject(deviceOnlineStatusRedisKey)==null;
|
||||
}
|
||||
|
||||
public List<DeviceType> queryDeviceTypes() {
|
||||
DeviceTypeQueryCriteria criteria = new DeviceTypeQueryCriteria();
|
||||
|
||||
return deviceTypeMapper.findAll(criteria);
|
||||
}
|
||||
|
||||
// @Log("新增设备")
|
||||
public void addDevice(DeviceForm deviceForm) {
|
||||
if (deviceForm.getDeviceMac() != null && deviceForm.getBluetoothName() == null) {
|
||||
throw new BadRequestException("请填写蓝牙名称!!!");
|
||||
}
|
||||
|
||||
Device device1 = deviceMapper.selectOne(new QueryWrapper<Device>().eq("device_mac", deviceForm.getDeviceMac()));
|
||||
if (device1 != null) {
|
||||
throw new BadRequestException("设备MAC已存在!!!");
|
||||
}
|
||||
Device device2 = deviceMapper.selectOne(new QueryWrapper<Device>().eq("device_imei", deviceForm.getDeviceImei()));
|
||||
if (device2 != null) {
|
||||
throw new BadRequestException("设备IMEI已存在!!!");
|
||||
}
|
||||
|
||||
DeviceTypeQueryCriteria queryCriteria = new DeviceTypeQueryCriteria();
|
||||
queryCriteria.setDeviceTypeId(deviceForm.getDeviceType());
|
||||
queryCriteria.setCustomerId(LoginHelper.getUserId());
|
||||
DeviceTypeGrants typeGrants = deviceTypeGrantsMapper.selectById(queryCriteria.getDeviceTypeId());
|
||||
if (typeGrants == null) {
|
||||
throw new ServiceException("设备类型不存在!!!");
|
||||
}
|
||||
DeviceType deviceTypes = deviceTypeMapper.selectById(typeGrants.getDeviceTypeId());
|
||||
if (deviceTypes == null) {
|
||||
throw new ServiceException("设备类型不存在!!!");
|
||||
}
|
||||
|
||||
// 转换对象并插入数据库
|
||||
Device device = new Device();
|
||||
|
||||
BeanUtil.copyProperties(deviceForm, device, true);
|
||||
device.setDeviceNo(createDeviceNo());
|
||||
AppLoginUser loginUser = AppLoginHelper.getLoginUser();
|
||||
device.setCurrentOwnerId(loginUser.getUserId());
|
||||
device.setOriginalOwnerId(loginUser.getUserId());
|
||||
device.setCreateByName(loginUser.getNickname());
|
||||
device.setTypeName(deviceTypes.getTypeName());
|
||||
device.setDeviceType(deviceTypes.getId());
|
||||
if (device.getDeviceImei() != null) {
|
||||
device.setPubTopic("A/" + device.getDeviceImei());
|
||||
device.setSubTopic("B/" + device.getDeviceImei());
|
||||
}
|
||||
// 0 未绑定
|
||||
device.setBindingStatus(0);
|
||||
deviceMapper.insert(device);
|
||||
|
||||
// 新增设备类型记录
|
||||
DeviceAssignments assignments = new DeviceAssignments();
|
||||
assignments.setDeviceId(device.getId());
|
||||
assignments.setAssignedAt(LocalDateTime.now());
|
||||
// 分配者
|
||||
assignments.setAssignerId(loginUser.getUserId());
|
||||
assignments.setAssignerName(loginUser.getUsername());
|
||||
// 接收者
|
||||
assignments.setAssigneeId(loginUser.getUserId());
|
||||
assignments.setActive(DeviceActiveStatusEnum.ACTIVE.getCode());
|
||||
String lever = USER_ID_SEPARATOR + loginUser.getUserId();
|
||||
assignments.setLever(lever);
|
||||
deviceAssignmentsService.save(assignments);
|
||||
}
|
||||
|
||||
private String createDeviceNo() {
|
||||
String uuidStr = UUID.fastUUID().toString(); // 获取带 - 的标准格式字符串
|
||||
return uuidStr.replaceAll("-", "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ public interface IAppBusinessFileService {
|
||||
* @param bo 批量新增app业务文件
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertBatch(Collection<AppBusinessFile> bo);
|
||||
Boolean insertBatch(Collection<AppBusinessFile> bo,Boolean isBatch);
|
||||
|
||||
/**
|
||||
* 修改app业务文件
|
||||
|
||||
@ -102,16 +102,18 @@ public class AppBusinessFileServiceImpl implements IAppBusinessFileService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean insertBatch(Collection<AppBusinessFile> bo) {
|
||||
public Boolean insertBatch(Collection<AppBusinessFile> bo,Boolean isBatch) {
|
||||
// 1. 去重后的 businessId 集合
|
||||
List<Long> businessIds = bo.stream()
|
||||
.map(AppBusinessFile::getBusinessId)
|
||||
.distinct()
|
||||
.toList();
|
||||
QueryWrapper<AppBusinessFile> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.in("business_id", businessIds);
|
||||
queryWrapper.eq("file_type", bo.stream().findFirst().orElseThrow().getFileType());
|
||||
baseMapper.delete(queryWrapper);
|
||||
if(isBatch){
|
||||
List<Long> businessIds = bo.stream()
|
||||
.map(AppBusinessFile::getBusinessId)
|
||||
.distinct()
|
||||
.toList();
|
||||
QueryWrapper<AppBusinessFile> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.in("business_id", businessIds);
|
||||
queryWrapper.eq("file_type", bo.stream().findFirst().orElseThrow().getFileType());
|
||||
baseMapper.delete(queryWrapper);
|
||||
}
|
||||
return baseMapper.insertBatch(bo);
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +32,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="criteria.repairPart != null">
|
||||
and dr.repair_part like concat('%', TRIM(#{criteria.repairPart}), '%')
|
||||
</if>
|
||||
<if test="criteria.repairPerson != null">
|
||||
and dr.repair_person like concat('%', TRIM(#{criteria.repairPerson}), '%')
|
||||
</if>
|
||||
<!-- 时间段条件 -->
|
||||
<if test="criteria.repairBeginTime != null">
|
||||
AND dr.repair_time <![CDATA[ >= ]]> #{criteria.repairBeginTime}
|
||||
|
||||
Reference in New Issue
Block a user