From aa9b5800b4e85e10e3a50b9dc72b71557db7ae62 Mon Sep 17 00:00:00 2001 From: "1378012178@qq.com" <1378012178@qq.com> Date: Fri, 26 Dec 2025 14:36:43 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=9C=8D=E5=8A=A1=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=202=E3=80=81=E6=9C=8D=E5=8A=A1=E6=8C=87?= =?UTF-8?q?=E4=BB=A4websocket=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/jeecg/config/WebSocketConfig.java | 4 +- .../controller/SendOrderRuleController.java | 165 ++++++++++++++++++ .../java/com/nu/websocket/SdWebsocket.java | 27 +++ .../websocket/WebSocketMessageController.java | 149 ++++++++++++++++ .../jeecg/common/system/api/ISysUserAPI.java | 3 + .../system/service/impl/SysUserApiImpl.java | 9 + 6 files changed, 355 insertions(+), 2 deletions(-) create mode 100644 nursing-unit-services/nu-services-biz/src/main/java/com/nu/modules/config/sendorderrule/controller/SendOrderRuleController.java create mode 100644 nursing-unit-services/nu-services-biz/src/main/java/com/nu/websocket/WebSocketMessageController.java diff --git a/nursing-unit-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java b/nursing-unit-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java index 87b188d9..933fb5dc 100644 --- a/nursing-unit-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java +++ b/nursing-unit-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java @@ -30,8 +30,8 @@ public class WebSocketConfig { public FilterRegistrationBean getFilterRegistrationBean(){ FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(websocketFilter()); - //TODO 临时注释掉,测试下线上socket总断的问题 - bean.addUrlPatterns("/sdWebsocket/*","/taskCountSocket/*", "/websocket/*","/eoaSocket/*","/eoaNewChatSocket/*", "/newsWebsocket/*", "/dragChannelSocket/*", "/vxeSocket/*"); + //TODO 临时注释掉,测试下线上socket总断的问题 "/sdWebsocket/*", + bean.addUrlPatterns("/taskCountSocket/*", "/websocket/*","/eoaSocket/*","/eoaNewChatSocket/*", "/newsWebsocket/*", "/dragChannelSocket/*", "/vxeSocket/*"); return bean; } diff --git a/nursing-unit-services/nu-services-biz/src/main/java/com/nu/modules/config/sendorderrule/controller/SendOrderRuleController.java b/nursing-unit-services/nu-services-biz/src/main/java/com/nu/modules/config/sendorderrule/controller/SendOrderRuleController.java new file mode 100644 index 00000000..53a42b5f --- /dev/null +++ b/nursing-unit-services/nu-services-biz/src/main/java/com/nu/modules/config/sendorderrule/controller/SendOrderRuleController.java @@ -0,0 +1,165 @@ +package com.nu.modules.config.sendorderrule.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.nu.modules.config.sendorderrule.entity.SendOrderRule; +import com.nu.modules.config.sendorderrule.service.ISendOrderRuleService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.jeecg.common.system.base.controller.JeecgController; +import org.jeecg.common.system.query.QueryGenerator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; + + /** + * @Description: 服务指令-派单规则配置主表 + * @Author: jeecg-boot + * @Date: 2025-12-25 + * @Version: V1.0 + */ +@Api(tags="服务指令-派单规则配置主表") +@RestController +@RequestMapping("/sendorderrule/sendOrderRule") +@Slf4j +public class SendOrderRuleController extends JeecgController { + @Autowired + private ISendOrderRuleService sendOrderRuleService; + + /** + * 分页列表查询 + * + * @param sendOrderRule + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "服务指令-派单规则配置主表-分页列表查询") + @ApiOperation(value="服务指令-派单规则配置主表-分页列表查询", notes="服务指令-派单规则配置主表-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(SendOrderRule sendOrderRule, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sendOrderRule, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = sendOrderRuleService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param sendOrderRule + * @return + */ + @AutoLog(value = "服务指令-派单规则配置主表-添加") + @ApiOperation(value="服务指令-派单规则配置主表-添加", notes="服务指令-派单规则配置主表-添加") + @PostMapping(value = "/add") + public Result add(@RequestBody SendOrderRule sendOrderRule) { + sendOrderRuleService.save(sendOrderRule); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param sendOrderRule + * @return + */ + @AutoLog(value = "服务指令-派单规则配置主表-编辑") + @ApiOperation(value="服务指令-派单规则配置主表-编辑", notes="服务指令-派单规则配置主表-编辑") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody SendOrderRule sendOrderRule) { + sendOrderRuleService.updateById(sendOrderRule); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "服务指令-派单规则配置主表-通过id删除") + @ApiOperation(value="服务指令-派单规则配置主表-通过id删除", notes="服务指令-派单规则配置主表-通过id删除") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + sendOrderRuleService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "服务指令-派单规则配置主表-批量删除") + @ApiOperation(value="服务指令-派单规则配置主表-批量删除", notes="服务指令-派单规则配置主表-批量删除") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.sendOrderRuleService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "服务指令-派单规则配置主表-通过id查询") + @ApiOperation(value="服务指令-派单规则配置主表-通过id查询", notes="服务指令-派单规则配置主表-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name="id",required=true) String id) { + SendOrderRule sendOrderRule = sendOrderRuleService.getById(id); + if(sendOrderRule==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(sendOrderRule); + } + + /** + * 导出excel + * + * @param request + * @param sendOrderRule + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, SendOrderRule sendOrderRule) { + return super.exportXls(request, sendOrderRule, SendOrderRule.class, "服务指令-派单规则配置主表"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, SendOrderRule.class); + } + + /** + * 启用模式 - 停用其它模式 + * + * @return + */ + @RequestMapping(value = "/enabledRule", method = RequestMethod.POST) + public Result enabledRule(@RequestBody SendOrderRule sendOrderRule) { + return Result.OK(sendOrderRuleService.enabledRule(sendOrderRule)); + } +} diff --git a/nursing-unit-services/nu-services-biz/src/main/java/com/nu/websocket/SdWebsocket.java b/nursing-unit-services/nu-services-biz/src/main/java/com/nu/websocket/SdWebsocket.java index 64209cb6..c952eb26 100644 --- a/nursing-unit-services/nu-services-biz/src/main/java/com/nu/websocket/SdWebsocket.java +++ b/nursing-unit-services/nu-services-biz/src/main/java/com/nu/websocket/SdWebsocket.java @@ -6,12 +6,14 @@ import lombok.extern.slf4j.Slf4j; import org.jeecg.common.base.BaseMap; import org.jeecg.common.constant.WebsocketConst; import org.jeecg.common.modules.redis.client.JeecgRedisClient; +import org.jeecg.common.system.api.ISysUserAPI; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; +import java.util.ArrayList; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -25,6 +27,13 @@ import java.util.concurrent.ConcurrentHashMap; @ServerEndpoint("/sdWebsocket/{userId}") public class SdWebsocket { + private static ISysUserAPI sysUserAPI; + + @Autowired + public void setSysUserAPI(ISysUserAPI sysUserAPI) { + SdWebsocket.sysUserAPI = sysUserAPI; + } + /**线程安全Map*/ private static ConcurrentHashMap sessionPool = new ConcurrentHashMap<>(); @@ -33,6 +42,8 @@ public class SdWebsocket { try { sessionPool.put(userId, session); log.info("【系统 SdWebsocket】有新的连接,总数为:"+sessionPool.size()); + + broadcastUserList(); } catch (Exception e) { } } @@ -42,6 +53,8 @@ public class SdWebsocket { try { sessionPool.remove(userId); log.info("【系统 SdWebsocket】连接断开,总数为:"+sessionPool.size()); + + broadcastUserList(); } catch (Exception e) { e.printStackTrace(); } @@ -115,4 +128,18 @@ public class SdWebsocket { sendMessage(userId, message); } } + + private void broadcastUserList() { + try { + // 构建消息:type固定为userList,users是当前所有用户ID + JSONObject msg = new JSONObject(); + msg.put("type", "userList"); + msg.put("users",sysUserAPI.queryByEmployees(String.join(",", sessionPool.keySet()))); + msg.put("timestamp", System.currentTimeMillis()); + + sendMessage(msg.toJSONString()); + } catch (Exception e) { + log.error("发送用户列表失败", e); + } + } } diff --git a/nursing-unit-services/nu-services-biz/src/main/java/com/nu/websocket/WebSocketMessageController.java b/nursing-unit-services/nu-services-biz/src/main/java/com/nu/websocket/WebSocketMessageController.java new file mode 100644 index 00000000..ad1e638b --- /dev/null +++ b/nursing-unit-services/nu-services-biz/src/main/java/com/nu/websocket/WebSocketMessageController.java @@ -0,0 +1,149 @@ +package com.nu.websocket; + +import com.alibaba.fastjson.JSONObject; +import com.nu.websocket.SdWebsocket; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.Data; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * WebSocket消息推送控制器 + */ +@Slf4j +@RestController +@RequestMapping("/api/websocket") +@Api(tags = "WebSocket消息推送") +public class WebSocketMessageController { + + @Autowired + private SdWebsocket sdWebsocket; + + /** + * 通用消息推送接口 + * 支持发送各种类型的消息 + */ + @PostMapping("/send") + @ApiOperation("发送消息") + public Result sendMessage(@RequestBody WebSocketMessageDTO dto) { + try { + JSONObject message = new JSONObject(); + + // 基本字段 + message.put("type", dto.getMessageType()); // 消息类型 + message.put("content", dto.getContent()); // 消息内容 + message.put("title", dto.getTitle()); // 消息标题 + message.put("timestamp", System.currentTimeMillis()); + + // 可选字段 + if (dto.getFromUserId() != null) { + message.put("from", dto.getFromUserId()); // 发送者 + } + if (dto.getToUserId() != null) { + message.put("to", dto.getToUserId()); // 接收者(单用户) + } + if (dto.getData() != null) { + message.put("data", dto.getData()); // 业务数据 + } + if (dto.getCmd() != null) { + message.put("cmd", dto.getCmd()); // 业务命令 + } + if (dto.getLevel() != null) { + message.put("level", dto.getLevel()); // 消息级别 + } + + String messageJson = message.toJSONString(); + + // 判断发送方式 + if (dto.getToUserIds() != null && !dto.getToUserIds().isEmpty()) { + // 发送给多个用户 + String[] userIds = dto.getToUserIds().toArray(new String[0]); + sdWebsocket.sendMessage(userIds, messageJson); + log.info("【消息推送】发送给 {} 个用户: {}", userIds.length, dto.getContent()); + + } else if (dto.getToUserId() != null) { + // 发送给单个用户 + sdWebsocket.sendMessage(dto.getToUserId(), messageJson); + log.info("【消息推送】发送给用户 {}: {}", dto.getToUserId(), dto.getContent()); + + } else { + // 广播给所有人 + sdWebsocket.sendMessage(messageJson); + log.info("【消息推送】广播消息: {}", dto.getContent()); + } + + return Result.ok("消息发送成功"); + + } catch (Exception e) { + log.error("发送消息失败", e); + return Result.error("发送失败: " + e.getMessage()); + } + } + + /** + * 获取在线用户列表 + */ + @GetMapping("/onlineUsers") + @ApiOperation("获取在线用户列表") + public Result getOnlineUsers() { + // 这里需要修改SdWebsocket类,添加获取在线用户的方法 + // 暂时返回空列表 + return Result.ok("在线用户列表功能待实现"); + } +} + +/** + * WebSocket消息DTO + * 一个DTO搞定所有消息类型 + */ +@Data +class WebSocketMessageDTO { + // 必填字段 + private String messageType; // 消息类型: system/private/broadcast/notification/business/command/status + private String content; // 消息内容 + + // 可选字段 + private String title; // 消息标题 + private String fromUserId; // 发送者用户ID + private String toUserId; // 接收者用户ID(单个) + private List toUserIds; // 接收者用户ID列表(多个) + private Object data; // 业务数据 + private String cmd; // 业务命令 + private String level; // 消息级别: info/success/warning/error +} + +/** + * 通用返回结果 + */ +@Data +class Result { + private boolean success; + private String message; + private Object data; + + public static Result ok(Object data) { + Result result = new Result(); + result.setSuccess(true); + result.setMessage("操作成功"); + result.setData(data); + return result; + } + + public static Result ok(String message) { + Result result = new Result(); + result.setSuccess(true); + result.setMessage(message); + return result; + } + + public static Result error(String message) { + Result result = new Result(); + result.setSuccess(false); + result.setMessage(message); + return result; + } +} diff --git a/nursing-unit-system/nu-system-api/nu-system-local-api/src/main/java/org/jeecg/common/system/api/ISysUserAPI.java b/nursing-unit-system/nu-system-api/nu-system-local-api/src/main/java/org/jeecg/common/system/api/ISysUserAPI.java index 04d0bcd4..a14e3f5e 100644 --- a/nursing-unit-system/nu-system-api/nu-system-local-api/src/main/java/org/jeecg/common/system/api/ISysUserAPI.java +++ b/nursing-unit-system/nu-system-api/nu-system-local-api/src/main/java/org/jeecg/common/system/api/ISysUserAPI.java @@ -5,6 +5,7 @@ import com.nu.entity.SysUserEntity; import org.jeecg.common.api.vo.Result; import org.springframework.web.bind.annotation.RequestBody; +import java.util.List; import java.util.Map; /** @@ -21,4 +22,6 @@ public interface ISysUserAPI{ void updateById(SysUserEntity sysUserEntity); Result> initialization(@RequestBody JSONObject jsonObject); + + List queryByEmployees(String employeeIds); } diff --git a/nursing-unit-system/nu-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserApiImpl.java b/nursing-unit-system/nu-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserApiImpl.java index 15626767..d02993a5 100644 --- a/nursing-unit-system/nu-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserApiImpl.java +++ b/nursing-unit-system/nu-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserApiImpl.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.service.impl; +import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -201,5 +202,13 @@ public class SysUserApiImpl implements ISysUserAPI { } return Result.ok(result); } + + @Override + public List queryByEmployees(String employeeIds) { + QueryWrapper qw = new QueryWrapper<>(); + qw.in("employess_id",employeeIds.split(",")); + List list = sysUserService.list(qw); + return BeanUtil.copyToList(list,SysUserEntity.class); + } }