Merge remote-tracking branch 'origin/5.X' into 5.X

This commit is contained in:
zzc 2025-03-27 23:02:07 +08:00
commit 9a1e3bfd15
11 changed files with 410 additions and 92 deletions

View File

@ -9,6 +9,7 @@ import com.alibaba.fastjson.JSONObject;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.dromara.common.core.constant.Constants; import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.domain.model.LoginUser;
@ -55,6 +56,7 @@ import java.util.stream.Collectors;
* @date 2024-07-14 * @date 2024-07-14
*/ */
@Validated @Validated
@Log4j2
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/app/device") @RequestMapping("/app/device")
@ -131,6 +133,7 @@ public class EqDeviceController extends BaseController {
*/ */
@GetMapping("/operate") @GetMapping("/operate")
public R<String> operate(EqDeviceCmdBo bo){ public R<String> operate(EqDeviceCmdBo bo){
log.info("设备控制参数 userId{}, equipmentCode{}, operateType{}",bo.getUserId(),bo.getEquipmentCode(),bo.getOperateType());
if (bo.getEquipmentCode() == null) throw new ServiceException("设备编码不能为空"); if (bo.getEquipmentCode() == null) throw new ServiceException("设备编码不能为空");
if (bo.getOperateType() == 0) throw new ServiceException("操作类型不能为0"); if (bo.getOperateType() == 0) throw new ServiceException("操作类型不能为0");
if (bo.getUserId() == null) throw new ServiceException("用户ID不能为空"); if (bo.getUserId() == null) throw new ServiceException("用户ID不能为空");
@ -283,6 +286,8 @@ public class EqDeviceController extends BaseController {
public void saveDeviceLogs(@RequestBody EqEquipmentLogBo eqEquipmentLogBo){ public void saveDeviceLogs(@RequestBody EqEquipmentLogBo eqEquipmentLogBo){
String equipmentName = eqEquipmentLogBo.getEquipmentName(); String equipmentName = eqEquipmentLogBo.getEquipmentName();
Integer status = eqEquipmentLogBo.getStatus(); Integer status = eqEquipmentLogBo.getStatus();
List<String> statusList = Arrays.asList("101", "102", "103", "104", "105", "106", "107", "108", "1", "2", "112", "113");
//设备id查询 //设备id查询
DeviceByDeviceName deviceByNameDto = iotService.apiTenantDevicesByName(equipmentName);//无信息会抛异常 无需判断 DeviceByDeviceName deviceByNameDto = iotService.apiTenantDevicesByName(equipmentName);//无信息会抛异常 无需判断
if (deviceByNameDto==null) throw new RuntimeException("设备不存在"); if (deviceByNameDto==null) throw new RuntimeException("设备不存在");
@ -319,7 +324,8 @@ public class EqDeviceController extends BaseController {
eqEquipmentLogBo.setDayOfWeek(dayOfWeek - 1);// Calendar类中星期日为1星期一为2依此类推 eqEquipmentLogBo.setDayOfWeek(dayOfWeek - 1);// Calendar类中星期日为1星期一为2依此类推
//更新状态 //更新状态
if(!(status==0 ||status==108 ||status==109 ||status==110 ||status==111 ||status==112 ||status==113||status==114||status==500||status==501) ) if (statusList.contains(status.toString()) )
// if(!(status==0 ||status==108 ||status==109 ||status==110 ||status==111 ||status==112 ||status==113||status==114||status==500||status==501) )
{ {
logService.insertByBo(eqEquipmentLogBo); logService.insertByBo(eqEquipmentLogBo);
} }

View File

@ -1,49 +1,30 @@
package org.dromara.web.controller.app; package org.dromara.web.controller.app;
import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.lock.annotation.Lock4j;
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Cache;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.dromara.common.core.constant.Constants; import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
import org.dromara.common.websocket.dto.WebSocketMessageDto; import org.dromara.common.websocket.holder.WebSocketSessionHolder;
import org.dromara.common.websocket.utils.WebSocketUtils;
import org.dromara.system.service.ISysDictTypeService;
import org.dromara.web.config.LastWebSocketParamDto; import org.dromara.web.config.LastWebSocketParamDto;
import org.dromara.web.device.iot.DeviceByDeviceName; import org.dromara.web.device.iot.DeviceByDeviceName;
import org.dromara.web.domain.bo.*; import org.dromara.web.domain.bo.*;
import org.dromara.web.domain.vo.*; import org.dromara.web.domain.vo.*;
import org.dromara.web.service.*; import org.dromara.web.service.*;
import org.dromara.web.utils.WebSocketBusinessHandler; import org.dromara.web.utils.WebSocketBusinessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
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 javax.annotation.Resource; import javax.annotation.Resource;
import java.text.SimpleDateFormat; import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/** /**
* app iot设备业务 * app iot设备业务
@ -51,6 +32,7 @@ import java.util.stream.Collectors;
* @author Lion Li * @author Lion Li
* @date 2024-07-14 * @date 2024-07-14
*/ */
@Log4j2
@Validated @Validated
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@ -141,8 +123,10 @@ public class EqIotDeviceController extends BaseController {
*/ */
@SaIgnore @SaIgnore
@PostMapping("/sendDeviceMsg2") @PostMapping("/sendDeviceMsg2")
public void sendDeviceMsg2(@RequestBody EqEquipmentLogBo eqEquipmentLogBo){ @Lock4j(keys = {"#eqEquipmentLogBo.equipmentName"}, expire = 30000, acquireTimeout = 1000)
String status = eqEquipmentLogBo.getStatus() + ""; public void sendDeviceMsg2(@RequestBody EqEquipmentLogBo eqEquipmentLogBo) throws InterruptedException {
// Thread.sleep(1000);
/*String status = eqEquipmentLogBo.getStatus() + "";
String statusCache = tokenCache.getIfPresent("status"); String statusCache = tokenCache.getIfPresent("status");
if (StringUtils.isEmpty(statusCache)){ if (StringUtils.isEmpty(statusCache)){
tokenCache.put("status",status); tokenCache.put("status",status);
@ -152,7 +136,7 @@ public class EqIotDeviceController extends BaseController {
}else{ }else{
return; return;
} }
} }*/
String equipmentName = eqEquipmentLogBo.getEquipmentName(); String equipmentName = eqEquipmentLogBo.getEquipmentName();
//设备id查询 //设备id查询
DeviceByDeviceName deviceByNameDto = iotService.apiTenantDevicesByName(equipmentName);//无信息会抛异常 无需判断 DeviceByDeviceName deviceByNameDto = iotService.apiTenantDevicesByName(equipmentName);//无信息会抛异常 无需判断
@ -168,12 +152,28 @@ public class EqIotDeviceController extends BaseController {
Long userId = eqEquipmentVo.getUserId(); Long userId = eqEquipmentVo.getUserId();
LoginUser loginUser = new LoginUser(); LoginUser loginUser = new LoginUser();
loginUser.setUserId(userId); loginUser.setUserId(userId);
//小优化 减少不必要查询 后续可以让设备传设备id 减少iot查询 再通过初始redis来映射userId来减少数据库查询
if (!WebSocketSessionHolder.existSession(Long.valueOf("5"+userId.toString().substring(1)))&&!WebSocketSessionHolder.existSession(Long.valueOf("6"+userId.toString().substring(1)))){
log.info("app-Socket-{} 未上线",userId);
return;
}
LastWebSocketParamDto dto = RedisUtils.getCacheObject(Constants.WEBSOCKET_METHOD+loginUser.getUserId()); LastWebSocketParamDto dto = RedisUtils.getCacheObject(Constants.WEBSOCKET_METHOD+loginUser.getUserId());
String param = JSONObject.toJSONString(dto.getBo()); String param = JSONObject.toJSONString(dto.getBo());
if (Constants.METHOD_EQ_DETAIL.equals(dto.getMethod())){ if (Constants.METHOD_EQ_DETAIL.equals(dto.getMethod())){
webSocketBusinessHandler.dealWithDetailMsg(loginUser,param); String redisKey = Constants.METHOD_EQ_DETAIL + userId;
Boolean isSent = RedisUtils.setObjectIfAbsent(redisKey, Constants.METHOD_EQ_DETAIL, Duration.ofMillis(1000));
if (Boolean.TRUE.equals(isSent)) {
webSocketBusinessHandler.dealWithDetailMsg2(loginUser,param,2);
}
}else if (Constants.METHOD_EQ_LIST.equals(dto.getMethod())){ }else if (Constants.METHOD_EQ_LIST.equals(dto.getMethod())){
webSocketBusinessHandler.dealWithListMsg(loginUser,param); String redisKey = Constants.METHOD_EQ_LIST + userId;
Boolean isSent = RedisUtils.setObjectIfAbsent(redisKey, Constants.METHOD_EQ_LIST, Duration.ofMillis(1000));
if (Boolean.TRUE.equals(isSent)) {
webSocketBusinessHandler.dealWithListMsg2(loginUser,param,2);
}
}else{ }else{
System.out.println("无设备信息最新参数"); System.out.println("无设备信息最新参数");
} }

View File

@ -74,19 +74,19 @@ public class EqEquipmentLogBo extends BaseEntity {
* 13.电机维护故障 motorMaintainException * 13.电机维护故障 motorMaintainException
* 14.设备故障 deviceException * 14.设备故障 deviceException
* *
* 101.烟雾报警 * 101.烟雾报警
* 102.红外触发报警 * 102.红外触发报警
* 103.电机运行报警 * 103.电机运行报警
* 104.电机维修报警 * 104.电机维修报警
* 105.非APP开门提醒 * 105.非APP开门提醒
* 106.非APP关门提醒 * 106.非APP关门提醒
* 107.关门故障报警 * 107.关门故障报警
* 108.开门故障报警 * 108.开门故障报警
* 109.开门运行提醒 * 109.开门运行提醒 使用1
* 110.关门运行提醒 * 110.关门运行提醒 使用2
* 111.忘记关门提醒 * 111.忘记关门提醒
* 112.门体手动开启提醒 * 112.门体手动开启提醒
* 113.半开门运行提醒 * 113.半开门运行提醒
* 114.门体停止运行提醒 * 114.门体停止运行提醒
* *
* 500.设备离线 offline * 500.设备离线 offline

View File

@ -0,0 +1,140 @@
package org.dromara.web.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import java.io.Serial;
import java.io.Serializable;
/**
* 设备信息视图对象 eq_equipment
*
* @author zzc
* @date 2024-07-19
*/
@Data
public class EqEquipmentListVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long equipmentId;
/**
* 分布id
*/
@ExcelProperty(value = "分布id")
private Long areaId;
/**
* 设备类型
*/
@ExcelProperty(value = "设备类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "eq_equipment_type")
private Integer type;
/**
* 登录账号
*/
@ExcelProperty(value = "登录账号ID")
private Long userId;
/**
* 设备编码
*/
@ExcelProperty(value = "设备编码")
private String equipmentCode;
/**
* 设备名称
*/
@ExcelProperty(value = "设备名称")
private String equipmentName;
/**
* 离线状态
*/
@ExcelProperty(value = "离线状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "eq_line_status")
private Integer lineStatus;
/**
* //半开门功能开关 false
* //半开门功能开关 true
*/
private Boolean PartOpenSwitch;
/**
* 排序
*/
@ExcelProperty(value = "排序")
private Integer orderNum;
/**
* 设备状态(开合度)
* 0.已关闭
* 10.打开10%
* 20.打开20%
* 30.打开30%
* 40.打开40%
* 50.打开50%
* 60.打开60%
* 70.打开70%
* 80.打开80%
* 90.打开90%
* 100.打开100%
*/
@ExcelProperty(value = "设备状态 设备的打开状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "eq_status_type")
private Integer openStatus;
/**
* 设备状态(开合度)
* 0.已关闭
* 10.打开10%
* 20.打开20%
* 30.打开30%
* 40.打开40%
* 50.打开50%
* 60.打开60%
* 70.打开70%
* 80.打开80%
* 90.打开90%
* 100.打开100%
* 故障状态
*/
private String openStatusText;
/**
* 设备运行状态
* 0.停止中 stop
* 1.关闭中 closing
* 2.开启中 opening
* 11.红外故障 irException
* 12.电机运转故障 motorRunException
* 13.电机维护故障 motorMaintainException
* 14.设备故障 deviceException
*/
@ExcelProperty(value = "设备状态 设备的打开状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "eq_run_status_type")
private Integer runStatus;
/**
* 设备运行状态文本
* 0.停止中 stop
* 1.关闭中 closing
* 2.开启中 openning
* 11.红外故障 irException
* 12.电机运转故障 motorRunException
* 13.电机维护故障 motorMaintainException
* 14.设备故障 deviceException
*/
private String runStatusText;
}

View File

@ -117,7 +117,7 @@ public class EqEquipmentServiceImpl implements IEqEquipmentService {
record.setOpenStatusText( record.setOpenStatusText(
telemetryMsg.getOpenPercentage()==0 telemetryMsg.getOpenPercentage()==0
?MessageUtils.message("openStatus.name0") ?MessageUtils.message("openStatus.name0")
:MessageUtils.message("openStatus.name1")+ telemetryMsg.getOpenPercentage()+"%"); :MessageUtils.message("openStatus.name1"));
//运行状态 //运行状态
record.setRunStatus(garageException ==10?telemetryMsg.getWorkState(): garageException); record.setRunStatus(garageException ==10?telemetryMsg.getWorkState(): garageException);
@ -321,7 +321,7 @@ public class EqEquipmentServiceImpl implements IEqEquipmentService {
result.setOpenStatusText( result.setOpenStatusText(
telemetryMsg.getOpenPercentage()==0 telemetryMsg.getOpenPercentage()==0
?MessageUtils.message("openStatus.name0") ?MessageUtils.message("openStatus.name0")
:MessageUtils.message("openStatus.name1")+ telemetryMsg.getOpenPercentage()+"%"); :MessageUtils.message("openStatus.name1"));
//运行状态 //运行状态
result.setRunStatus(telemetryMsg.getGarageException()==10?telemetryMsg.getWorkState():telemetryMsg.getGarageException()); result.setRunStatus(telemetryMsg.getGarageException()==10?telemetryMsg.getWorkState():telemetryMsg.getGarageException());
@ -476,7 +476,8 @@ public class EqEquipmentServiceImpl implements IEqEquipmentService {
eqVersionBo.setCurrentVersion(currentVersion); eqVersionBo.setCurrentVersion(currentVersion);
eqVersionBo.setLatestVersion(null); eqVersionBo.setLatestVersion(null);
}else{ }else{
eqVersionBo.setNeedUpdate(true); if (StringUtils.isBlank(currentVersion)) throw new RuntimeException("设备无当前OTA版本");
eqVersionBo.setNeedUpdate(!currentVersion.equals(lastOtaPackage.getVersion()));
eqVersionBo.setCurrentVersion(currentVersion); eqVersionBo.setCurrentVersion(currentVersion);
eqVersionBo.setLatestVersion(lastOtaPackage.getVersion()); eqVersionBo.setLatestVersion(lastOtaPackage.getVersion());
} }

View File

@ -1,6 +1,8 @@
package org.dromara.web.utils; package org.dromara.web.utils;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.baomidou.lock.annotation.Lock4j;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.Constants; import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
@ -18,6 +20,7 @@ import org.dromara.web.controller.app.EqHomeController;
import org.dromara.web.domain.bo.EqAppHomeBo; import org.dromara.web.domain.bo.EqAppHomeBo;
import org.dromara.web.domain.bo.EqUserConfigBo; import org.dromara.web.domain.bo.EqUserConfigBo;
import org.dromara.web.domain.vo.EqEquipmentDetailVo; import org.dromara.web.domain.vo.EqEquipmentDetailVo;
import org.dromara.web.domain.vo.EqEquipmentListVo;
import org.dromara.web.domain.vo.EqEquipmentVo; import org.dromara.web.domain.vo.EqEquipmentVo;
import org.dromara.web.domain.vo.EqUserConfigVo; import org.dromara.web.domain.vo.EqUserConfigVo;
import org.dromara.web.service.IEqUserConfigService; import org.dromara.web.service.IEqUserConfigService;
@ -25,6 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -78,21 +82,62 @@ public class WebSocketBusinessHandler implements WebSocketApi {
// EqEquipmentDetailVo data = deviceMsg.getData(); // EqEquipmentDetailVo data = deviceMsg.getData();
sendMsg = JsonUtils.toJsonString(deviceMsg); sendMsg = JsonUtils.toJsonString(deviceMsg);
log.info("socket详情发送{}",sendMsg); log.info("socket详情发送{}",sendMsg);
sendMsg(sendMsg, userId); // sendMsg(sendMsg, userId);
sendMsg(sendMsg, Long.valueOf("5"+userId.toString().substring(1)));
}
@Lock4j(keys = {"#loginUser.userId"}, expire = 2000, acquireTimeout = 1000)
@Override
public void dealWithDetailMsg2(LoginUser loginUser, String msg,int type) {
EqAppHomeBo bo = null;
String sendMsg = "";
R<EqEquipmentDetailVo> deviceMsg = null;
boolean isTrue = true;
Long userId = loginUser.getUserId();
try {
initLanguage(userId);
bo = JSON.parseObject(msg, EqAppHomeBo.class);
LastWebSocketParamDto dto = new LastWebSocketParamDto();
dto.setMethod(Constants.METHOD_EQ_DETAIL);
dto.setBo(bo);
RedisUtils.setCacheObject(Constants.WEBSOCKET_METHOD+ userId,dto);
} catch (Exception e) {
log.error("参数错误");
isTrue = false;
deviceMsg = R.fail("参数错误:"+e.getMessage());
}
if (isTrue){
try {
deviceMsg = controller.getDeviceMsg(bo);
} catch (Exception e) {
deviceMsg = R.fail("设备详情获取失败:"+e.getMessage());
log.error("设备详情获取失败");
}
}
// EqEquipmentDetailVo data = deviceMsg.getData();
sendMsg = JsonUtils.toJsonString(deviceMsg);
log.info("socket详情发送{}",sendMsg);
// sendMsg(sendMsg, userId);
sendMsg(sendMsg, Long.valueOf("5"+userId.toString().substring(1)));
} }
private void initLanguage(Long userId) { private void initLanguage(Long userId) {
EqUserConfigBo userConfigBo = new EqUserConfigBo(); synchronized (this){
userConfigBo.setUserId(userId); EqUserConfigBo userConfigBo = new EqUserConfigBo();
List<EqUserConfigVo> eqUserConfigVos = userConfigService.queryList(userConfigBo); userConfigBo.setUserId(userId);
if(!eqUserConfigVos.isEmpty()){ List<EqUserConfigVo> eqUserConfigVos = userConfigService.queryList(userConfigBo);
EqUserConfigVo eqUserConfigVo = eqUserConfigVos.get(0); if(!eqUserConfigVos.isEmpty()){
String languageType = eqUserConfigVo.getLanguageType(); EqUserConfigVo eqUserConfigVo = eqUserConfigVos.get(0);
String[] languages = languageType.split("_"); String languageType = eqUserConfigVo.getLanguageType();
LocaleContextHolder.setDefaultLocale(new Locale(languages[0], languages[1])); String[] languages = languageType.split("_");
// LocaleContextHolder.setDefaultLocale(new Locale(languages[0], languages[1]));
LocaleContextHolder.setLocale(new Locale(languages[0], languages[1]));
// 从HTTP请求中获取Locale
}
} }
} }
@Override @Override
public void dealWithListMsg(LoginUser loginUser, String msg) { public void dealWithListMsg(LoginUser loginUser, String msg) {
EqAppHomeBo bo = null; EqAppHomeBo bo = null;
@ -126,7 +171,93 @@ public class WebSocketBusinessHandler implements WebSocketApi {
} }
sendMsg = isTure? JsonUtils.toJsonString(list):sendMsg; sendMsg = isTure? JsonUtils.toJsonString(list):sendMsg;
log.info("socket列表发送{}",sendMsg); log.info("socket列表发送{}",sendMsg);
sendMsg(sendMsg, userId); // sendMsg(sendMsg, userId);
sendMsg(sendMsg, Long.valueOf("6"+userId.toString().substring(1)));
}
@Lock4j(keys = {"#loginUser.userId"}, expire = 2000, acquireTimeout = 1000)
@Override
public void dealWithListMsg2(LoginUser loginUser, String msg, int type) {
EqAppHomeBo bo = null;
String sendMsg = "";
boolean isTure = true;
Long userId = loginUser.getUserId();
try {
initLanguage(userId);
bo = JSON.parseObject(msg, EqAppHomeBo.class);
LastWebSocketParamDto dto = new LastWebSocketParamDto();
dto.setMethod(Constants.METHOD_EQ_LIST);
dto.setBo(bo);
RedisUtils.setCacheObject(Constants.WEBSOCKET_METHOD + userId,dto);
} catch (Exception e) {
log.error("参数错误");
sendMsg = "参数错误";
isTure = false;
}
TableDataInfo<EqEquipmentVo> list = null;
boolean canSendFlag = false;
if (isTure){
PageQuery pageQuery = new PageQuery();
pageQuery.setPageNum(0);
pageQuery.setPageSize(100);
try {
list = homeController.listForWebSocket(bo, pageQuery,loginUser);
canSendFlag = true;
/* zc 去除去重
if (type == 1){
canSendFlag = true;
}else{
String key = userId + "_" + Constants.METHOD_EQ_LIST;
List<EqEquipmentVo> rows = list.getRows();
List<EqEquipmentListVo> currentVoList = new ArrayList<>();
if (rows !=null && !rows.isEmpty()){
currentVoList = BeanUtil.copyToList(rows, EqEquipmentListVo.class);
if (RedisUtils.hasKey(key)){
List<EqEquipmentListVo> cacheList = RedisUtils.getCacheList(key);
for (EqEquipmentListVo cacheVo : cacheList) {
for (EqEquipmentListVo currentVo : currentVoList) {
if (cacheVo.getEquipmentId().equals(currentVo.getEquipmentId())){
if (
!cacheVo.getLineStatus().equals(currentVo.getLineStatus())||
!cacheVo.getAreaId().equals(currentVo.getAreaId())||
!cacheVo.getOpenStatus().equals(currentVo.getOpenStatus())||
!cacheVo.getRunStatus().equals(currentVo.getRunStatus())||
!cacheVo.getPartOpenSwitch().equals(currentVo.getPartOpenSwitch())||
!cacheVo.getEquipmentCode().equals(currentVo.getEquipmentCode())||
!cacheVo.getEquipmentName().equals(currentVo.getEquipmentName())||
!cacheVo.getUserId().equals(currentVo.getUserId())||
!cacheVo.getOrderNum().equals(currentVo.getOrderNum())
){
canSendFlag = true;
}
}
}
}
if (canSendFlag) RedisUtils.setCacheList(key,currentVoList);
}else{
RedisUtils.setCacheList(key,currentVoList);
canSendFlag = true;
}
}else{
canSendFlag = true;
}
}*/
} catch (Exception e) {
isTure = false;
sendMsg = "获取设备列表失败"+e.getMessage();
log.error("获取设备列表失败:{}",e.getMessage());
}
}
if (canSendFlag){
sendMsg = isTure? JsonUtils.toJsonString(list):sendMsg;
log.info("socket列表发送{}",sendMsg);
// sendMsg(sendMsg, userId);
sendMsg(sendMsg, Long.valueOf("6"+userId.toString().substring(1)));
}
} }

View File

@ -332,19 +332,19 @@ logStatus.name13=电机维护故障
logStatus.name14=设备故障 logStatus.name14=设备故障
## 《故障状态》 ## 《故障状态》
logStatus.name101=烟雾报警 logStatus.name101=烟雾报警
logStatus.name102=红外触发报警 logStatus.name102=红外保护被触发
logStatus.name103=电机运报警 logStatus.name103=电机运报警
logStatus.name104=电机维修报警 logStatus.name104=电机维修报警
logStatus.name105=非APP开门提醒 logStatus.name105=非APP开门
logStatus.name106=非APP关门提醒 logStatus.name106=非APP关门
logStatus.name107=关门故障报警 logStatus.name107=关门故障
logStatus.name108=开门故障报警 logStatus.name108=开门故障
logStatus.name109=开门运行提醒 logStatus.name109=开门运行
logStatus.name110=关门运行提醒 logStatus.name110=关门运行
logStatus.name111=忘记关门提醒 logStatus.name111=忘记关门
logStatus.name112=体手动开启提醒 logStatus.name112=被手动打开
logStatus.name113=半开门运行提醒 logStatus.name113=半开门
logStatus.name114=门体停止运行提醒 logStatus.name114=门体停止
logStatus.name500=离线 logStatus.name500=离线
logStatus.name501=在线 logStatus.name501=在线

View File

@ -30,6 +30,7 @@ public class MessageUtils {
public static String message(String code, Object... args) { public static String message(String code, Object... args) {
try { try {
Locale locale = LocaleContextHolder.getLocale(); Locale locale = LocaleContextHolder.getLocale();
log.info("获取国际化资源文件: {}~{}", locale.toLanguageTag(), code);
// if (locale.toLanguageTag().equals("en")) locale = Locale.CHINA;//zc change with userid because socket I18n // if (locale.toLanguageTag().equals("en")) locale = Locale.CHINA;//zc change with userid because socket I18n
return MESSAGE_SOURCE.getMessage(code, args, locale); return MESSAGE_SOURCE.getMessage(code, args, locale);
} catch (NoSuchMessageException e) { } catch (NoSuchMessageException e) {

View File

@ -1,8 +1,6 @@
package org.dromara.common.websocket.handler; package org.dromara.common.websocket.handler;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.websocket.constant.WebSocketConstants; import org.dromara.common.websocket.constant.WebSocketConstants;
@ -10,11 +8,13 @@ import org.dromara.common.websocket.dto.WebSocketMessageDto;
import org.dromara.common.websocket.holder.WebSocketSessionHolder; import org.dromara.common.websocket.holder.WebSocketSessionHolder;
import org.dromara.common.websocket.utils.WebSocketUtils; import org.dromara.common.websocket.utils.WebSocketUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.*; import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.AbstractWebSocketHandler; import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Objects;
import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY; import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY;
@ -24,8 +24,10 @@ import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USE
* @author zendwang * @author zendwang
*/ */
@Slf4j @Slf4j
@Service
public class PlusWebSocketHandler extends AbstractWebSocketHandler { public class PlusWebSocketHandler extends AbstractWebSocketHandler {
@Autowired
WebSocketApi webSocketApi;
/** /**
* 连接成功后 * 连接成功后
*/ */
@ -37,12 +39,21 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
log.info("[connect] invalid token received. sessionId: {}", session.getId()); log.info("[connect] invalid token received. sessionId: {}", session.getId());
return; return;
} }
WebSocketSessionHolder.addSession(loginUser.getUserId(), session); String currentPath = Objects.requireNonNull(session.getUri()).getPath();
log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType()); Long userId = loginUser.getUserId();
if (currentPath.contains(WebSocketConstants.detail)){
WebSocketSessionHolder.addSession(Long.valueOf("5"+userId.toString().substring(1) ), session);
}else if (currentPath.contains(WebSocketConstants.list)){
WebSocketSessionHolder.addSession(Long.valueOf("6"+userId.toString().substring(1)), session);
}else{
WebSocketSessionHolder.addSession(userId, session);
}
log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), userId, loginUser.getUserType());
} }
@Autowired
WebSocketApi webSocketApi;
/** /**
* 处理接收到的文本消息 * 处理接收到的文本消息
@ -56,17 +67,17 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
// 从WebSocket会话中获取登录用户信息 // 从WebSocket会话中获取登录用户信息
log.info("socket接受到消息 {}", message.getPayload()); log.info("socket接受到消息 {}", message.getPayload());
LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY); LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
String currentPath = session.getUri().getPath(); String currentPath = Objects.requireNonNull(session.getUri()).getPath();
String lastPath = WebSocketSessionHolder.getSessions(loginUser.getUserId()).getUri().getPath(); /*String lastPath = WebSocketSessionHolder.getSessions(loginUser.getUserId()).getUri().getPath();
if (!currentPath.equals(lastPath)){ if (!currentPath.equals(lastPath)){
WebSocketSessionHolder.addSession(loginUser.getUserId(), session); WebSocketSessionHolder.addSession(loginUser.getUserId(), session);
} }*/
String payload = message.getPayload(); String payload = message.getPayload();
if (currentPath.contains(WebSocketConstants.detail)){ if (currentPath.contains(WebSocketConstants.detail)){
webSocketApi.dealWithDetailMsg(loginUser, payload); webSocketApi.dealWithDetailMsg2(loginUser, payload,1);
} else if (currentPath.contains(WebSocketConstants.list)) { } else if (currentPath.contains(WebSocketConstants.list)) {
webSocketApi.dealWithListMsg(loginUser, payload); webSocketApi.dealWithListMsg2(loginUser, payload,1);
} else { } else {
// 创建WebSocket消息DTO对象 // 创建WebSocket消息DTO对象
@ -111,7 +122,11 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
*/ */
@Override @Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
// 当WebSocket发生传输错误时调用比如网络问题导致连接断开
// 这里可以认为是客户端断开连接因为服务端无法主动抛出传输错误
log.info("websocket连接-网络-客户端断开连接,错误信息:" + exception.getMessage());
log.error("[transport error] sessionId: {} , exception:{}", session.getId(), exception.getMessage()); log.error("[transport error] sessionId: {} , exception:{}", session.getId(), exception.getMessage());
super.handleTransportError(session, exception);
} }
/** /**
@ -121,14 +136,33 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
* @param status 关闭状态信息 * @param status 关闭状态信息
*/ */
@Override @Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY); LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
if (ObjectUtil.isNull(loginUser)) { if (ObjectUtil.isNull(loginUser)) {
log.info("[disconnect] invalid token received. sessionId: {}", session.getId()); log.info("[disconnect] invalid token received. sessionId: {}", session.getId());
return; return;
} }
WebSocketSessionHolder.removeSession(loginUser.getUserId()); // 当WebSocket连接关闭时调用
log.info("[disconnect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType()); if (status.equals(CloseStatus.SERVER_ERROR)) {
// 服务端断开连接比如服务端代码中调用了session.close()
log.info("websocket连接-服务端-断开连接,关闭状态:" + status);
} else {
// 客户端断开连接比如客户端调用了close方法
log.info("websocket连接-客户端-断开连接,关闭状态:" + status);
}
super.afterConnectionClosed(session, status);
String currentPath = session.getUri().getPath();
Long userId = loginUser.getUserId();
if (currentPath.contains(WebSocketConstants.detail)){
WebSocketSessionHolder.removeSession(Long.valueOf("5"+userId.toString().substring(1)));
}else if (currentPath.contains(WebSocketConstants.list)){
WebSocketSessionHolder.removeSession(Long.valueOf("6"+userId.toString().substring(1)));
}else{
WebSocketSessionHolder.removeSession(userId);
}
// WebSocketSessionHolder.removeSession(loginUser.getUserId());
log.info("[disconnect] sessionId: {},userId:{},userType:{}", session.getId(), userId, loginUser.getUserType());
} }
/** /**
@ -141,4 +175,5 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
return false; return false;
} }
} }

View File

@ -2,7 +2,6 @@ package org.dromara.common.websocket.handler;
import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.domain.model.LoginUser;
import org.springframework.stereotype.Service;
/** /**
* @ClassName : WebSocketApi * @ClassName : WebSocketApi
@ -10,8 +9,10 @@ import org.springframework.stereotype.Service;
* @Date : 2024/11/16 19:06 * @Date : 2024/11/16 19:06
* @Description : * @Description :
**/ **/
@Service //@Service
public interface WebSocketApi { public interface WebSocketApi {
void dealWithDetailMsg(LoginUser loginUser, String msg); void dealWithDetailMsg(LoginUser loginUser, String msg);
void dealWithDetailMsg2(LoginUser loginUser, String msg,int type);
void dealWithListMsg(LoginUser loginUser, String msg); void dealWithListMsg(LoginUser loginUser, String msg);
void dealWithListMsg2(LoginUser loginUser, String msg,int type);
} }

View File

@ -106,7 +106,7 @@ public class WebSocketUtils {
public static void sendMessage(WebSocketSession session, String message) { public static void sendMessage(WebSocketSession session, String message) {
sendMessage(session, new TextMessage(message)); sendMessage(session, new TextMessage(message));
} }
private static final Object sessionLock = new Object();
/** /**
* 向指定的WebSocket会话发送WebSocket消息对象 * 向指定的WebSocket会话发送WebSocket消息对象
* *
@ -114,14 +114,17 @@ public class WebSocketUtils {
* @param message 要发送的WebSocket消息对象 * @param message 要发送的WebSocket消息对象
*/ */
private static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) { private static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) {
if (session == null || !session.isOpen()) { synchronized (sessionLock) {
log.warn("[send] session会话已经关闭"); if (session == null || !session.isOpen()) {
} else { log.warn("[send] session会话已经关闭");
try { } else {
session.sendMessage(message); try {
} catch (IOException e) { session.sendMessage(message);
log.error("[send] session({}) 发送消息({}) 异常", session, message, e); } catch (IOException e) {
log.error("[send] session({}) 发送消息({}) 异常", session, message, e);
}
} }
} }
} }
} }