From 655581b217f11fd6db70875e471328f8d9a7fa67 Mon Sep 17 00:00:00 2001 From: ZhangAo Date: Wed, 15 Oct 2025 17:33:02 +0800 Subject: [PATCH] u --- .../link/im/controller/CompanyController.java | 30 ++++---- .../link/im/handler/ImMessageProcessor.java | 59 +++++++++++---- .../link/im/handler/ImWebSocketHandler.java | 5 -- .../com/link/im/manager/GroupManager.java | 71 ------------------ .../com/link/im/manager/WriteManager.java | 42 +++++++---- .../java/com/link/im/model/ImResponse.java | 49 ++++++------ .../java/com/link/im/utils/CommonUtils.java | 28 +++++++ .../im/controller/CompanyController.class | Bin 2494 -> 2151 bytes .../link/im/handler/ImMessageProcessor.class | Bin 3589 -> 4691 bytes .../link/im/handler/ImWebSocketHandler.class | Bin 4430 -> 4343 bytes .../com/link/im/manager/GroupManager.class | Bin 4141 -> 0 bytes .../com/link/im/manager/WriteManager.class | Bin 2718 -> 2915 bytes .../com/link/im/model/ImResponse.class | Bin 3054 -> 3015 bytes .../com/link/im/utils/CommonUtils.class | Bin 681 -> 1563 bytes code/link/link-frontend/src/App.vue | 2 +- .../link-frontend/src/views/home/index.vue | 1 - .../link/link-frontend/src/views/im/index.vue | 47 +++++++++++- 17 files changed, 188 insertions(+), 146 deletions(-) delete mode 100644 code/link/link-backend/src/main/java/com/link/im/manager/GroupManager.java delete mode 100644 code/link/link-backend/target/classes/com/link/im/manager/GroupManager.class diff --git a/code/link/link-backend/src/main/java/com/link/im/controller/CompanyController.java b/code/link/link-backend/src/main/java/com/link/im/controller/CompanyController.java index 9172b256..d363f3b8 100644 --- a/code/link/link-backend/src/main/java/com/link/im/controller/CompanyController.java +++ b/code/link/link-backend/src/main/java/com/link/im/controller/CompanyController.java @@ -1,21 +1,12 @@ package com.link.im.controller; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.link.api.util.DruidDataSourceManager; -import com.link.api.util.PaginationUtils; import com.link.api.util.Result; import com.link.api.util.UserContext; -import com.link.im.manager.UserChannelManager; import com.link.im.utils.DbUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; @RestController @CrossOrigin @@ -29,15 +20,28 @@ public class CompanyController { List> maps = DbUtils.queryForList(orgId, sql); - for (Map map : maps) { - String bId = map.get("b_id").toString(); + return Result.ok("成功",maps); + } catch (Exception e) { + return Result.fail("公司列表查询异常:" + e.getMessage()); + } + } - map.put("_online",UserChannelManager.isOnline(bId)); - } + @GetMapping("/api/loadFriendList") + public Result loadFriendList(){ + try { + String orgId = UserContext.getOrgId(); + String sql = "select b_id,b_name from b_user where b_canuse = '1' "; + + List> maps = DbUtils.queryForList(orgId, sql); return Result.ok("成功",maps); } catch (Exception e) { return Result.fail("公司列表查询异常:" + e.getMessage()); } } + + @GetMapping("/api/loadGroupList") + public Result loadGroupList(){ + return Result.ok(""); + } } diff --git a/code/link/link-backend/src/main/java/com/link/im/handler/ImMessageProcessor.java b/code/link/link-backend/src/main/java/com/link/im/handler/ImMessageProcessor.java index 873105e3..5c1942cb 100644 --- a/code/link/link-backend/src/main/java/com/link/im/handler/ImMessageProcessor.java +++ b/code/link/link-backend/src/main/java/com/link/im/handler/ImMessageProcessor.java @@ -1,6 +1,5 @@ package com.link.im.handler; -import com.link.api.util.UserContext; import com.link.im.manager.UserChannelManager; import com.link.im.manager.WriteManager; import com.link.im.model.ImRequest; @@ -9,7 +8,6 @@ import com.link.im.utils.CommonUtils; import com.link.im.utils.DbUtils; import io.netty.channel.ChannelHandlerContext; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; import java.sql.SQLException; import java.util.List; @@ -38,35 +36,68 @@ public class ImMessageProcessor { } private void handlePing(ChannelHandlerContext ctx) { - WriteManager.writeToChannel(ctx.channel(), ImResponse.success("pong",null)); + WriteManager.writeToChannel(ctx.channel(), ImResponse.success("pong",null,null)); } private void handleLogin(ChannelHandlerContext ctx,ImRequest request){ - String fromUserid = request.getFrom(); - UserChannelManager.addUser(fromUserid,ctx.channel()); String orgId = request.getOrgId(); - System.out.println(orgId); + String fromUserid = request.getFrom(); + // 单个上线 + UserChannelManager.addUser(fromUserid,ctx.channel()); + // 群组上线 // 1.通知给好友 - String sql1 = "select b_frienduser_Id from IM_Friends where b_user_id = '" + fromUserid +"'"; try { - List> maps = DbUtils.queryForList(orgId, sql1); + String friendSql = "select b_frienduser_Id from IM_Friends where b_user_id = '" + fromUserid +"'"; + + List> maps = DbUtils.queryForList(orgId, friendSql); + + ImResponse response = ImResponse.success(); + response.setType("online"); + response.setFrom(fromUserid); + for (Map map : maps) { String bFrienduserId = map.get("b_frienduser_Id").toString(); - if (CommonUtils.isNotEmpty(bFrienduserId)) { - boolean friendOnline = UserChannelManager.isOnline(bFrienduserId); - if(friendOnline){ - + if (CommonUtils.isNotEmpty(bFrienduserId) && UserChannelManager.isOnline(bFrienduserId)) { + WriteManager.writeToUser(bFrienduserId,response); + } + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + + try { + // 1. 查询用户所属群组 + String sqlGroups = "SELECT b_group_id FROM IM_GroupMembers WHERE b_member_id = '" + fromUserid + "'"; + List> groupList = DbUtils.queryForList(orgId, sqlGroups); + + for (Map g : groupList) { + String groupId = (String) g.get("b_group_id"); + + if (CommonUtils.isEmpty(groupId)) continue; + + // 2. 查询群组成员 + String sqlMembers = "SELECT b_member_id FROM IM_GroupMembers WHERE b_group_id = '" + groupId + "'"; + List> memberList = DbUtils.queryForList(orgId, sqlMembers); + + // 3. 构造消息 + ImResponse response = ImResponse.success(); + response.setFrom(fromUserid); + response.setData(CommonUtils.mapOf("groupId", groupId)); + + // 4. 遍历群成员发送消息 + for (Map member : memberList) { + String memberId = (String) member.get("b_member_id"); + if (!fromUserid.equals(memberId)) { + WriteManager.writeToUser(memberId, response); } } } } catch (SQLException e) { throw new RuntimeException(e); } - // 2.通知给群组 - // 3.通知给全部(测试用,先留,后面会删) } } diff --git a/code/link/link-backend/src/main/java/com/link/im/handler/ImWebSocketHandler.java b/code/link/link-backend/src/main/java/com/link/im/handler/ImWebSocketHandler.java index 9360461b..c1b6f1b2 100644 --- a/code/link/link-backend/src/main/java/com/link/im/handler/ImWebSocketHandler.java +++ b/code/link/link-backend/src/main/java/com/link/im/handler/ImWebSocketHandler.java @@ -1,10 +1,8 @@ package com.link.im.handler; import com.fasterxml.jackson.databind.ObjectMapper; -import com.link.im.manager.GroupManager; import com.link.im.manager.UserChannelManager; import com.link.im.manager.WriteManager; -import com.link.im.model.ImMessage; import com.link.im.model.ImRequest; import com.link.im.model.ImResponse; import io.netty.channel.ChannelHandler; @@ -31,9 +29,6 @@ public class ImWebSocketHandler extends SimpleChannelInboundHandler Set - private static final ConcurrentHashMap> GROUP_MAP = new ConcurrentHashMap<>(); - - /** - * 创建或获取群成员集合 - */ - private static Set getGroup(String groupId) { - return GROUP_MAP.computeIfAbsent(groupId, k -> Collections.newSetFromMap(new ConcurrentHashMap<>())); - } - - /** - * 添加成员到群 - */ - public static void addUser(String groupId, String userId) { - if (groupId == null || userId == null) return; - getGroup(groupId).add(userId); - } - - /** - * 从群中移除成员 - */ - public static void removeUser(String groupId, String userId) { - Set members = GROUP_MAP.get(groupId); - if (members != null) { - members.remove(userId); - } - } - - /** - * 根据 Channel 移除该用户在所有群的成员记录 - */ - public static void removeUserFromAllGroups(Channel channel) { - if (channel == null) return; - - // 遍历所有群 - GROUP_MAP.forEach((groupId, members) -> { - members.removeIf(userId -> { - Channel ch = UserChannelManager.getChannel(userId); - boolean match = ch != null && ch.equals(channel); - if (match) { - logger.info("用户从群移除: groupId={}, userId={}", groupId, userId); - } - return match; - }); - }); - } - - /** - * 获取群成员列表(不可修改) - */ - public static Set getMembers(String groupId) { - Set members = GROUP_MAP.get(groupId); - if (members == null) return Collections.emptySet(); - return Collections.unmodifiableSet(members); - } -} diff --git a/code/link/link-backend/src/main/java/com/link/im/manager/WriteManager.java b/code/link/link-backend/src/main/java/com/link/im/manager/WriteManager.java index 742126da..fd5a4e84 100644 --- a/code/link/link-backend/src/main/java/com/link/im/manager/WriteManager.java +++ b/code/link/link-backend/src/main/java/com/link/im/manager/WriteManager.java @@ -1,13 +1,12 @@ package com.link.im.manager; import com.fasterxml.jackson.databind.ObjectMapper; -import com.link.im.handler.ImWebSocketHandler; import io.netty.channel.Channel; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Set; +import java.util.List; public class WriteManager { private static final ObjectMapper MAPPER = new ObjectMapper(); @@ -15,8 +14,16 @@ public class WriteManager { /** * 发送消息 - 根据 userId + * 内部会自动判断用户是否在线 */ public static void writeToUser(String userId, Object message) { + if (userId == null || message == null) return; + + if (!UserChannelManager.isOnline(userId)) { + // 用户不在线,直接跳过 + return; + } + Channel ch = UserChannelManager.getChannel(userId); writeToChannel(ch, message); } @@ -36,22 +43,25 @@ public class WriteManager { } /** - * 向群内所有在线成员广播消息 - * 只在异常时记录日志 + * 广播消息给指定用户列表 + * 内部会自动过滤离线用户 */ - public static void writeToGroup(String groupId, Object message) { - Set members = GroupManager.getMembers(groupId); - for (String userId : members) { - try { - Channel ch = UserChannelManager.getChannel(userId); - if (ch != null && ch.isActive() && message != null) { - String json = message instanceof String ? (String) message : MAPPER.writeValueAsString(message); + public static void broadcastToUsers(List userIds, Object message) { + if (message == null || userIds == null || userIds.isEmpty()) return; - ch.writeAndFlush(new TextWebSocketFrame(json)); - } - } catch (Exception e) { - logger.error("❌ 群消息发送失败 groupId={} userId={}", groupId, userId, e); - } + for (String userId : userIds) { + writeToUser(userId, message); // 内部自动判断在线 + } + } + + /** + * 广播消息给指定 Channel 列表 + */ + public static void broadcastToChannels(List channels, Object message) { + if (message == null || channels == null || channels.isEmpty()) return; + + for (Channel ch : channels) { + writeToChannel(ch, message); } } } diff --git a/code/link/link-backend/src/main/java/com/link/im/model/ImResponse.java b/code/link/link-backend/src/main/java/com/link/im/model/ImResponse.java index f6e695f1..a9efc4c2 100644 --- a/code/link/link-backend/src/main/java/com/link/im/model/ImResponse.java +++ b/code/link/link-backend/src/main/java/com/link/im/model/ImResponse.java @@ -5,37 +5,45 @@ public class ImResponse { private int code; private String message; private long timestamp; + private String from; private Object data; - // 无参构造 - public ImResponse() {} + public ImResponse() { + } - // 全参构造 - public ImResponse(String type, int code, String message, long timestamp, Object data) { + public ImResponse(String type, int code, String message, long timestamp, String from,Object data) { this.type = type; this.code = code; this.message = message; this.timestamp = timestamp; + this.from = from; this.data = data; } - public static ImResponse success(String type, Object data) { - return new ImResponse(type, 200, "success", System.currentTimeMillis(), data); + public static ImResponse success() { + ImResponse response = new ImResponse(); + response.setCode(200); + response.setMessage("success"); + response.setTimestamp( System.currentTimeMillis()); + return response; } - public static ImResponse success(String type, String message, Object data) { - return new ImResponse(type, 200, message, System.currentTimeMillis(), data); + public static ImResponse success(String type, String from,Object data) { + return new ImResponse(type, 200, "success", System.currentTimeMillis(), from,data); + } + + public static ImResponse success(String type, String message,String from,Object data) { + return new ImResponse(type, 200, message, System.currentTimeMillis(), from,data); } public static ImResponse error(String type, String message) { - return new ImResponse(type, 500, message, System.currentTimeMillis(), null); + return new ImResponse(type, 500, message, System.currentTimeMillis(), null,null); } public static ImResponse error(String type, int code, String message) { - return new ImResponse(type, code, message, System.currentTimeMillis(), null); + return new ImResponse(type, code, message, System.currentTimeMillis(), null,null); } - // Getter & Setter public String getType() { return type; } @@ -68,6 +76,14 @@ public class ImResponse { this.timestamp = timestamp; } + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + public Object getData() { return data; } @@ -75,15 +91,4 @@ public class ImResponse { public void setData(Object data) { this.data = data; } - - @Override - public String toString() { - return "ImResponse{" + - "type='" + type + '\'' + - ", code=" + code + - ", message='" + message + '\'' + - ", timestamp=" + timestamp + - ", data=" + data + - '}'; - } } \ No newline at end of file diff --git a/code/link/link-backend/src/main/java/com/link/im/utils/CommonUtils.java b/code/link/link-backend/src/main/java/com/link/im/utils/CommonUtils.java index f48ea696..215819a4 100644 --- a/code/link/link-backend/src/main/java/com/link/im/utils/CommonUtils.java +++ b/code/link/link-backend/src/main/java/com/link/im/utils/CommonUtils.java @@ -1,5 +1,8 @@ package com.link.im.utils; +import java.util.HashMap; +import java.util.Map; + public class CommonUtils { /** * 判断字符串是否为空(null 或 "") @@ -18,4 +21,29 @@ public class CommonUtils { public static boolean isNotEmpty(String str) { return !isEmpty(str); } + + + /** + * 快速创建 Map,类似 JDK9 的 Map.of() + * 用法示例: + * MapUtils.of("groupId", 1, "userId", 2, "status", "online") + */ + public static Map mapOf(Object... keyValues) { + if (keyValues == null || keyValues.length == 0) { + return new HashMap<>(); + } + if (keyValues.length % 2 != 0) { + throw new IllegalArgumentException("参数数量必须为偶数(键值成对出现)"); + } + + Map map = new HashMap<>(keyValues.length / 2); + for (int i = 0; i < keyValues.length; i += 2) { + @SuppressWarnings("unchecked") + K key = (K) keyValues[i]; + @SuppressWarnings("unchecked") + V value = (V) keyValues[i + 1]; + map.put(key, value); + } + return map; + } } diff --git a/code/link/link-backend/target/classes/com/link/im/controller/CompanyController.class b/code/link/link-backend/target/classes/com/link/im/controller/CompanyController.class index fd04807c4be86ea7156931c48ec0db388dba20d4..69d3e1634e82090515a7ef0c8110f370892c5d33 100644 GIT binary patch delta 969 zcmb_aT~8BH5IuLhyLY>6Yuy&DMJ6{?6|MWlQv)rvlCQq$CsmXzw7X?!z2 zVQ!3%B%1hUQeR3V2|vL9;YZ?sFwWf)Fvh+ZH`zOL=bo84XENL2Z=u}hpP#k?q;TJa zjWHAFaNfWL6XTdLkT!71u$IVyI-t}me zYH_B(U}qn@PhDrlEf<}oTD4Rzro}SLi|_0Kn-mMm+e~n!;ubR1(xY-ATUx6zgdKOa z8$iQ^9@?^D*vUgElQ2bCfy26NX%viXES@GI89?M#o!#soj^~L&^mm3@l78Y@v zT8QT?EEd&?*c~ic$YIvPU3uI?o&ge-7jM)l5z^kXsBo32i1T&7QLD5yhz~qn-%kUR zp9(672%X(@bI4K&Xv3ReAIVX0fKJ^D25^vks|`RDhv>!-Ll1mj@)n_0ia9MPS=%?4 z7->PBx3y#odLz39V|f#P+iapM(X7KF+eDy+V8g2@NpQ-S{bJM+L{KGaoNCL?5$f1Y zJtc<}G=1mIKc)eMB;KBgBT)T z!3mrs8zk5;{fUQQYZxIf`A;%Cs;uwH>?J9EM5&*M4Uo)1k~#FBWOh_p|BK91B-7cI tIZ8LV3c9_og;2vA&fYF0f7=CpXTF^WI7)*(?NvDA^)=yFaFzlo;1~Bhe~SPB delta 1247 zcma)+U2_v<6vuy0lFcrgOUJ36?c9J^*iW{_3Wmd))_C{**)hu=lq{@{^#to`$yM< zWaHuAKRy7C^0~<##!SX}+2D-HE4&)xEE6$a81|zWhq(1B(y&NRbQ@7Hv15KC`;uRO((Ud@|nPV~bD7TYSoAURUJQ z@vbf0#d@{iN~w-5E}25Du1IV-ChAVru9vG`HgdON6gDhHPikP>tTs_HFn!UkWt~;Y z5>5@wN@H$d?ApW!45#LooQ1le!+A%L{i$}Y?XivY+g;-dqh8)*-M>&SrDZ}l(uGpG zWV?3WsirU2oa*?Z?Yd5Jvh9*Rh1ygwN=0|d`!$km2(6u4V;C!!i;nFI^%c9g>`Yzv zyPMr!e*@w3tt<=Q;s4e%KjBXAty-WezDS`m1ynI zebo0s_)(G3z}dqASzB!Yk8w~e#p66d*x#%&qIL0AnuIcm@Z{j(CXwt=3r#T^>5a6A zD(-N^Uo~{a&lsaxua?-+!VIxSY&0sC)f;URZ_?4CGtBh2>kkuMLrr$x%lt%g=03X; z-D~s=uJMSdHFh`Yy%$iDuTeg>2tMIMm?HOxwO1(ZCoa?nh4P5dJtu^-4f+NC6gg5s zS7!w_BHN!7e^j6cB$h&x1Q!?(pS&fqlD1z47MK6SAcv*f9DNM&bWpysF_E+s?h#Zw z$1{?njel0~M%`8@v8=aI(u&des8Kq`5Xd*{xa zd(L~#dC$2w@4SERH2}-;w*bOO29SbTf;9H2umZ@y4qyp-RNN=${VEOwDBCNC&noy_ z02-1i?w9lDOuSqRWOF(@JPAd3%0M&R##j`4&Q*cU(d_%?a3QntN zm8)+`&EHb-f`V@g6s@rd`*S^j&^i)SrMz0_a)C5#Z&!o*%hR)5NAO`Mt$_ffib5&&aCBn^Hq74V) zdfGP3l+={eB~K)zBKMI2?y}6Dw0srdjwVMy#=`wBAy6yhQOvLFr6@lZJA2%3e$(o5 zc6VB4avL2ssH$=-1(_I+hPUUr#~7@1m-)%cd$Xy1j~=({RulR9ynWKHw=oyXThz0< zj)kP4U%_`2yr|$M1ur|5c$^M5n>|)sUuVb?ns#GFES1R<2yX33*+x=tH8KXP>#kJF zv|}>73`82!SxZX@Mk$TFm({MXh5Qc{D;tUaKcm=Nt zOust#*wurtUK=?7_vemY$v*y%Ll>@O&s}@*oPzIZ7{K>6`~W{BS<*D2;YS!0@Fyhc zG_1!44UJeu^y4dFO^=c2&@Fzs`piq$PQ7sLSAm(oWpqy zKgJmi7bM8nG`xNCH(9m(Z z45-TkF(lLE1Hnn#5|ZN7l#-;FMNr7WAd zZMss7Ql=*^&uxL$n<&Y%>#5Cqlf(Z14i=S(*yMJ4nUi&_^>LI+dNGw}fEU4$$SSdp z4*A{*>G(>hn>cMUq`~~e$%dZ^uWjEZX90~j3#)gXX}JtraZBENL3Pd!xlfXV+{rgH zO6HN1RmtR-I3|<1L=mWzaO0wqMjnAHbF_8L<%ms_3YoHzcP8gLM;`c6&SEUhz3fni zF=xE<{Ts>LXgo*6XXQKN#;o2oZie%;#G#5 z!-e@UCZ-faGCg0irQ0(1%PXmK6I6_hXW!48&!$d+dDXjaM$FN+;9i=^9Pi*N%vo^u*9<`n@Sy-7=UC*toPs;~thoY+ppGkcXRM+W zH;XU|DG8ijGKhkWwQr$p@mUn|vhB;lKTsR-6|C?FeS;`^nL_-L+6u7zpvAeWX#PJ9 z&P#&6a%B)|A1Vu1`1>)L>tbhJx~ z7Qu)TRLW-zVrEd0LRG<{vzW!}j~Z0ZVzxjZ?vPJ&1TG>JDGnBw&pnF|6<`n_js${% zEavs0T+Z|Rz;#f`VnP4#rGAt}{O3`%Q%ea^e#X(F(T7vm!5u2SdYe|H zwM%#dyQDRu^lV7B=gNamUe)r+t6Fgk_i%3^bsxpOeDcu(C|Bh9(?)+>FLqO}i?a=- z9;V&Qhl`|*NL>4rb9%rlm^4hMiWS5Zv@3|S5#)Y56zB>%fygkk?jI)ttWnTa@;(+j z@)Yj8j-?8^xg2I>OUKENNVy`prE6iiw4hG31Nb)z9BVhWCfS?|u!n(gkAnp8KifUX AjQ{`u delta 1530 zcmZXU`*TxO5XV0^uX}TIu%RKeY0DcbEiJWxt)xD%#Rm!$~H6>0FN`I#S*W6 z8sjOG!zM>;7VxymQIlsze_LZ1$DAduty9&`Y%-qi>rSVV>9~Q>;~aN2R(bkk1381> z>fN!uv6jJnGS#v=naew-drpnLGn?t(n2TqVeFol4HnB>yC$}fn>I}P21qJ_EljlsH zH+exaJDr|vsDVb=Qygbljuj_((fQspqv<7u!%354ikEpsUWncFm*{CT}WE@s{Fkjr@+{G-nj=>cxAC_xZr&tl~pHa#G%| z+K&~V@Truh_>9k`KE)S&sTk#)^Q(7$=saJUe61K`Tv24)AnXL)VP~mtmal;cgL?cpI}D@F`Q24F#lXxB_V&he z!s<$AAW-jg`DZ(6f2PMu#Pi){690v|et#|>?>BH~2J=!yxev)q%erhbonN2N#$){* z2BA_J|J{~M1KKH-c2ahY^NYXFIbr{ls$N*eDAl}SS2nXRwj&kqXxPLYnZ|`O#Nfd| zIwf+EtXf1HqP>md7^7miXcFlwZH8zTTa_JHEY6611Fhn<$l0#W7qstU0wTkBnU0?- zrco`cTJp?bzYOXSvpFOM9ATa`uD*oXC}qHzNla}mVQDGP8F^8bvCLc>lSk zT{>@|Lio^EonH38R#tGbES# zGe*@#)Ru9kR925s(JWtOM8p`us5jz?c#G6TeG%UTwFXf$Vop$JFv2oz%`mvc%%~Ny zDrZeF+a)tQC+d&*i_9INBH}L;nb&5A?GfB(ul#V9im2}*3${djz^c_T(h9dhcq(hqGr14iFXQSo Vxj*p#nOQFYE;g`Hv>yFU@Hf@|6=nbc diff --git a/code/link/link-backend/target/classes/com/link/im/handler/ImWebSocketHandler.class b/code/link/link-backend/target/classes/com/link/im/handler/ImWebSocketHandler.class index fecb8e7d0be1dca6b72e0e25a2354e5217cf5b60..501ac092901dc7ae644a74a79d75f18b20fc9c22 100644 GIT binary patch delta 1416 zcmZXT>30)l6o;RgEN?QI){xLZ8(N!$rb}9@X+S_JMN_p^iaVC77_ndx+gdA9x1gfp zzRVZJeXR=$Z7^-bxQ|JT zjZEqIX~h#39n9#APby~h=2Je71bCXGKISYUJ9O|fJZteB&nsT=k=F%|X_yy%yrf-U zRvfn^^cBUc7O!za@w(0{ux~8FZ01_A23y!F9(~T< zx^1}?|MjA4W7$7aj_<7cLnqs~PU5bYXpbQ;I?47*5?N0Qo-UY9m9Pw!xndE|IlQAw zs8GF0{UMa8Ww6?c&@!BrhsjM6sxS{I zZf-7%={L(_W@X>dgCQw&n;(kRS`BnxpyeYrt&;Ofk#j>{dTBM-GmpP3)xAV)L7Xcc zM1)LELdx{XfMn#1Hj8>&%G9luq&32U8sPxL+*$>6V{Y|un`ChdRAe>huxuLaB0o|+ zj|uV7pb0H>yrOW4fI$h{pu0rEt##L|8qq9^T$zLIMCD-P0;dJ7pe1T(i5gmh-P|sb zdiJVv?as?EXC?Z7y)pu!F)UHzJR6I&tyJ?0v7Y^v|G=tNxxB?7Waaj8N9Bi-z+Ne> zuW%^2OnZTK=ja$6TB5T+NEb26EmeNFkVJ+>kvnDIFvb*Qqmlvc3fmShKW4SE2Vpt-jsH{c?*~N^a3(-o*Woc2gq*lA9 z-R$k6m0c|=?ZTx6v~g(0ADVt>#y_K(e(1M;YkJP^3QRJyJm)>VY(F$Te#@%2nz#^j~*F5}SjK+Z3Q@s?BLY4@(@CWDZ()(92Y ztfNu!w#`Z2F(`44nkCLilh}=_>OtqouqzJ`@@3A0CMG4@HK0hI{&A ziO9}G{NPAO=0k)?#D?Nyu|1=)#EwLKXzSo$`h0YHg>~E&t`_Mbhk%BcRX{f@*00qR zYhoZG%l{_lvRx70AbWbkP>7piZkClTr%=ExY!qwI%qH<@atiV`C71jI)UYb;U!0Dw z&H5w5ZQ)jlyG^1!hJ5HGn=?sdeMInd!Itnmmcbk=t}Y6u@La^(HH-3Jm%^9XpC{K~ z9@`*=vyhjUX7CFwl;a~Py;Vu_&@z^mMV6LpS=`86bVHKhH(}96k75oJaX=1E88TpnliS_S&p1U7h8#DTj|uBQFcfR zJH z0wYpd{}uYH=ct*c^dhxg?X%QPQ>cp=>6S82vPdFViX!*QzKi?VleYJ>SFFZ(NbH01 Nvt<1MZ_*X={Ri7S>FNLg diff --git a/code/link/link-backend/target/classes/com/link/im/manager/GroupManager.class b/code/link/link-backend/target/classes/com/link/im/manager/GroupManager.class deleted file mode 100644 index 95bace763045eb40bd5cdefbbc45d324848dfbf0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4141 zcmbVPYjYdb8Geo|du?eQ$x0lXw17!W;)@a)as%7AI07f8a$;~2N@$y|rIoz#YFDgQ zp=nBK>5bm#jb750OKBj$^aGa};v_RnKczFB{)|pD{SQp1&)Ho`Yg-XaKWNXM_q^BV zy`0rQ{(Jpn00;1H3_I{x4+inY6bX;V(2pk+EX7DU8Am5hNy=&Y_GAhIPs{C>WB3Zb zDj#Q4h#)Ud3o+;@N^K>nZKWGV9OtmAz?347N$#=&D+U`C1apKhC*@f9ffsx!f?Yx$$xrUj^+g85jIJ)I#vW?ecT6JYXt4OgW zqhx7r&CvzUenzorpU>2+QfA3@468I1l3dc=77Q~}Gqlzy@FU&5GT+rPWyRfJ^T3L5>hkhLXbiFNc zpe?OXI8~LI+|xqGX7duNt{MfTd%a7pmS1J^0#ss-UbfHczCNX_OBCr{VpD|M*JFC2 zQpa`Ide)Xsv%&=inx^I)yF6=}9>lbE=Sa@5GnVeU7c%)3&9Zbell9jr>AeyV1$Nw? zQ6R>wEz~0zGPUw@K^wk}(c$|AX4;tD4CDGRJ->Pb8&=IUhwl@Z{XZ0j3uW|-KqS8+ z&{@`8xr#FinCHI0PQ5CJCwR2VGM&z|kiCwGE!j0Eug@8>{`g?6+gw#RJ??rEBJ+qU*cCPel2x< z4xbkoz4h|j|9*LF}uH5*~rOT5;L03I=@wxPnU%`A;@Un{E;I{(1o9?xn zQ!0Lk-wOLl7s$L zCRnRfOagrONO+bMYgXPhY%4Ptyl}E4=yj#$>hs0fXYP;qWn(!vdnP)-qn z{ua7q6?U-HI5qs{*)V8=NJ1S_5BIc;?lpnou-29%-fN#OEuYsbv@_MFZ(8DW#NcIA zt(A30&fcQ!JgUid*%{dNZmtFnA!a#D`kO_QwM~=BCE^@H-Fms=USOHCf7WG%B$
SCw8}L3V9m@^EbE?{oxwW1opK^@Mycy+@(KL(@dhA-1zN591N>y z3q06DXDI$QRmVAH>CX~zd9CnjW2=WFmtQIyQ^VV6qa$-#-nAX}WDjfK|1J`^H|$i_ z)T&jg+9)}t;Lj@Fz*{OFl>_o2%&7PR9%ex{=ZImQw^#K{&byU3c(r2PUYwr<^__yZ z*>*YGUac_O{5t34ktw?TdhgCEB` z{tcb)krqKy&p=2|5@Q(Wd78gY!3_e>_M!*-=ugB`{WRAI&-%x1LK*)%qVJEbp=-!MNIn2)0u`}xNwf`jCe zp!$?Uq)6AgAwI!?g2Ns(>)d+)50XiyYk{joJT)dE@nMfi*y9^9nc!ce{pe#0HglN5 zB&H}W%`tPG^(0Jk--GE!UR_#|;D8;&4LUu4<{_$TOB@W{igmXz=^*a#ts2`>cB-XMg7TxG=Z8|Z)PDz>j- zpj~suF&A#mIfBxSqoH9Ts{+`X8eGF2A0icK{SXmZe*E0w(@(<|3ii?aW28hdk2k#& ifxqAiF5?d5xR;%>z~6D4z@qo|B|L>Q-rLupVflZ2f&UW# diff --git a/code/link/link-backend/target/classes/com/link/im/manager/WriteManager.class b/code/link/link-backend/target/classes/com/link/im/manager/WriteManager.class index c998a8d3577b7b6e8515f82ec7765f235e7cd6f6..2e4abb93a50b30c960a9f31713dbd89cdeebcdad 100644 GIT binary patch literal 2915 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 delta 295 zcmY+6yAr`b7=_PfZB|y|mc;!QL!;3oB}1<_f+@IGQfEZ%~8%={2+F5iA6uKHcjsAZ9NVnD~)F^5UTnsUCQAU(SCDk%XH!|5F z;)P8YAR$1Q>2RB~1zXK75N8e+4AXu;N|ZReAAs#~b22X}Cyfi!<&QNvHb50Mvh}w~ kmgP#o=d1)jGDYxJ914TQPvPejUQVH4mHrI^Aw3ovFQFb2p#T5? diff --git a/code/link/link-frontend/src/App.vue b/code/link/link-frontend/src/App.vue index b8b83d70..063b1316 100644 --- a/code/link/link-frontend/src/App.vue +++ b/code/link/link-frontend/src/App.vue @@ -6,7 +6,7 @@ import { useWebSocket } from './stores/websocketStore' const websocket = useWebSocket() onBeforeUnmount(() => { - // websocket.disconnect() + websocket.disconnect() }) diff --git a/code/link/link-frontend/src/views/home/index.vue b/code/link/link-frontend/src/views/home/index.vue index 314950a6..7835c136 100644 --- a/code/link/link-frontend/src/views/home/index.vue +++ b/code/link/link-frontend/src/views/home/index.vue @@ -31,7 +31,6 @@ onMounted(async () => { -