From 347c887b5be5f6252f83a14ab1d44aa2226163fb Mon Sep 17 00:00:00 2001 From: pengjie <17373303529@163.com> Date: Fri, 29 Dec 2023 17:10:05 +0800 Subject: [PATCH] =?UTF-8?q?AI=E9=A2=84=E8=AD=A6=E5=BC=B9=E7=AA=97=E6=8F=90?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 + .../recognition/config/WebSocketConfig.java | 17 +++ .../HardWareCallbackController.java | 21 ++- .../admin/controller/WebSocketServer.java | 131 ++++++++++++++++++ .../admin/service/impl/DeviceServiceImpl.java | 4 +- .../enterprise/entity/DeviceAlarm.java | 2 + .../service/impl/SystemDeptServiceImpl.java | 23 ++- .../security/WebSecurityConfig.java | 1 + 8 files changed, 199 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/xmgl/recognition/config/WebSocketConfig.java create mode 100644 src/main/java/com/xmgl/recognition/modules/admin/controller/WebSocketServer.java diff --git a/pom.xml b/pom.xml index 6b3f9f8..fcd7316 100644 --- a/pom.xml +++ b/pom.xml @@ -219,6 +219,11 @@ kingbase8 8.6.0 + + + org.springframework.boot + spring-boot-starter-websocket + diff --git a/src/main/java/com/xmgl/recognition/config/WebSocketConfig.java b/src/main/java/com/xmgl/recognition/config/WebSocketConfig.java new file mode 100644 index 0000000..32be9dc --- /dev/null +++ b/src/main/java/com/xmgl/recognition/config/WebSocketConfig.java @@ -0,0 +1,17 @@ +package com.xmgl.recognition.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +@Configuration +public class WebSocketConfig { + /** + * 主要作用是自动注册使用了 @ServerEndpoint 注解的 WebSocket endpoint。 + * @return + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/src/main/java/com/xmgl/recognition/modules/admin/controller/HardWareCallbackController.java b/src/main/java/com/xmgl/recognition/modules/admin/controller/HardWareCallbackController.java index b2f7bee..a211dce 100644 --- a/src/main/java/com/xmgl/recognition/modules/admin/controller/HardWareCallbackController.java +++ b/src/main/java/com/xmgl/recognition/modules/admin/controller/HardWareCallbackController.java @@ -2,6 +2,8 @@ package com.xmgl.recognition.modules.admin.controller; import cn.xuyanwu.spring.file.storage.FileInfo; import cn.xuyanwu.spring.file.storage.FileStorageService; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.xmgl.recognition.jeecg.common.api.vo.Result; @@ -12,7 +14,9 @@ import com.xmgl.recognition.modules.admin.entity.DeviceAlgorithm; import com.xmgl.recognition.modules.admin.entity.SystemDictData; import com.xmgl.recognition.modules.admin.service.*; import com.xmgl.recognition.modules.enterprise.entity.DeviceAlarm; +import com.xmgl.recognition.modules.enterprise.entity.SystemUser; import com.xmgl.recognition.modules.enterprise.service.IDeviceAlarmService; +import com.xmgl.recognition.modules.enterprise.service.ISystemUserService; import com.xmgl.recognition.util.CommonUtil; import com.xmgl.recognition.util.FileUtil; import io.swagger.annotations.Api; @@ -25,6 +29,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -56,6 +61,12 @@ public class HardWareCallbackController { @Autowired private IAlgorithmService algorithmService; + @Autowired + private WebSocketServer webSocketServer; + + @Autowired + private ISystemUserService systemUserService; + /** * AI设备报警信息上报 * @param map @@ -84,7 +95,7 @@ public class HardWareCallbackController { deviceAlarm.setDeviceCode(device.getCode()); deviceAlarm.setType(MapUtils.getInteger(map, "type")); String image = MapUtils.getString(map, "image"); - MultipartFile multipartFile = FileUtil.base64toMultipart("data:image/jpeg;base64,"+ image, "text.jpg"); + MultipartFile multipartFile = FileUtil.base64toMultipart(image, "text.jpg"); FileInfo upload = fileStorageService.of(multipartFile) .setPlatform("minio-1") .upload(); @@ -96,6 +107,14 @@ public class HardWareCallbackController { deviceAlarm.setDeptId(device.getDeptId()); deviceAlarm.setDeptGroup(device.getDeptGroup()); deviceAlarmService.save(deviceAlarm); + deviceAlarm.setTypeName(algorithmList.get(0).getTitle()); + try { + List list = systemUserService.list(Wrappers.lambdaQuery().eq(SystemUser::getSn, device.getSn())); + webSocketServer.sendMoreMessage(list.stream().map(u -> u.getUserId()).collect(Collectors.toList()), JSONObject.toJSONString(deviceAlarm)); + } catch (Exception e) { + e.printStackTrace(); + return Result.error("发送消息失败。"); + } return Result.success("添加成功!"); } } diff --git a/src/main/java/com/xmgl/recognition/modules/admin/controller/WebSocketServer.java b/src/main/java/com/xmgl/recognition/modules/admin/controller/WebSocketServer.java new file mode 100644 index 0000000..f590baa --- /dev/null +++ b/src/main/java/com/xmgl/recognition/modules/admin/controller/WebSocketServer.java @@ -0,0 +1,131 @@ +package com.xmgl.recognition.modules.admin.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; + +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocketServer { + + private Logger logger = LoggerFactory.getLogger(WebSocketServer.class); + /** + * 与某个客户端的连接会话,需要通过它来给客户端发送数据 + */ + private Session session; + /** + * 用户id + */ + private String userId; + /** + * 用来存放每个客户端对应的MyWebSocket对象 + */ + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + /** + * 用来存在线连接用户信息 + */ + private static ConcurrentHashMap sessionPool = new ConcurrentHashMap(); + + /** + * 链接成功调用的方法 + */ + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + try { + this.session = session; + this.userId = userId; + webSockets.add(this); + sessionPool.put(userId, session); + logger.info("【websocket消息】有新的连接,总数为:" + webSockets.size()); + } catch (Exception e) { + } + } + + /** + * 链接关闭调用的方法 + */ + @OnClose + public void onClose() { + try { + webSockets.remove(this); + sessionPool.remove(this.userId); + logger.info("【websocket消息】连接断开,总数为:" + webSockets.size()); + } catch (Exception e) { + } + } + + /** + * 收到客户端消息后调用的方法 + */ + @OnMessage + public void onMessage(String message) { + logger.info("【websocket消息】收到客户端消息:" + message); + } + + /** + * 发送错误时的处理 + * + * @param session + * @param error + */ + @OnError + public void onError(Session session, Throwable error) { + logger.error("用户错误,原因:" + error.getMessage()); + error.printStackTrace(); + } + + /** + * 此为广播消息 + */ + public void sendAllMessage(String message) { + logger.info("【websocket消息】广播消息:" + message); + for (WebSocketServer webSocket : webSockets) { + try { + if (webSocket.session.isOpen()) { + webSocket.session.getAsyncRemote().sendText(message); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 此为单点消息 + */ + public void sendOneMessage(String userId, String message) { + Session session = sessionPool.get(userId); + if (session != null && session.isOpen()) { + try { + logger.info("【websocket消息】 单点消息:" + message); + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 此为单点消息(多人) + */ + public void sendMoreMessage(List userIds, String message) { + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null && session.isOpen()) { + try { + logger.info("【websocket消息】 单点消息:" + message); + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/src/main/java/com/xmgl/recognition/modules/admin/service/impl/DeviceServiceImpl.java b/src/main/java/com/xmgl/recognition/modules/admin/service/impl/DeviceServiceImpl.java index 02c595e..4a8fad2 100644 --- a/src/main/java/com/xmgl/recognition/modules/admin/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/xmgl/recognition/modules/admin/service/impl/DeviceServiceImpl.java @@ -111,10 +111,10 @@ public class DeviceServiceImpl extends ServiceImpl impleme if (device1.getSn() != null && !device1.getSn().equals(user.getSn())) { throw new CustomException("其他企业已绑定该设备"); } - if (device1.getDeptId() != null && device1.getDeptId() != null) { + if (device1.getDeptId() != null && device.getDeptId() != null) { throw new CustomException("该设备已绑定组织机构"); } - if (device1.getDeptGroup() != null && device1.getDeptGroup() != null) { + if (device1.getDeptGroup() != null && device.getDeptGroup() != null) { throw new CustomException("该设备已绑定设备组"); } LambdaUpdateWrapper wrapper = Wrappers.lambdaUpdate(); diff --git a/src/main/java/com/xmgl/recognition/modules/enterprise/entity/DeviceAlarm.java b/src/main/java/com/xmgl/recognition/modules/enterprise/entity/DeviceAlarm.java index 92827c1..b30dcf1 100644 --- a/src/main/java/com/xmgl/recognition/modules/enterprise/entity/DeviceAlarm.java +++ b/src/main/java/com/xmgl/recognition/modules/enterprise/entity/DeviceAlarm.java @@ -3,6 +3,7 @@ package com.xmgl.recognition.modules.enterprise.entity; import java.io.Serializable; import java.util.Date; +import com.alibaba.fastjson.annotation.JSONField; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -72,6 +73,7 @@ public class DeviceAlarm implements Serializable { * 预警上报时间 */ @Excel(name = "预警上报时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") @ApiModelProperty(value = "预警上报时间") private Date reportTime; /** diff --git a/src/main/java/com/xmgl/recognition/modules/enterprise/service/impl/SystemDeptServiceImpl.java b/src/main/java/com/xmgl/recognition/modules/enterprise/service/impl/SystemDeptServiceImpl.java index 15518cc..87aca8e 100644 --- a/src/main/java/com/xmgl/recognition/modules/enterprise/service/impl/SystemDeptServiceImpl.java +++ b/src/main/java/com/xmgl/recognition/modules/enterprise/service/impl/SystemDeptServiceImpl.java @@ -1,13 +1,17 @@ package com.xmgl.recognition.modules.enterprise.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xmgl.recognition.modules.admin.entity.Device; +import com.xmgl.recognition.modules.admin.service.IDeviceService; import com.xmgl.recognition.modules.enterprise.entity.SystemDept; import com.xmgl.recognition.modules.enterprise.mapper.SystemDeptMapper; import com.xmgl.recognition.modules.enterprise.service.ISystemDeptService; import com.xmgl.recognition.security.SecurityUser; import com.xmgl.recognition.security.SecurityUtil; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -25,6 +29,9 @@ import java.util.stream.Collectors; @Transactional(rollbackFor = Exception.class) public class SystemDeptServiceImpl extends ServiceImpl implements ISystemDeptService { + @Autowired + private IDeviceService deviceService; + @Override public List getList(SystemDept systemDept) { SecurityUser user = SecurityUtil.getUser(); @@ -69,8 +76,20 @@ public class SystemDeptServiceImpl extends ServiceImpllambdaQuery().apply("FIND_IN_SET({0}, ancestors)", deptId)); - return this.removeById(deptId); + SystemDept systemDept = this.getById(deptId); + List list = this.list(Wrappers.lambdaQuery().apply("FIND_IN_SET({0}, ancestors)", deptId)) + .stream().map(d -> d.getDeptId()).collect(Collectors.toList()); + list.add(deptId); + LambdaUpdateWrapper wrapper = Wrappers.lambdaUpdate(); + if (systemDept.getType() == 1) { + wrapper.set(Device::getDeptId, null); + wrapper.in(Device::getDeptId, list); + } else { + wrapper.set(Device::getDeptGroup, null); + wrapper.in(Device::getDeptGroup, list); + } + deviceService.update(wrapper); + return this.remove(Wrappers.lambdaQuery().in(SystemDept::getDeptId, deptId)); } private List getTreeList(List treeList, List list) { diff --git a/src/main/java/com/xmgl/recognition/security/WebSecurityConfig.java b/src/main/java/com/xmgl/recognition/security/WebSecurityConfig.java index 9c89573..7793c06 100644 --- a/src/main/java/com/xmgl/recognition/security/WebSecurityConfig.java +++ b/src/main/java/com/xmgl/recognition/security/WebSecurityConfig.java @@ -70,6 +70,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { //请求路径允许访问 .antMatchers("/param/grouplist").permitAll() .antMatchers("/xmgl/api/**").permitAll() + .antMatchers("/websocket/**").permitAll() .antMatchers("/license/**").permitAll() .antMatchers("/api/main/alarm").permitAll() .antMatchers("/xmgl/lifter/list").permitAll()