u
This commit is contained in:
1 parent
35951777b0
commit
63f1d4d1dc
39 files changed
+880
-133
No files matched your search
@@ -24,6 +24,7 @@ public class AuthController {
|
||||
response.put("message", "Missing parameters");
|
||||
return response;
|
||||
}
|
||||
|
||||
UserInfo userInfo = UserRepository.getUserPasswordById(orgId, userId);
|
||||
if (userInfo != null && userInfo.getPassword().equals(password)) {
|
||||
String token = JwtUtil.generateToken(userId, orgId);
|
||||
@@ -33,6 +34,7 @@ public class AuthController {
|
||||
} else {
|
||||
response.put("message", "Invalid credentials");
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
-5
@@ -19,10 +19,7 @@ public class ColumnConfigController {
|
||||
*/
|
||||
@GetMapping("/api/columns")
|
||||
public Result<?> getColumnConfig(@RequestParam String tableName, HttpServletRequest request) {
|
||||
|
||||
|
||||
try {
|
||||
|
||||
String orgId = UserContext.getOrgId();
|
||||
System.out.println("api/columns:"+orgId);
|
||||
List<Map<String, Object>> data = JsonUtils.queryColumnConfig(orgId, tableName);
|
||||
@@ -32,10 +29,8 @@ public class ColumnConfigController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/api/columnsEdit")
|
||||
public Result<?> getColumnEditConfig(@RequestParam String tableName, HttpServletRequest request) {
|
||||
|
||||
try {
|
||||
String orgId = UserContext.getOrgId();
|
||||
List<Map<String, Object>> data = JsonUtils.queryColumnEditConfig(orgId, tableName);
|
||||
|
||||
@@ -8,7 +8,7 @@ public class WebConfig implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOriginPatterns("http://localhost:5173", "http://localhost:8089","http://localhost:5174") // 前端地址
|
||||
.allowedOriginPatterns("*") // 前端地址
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
||||
.allowedHeaders("*")
|
||||
.allowCredentials(true);
|
||||
|
||||
@@ -3,11 +3,15 @@ package com.link.api.util;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.link.im.manager.UserChannelManager;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.sql.*;
|
||||
import java.sql.Date;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PaginationUtils {
|
||||
|
||||
@@ -470,5 +474,5 @@ public class PaginationUtils {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
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
|
||||
public class CompanyController {
|
||||
|
||||
@GetMapping("/api/loadCompanyList")
|
||||
public Result<?> getCompanyList(){
|
||||
try {
|
||||
String orgId = UserContext.getOrgId();
|
||||
String sql = "select b_id,b_name from b_user where b_canuse = '1' ";
|
||||
|
||||
List<Map<String, Object>> maps = DbUtils.queryForList(orgId, sql);
|
||||
|
||||
for (Map<String, Object> map : maps) {
|
||||
String bId = map.get("b_id").toString();
|
||||
|
||||
map.put("_online",UserChannelManager.isOnline(bId));
|
||||
}
|
||||
|
||||
return Result.ok("成功",maps);
|
||||
} catch (Exception e) {
|
||||
return Result.fail("公司列表查询异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
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;
|
||||
import com.link.im.model.ImResponse;
|
||||
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;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class ImMessageProcessor {
|
||||
public void process(ChannelHandlerContext ctx, ImRequest request) {
|
||||
String type = request.getType();
|
||||
if (type == null) {
|
||||
WriteManager.writeToChannel(ctx.channel(), "消息类型不能为空");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case "ping":
|
||||
handlePing(ctx);
|
||||
break;
|
||||
case "login":
|
||||
handleLogin(ctx, request);
|
||||
break;
|
||||
default:
|
||||
WriteManager.writeToChannel(ctx.channel(), "未知的消息类型: " + type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePing(ChannelHandlerContext ctx) {
|
||||
WriteManager.writeToChannel(ctx.channel(), ImResponse.success("pong",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);
|
||||
|
||||
// 1.通知给好友
|
||||
String sql1 = "select b_frienduser_Id from IM_Friends where b_user_id = '" + fromUserid +"'";
|
||||
try {
|
||||
List<Map<String, Object>> maps = DbUtils.queryForList(orgId, sql1);
|
||||
for (Map<String, Object> map : maps) {
|
||||
String bFrienduserId = map.get("b_frienduser_Id").toString();
|
||||
if (CommonUtils.isNotEmpty(bFrienduserId)) {
|
||||
boolean friendOnline = UserChannelManager.isOnline(bFrienduserId);
|
||||
if(friendOnline){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// 2.通知给群组
|
||||
|
||||
// 3.通知给全部(测试用,先留,后面会删)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,8 @@ 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;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
@@ -17,6 +19,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class ImWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ImWebSocketHandler.class);
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
private final ImMessageProcessor imMessageProcessor = new ImMessageProcessor();
|
||||
|
||||
@Override
|
||||
public void handlerAdded(ChannelHandlerContext ctx) {
|
||||
@@ -35,14 +38,15 @@ public class ImWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocke
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
|
||||
String text = msg.text();
|
||||
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
|
||||
try {
|
||||
ImMessage imMessage = MAPPER.readValue(text, ImMessage.class);
|
||||
|
||||
System.out.println(imMessage);
|
||||
System.out.println(msg.text());
|
||||
ImRequest request = MAPPER.readValue(msg.text(), ImRequest.class);
|
||||
imMessageProcessor.process(ctx,request);
|
||||
} catch (Exception e) {
|
||||
WriteManager.writeToChannel(ctx.channel(),"JSON格式错误");
|
||||
logger.error("channelRead0数据处理失败", e);
|
||||
|
||||
WriteManager.writeToChannel(ctx.channel(),ImResponse.error("error",e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.link.im.manager;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -14,20 +12,45 @@ public class UserChannelManager {
|
||||
private static final ConcurrentHashMap<String, Channel> userChannelMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 添加用户与Channel绑定
|
||||
* 添加用户与Channel绑定,如果已有绑定,先移除旧的
|
||||
*/
|
||||
public static void addUser(String userId, Channel channel) {
|
||||
if (userId != null && channel != null) {
|
||||
userChannelMap.put(userId, channel);
|
||||
if (userId == null || channel == null) return;
|
||||
|
||||
// 如果已有旧的 channel,先移除
|
||||
Channel oldChannel = userChannelMap.put(userId, channel);
|
||||
|
||||
if (oldChannel != null && oldChannel != channel) {
|
||||
try {
|
||||
if (oldChannel.isActive()) {
|
||||
oldChannel.close();
|
||||
}
|
||||
logger.info("用户 {} 已有旧 channel,被替换: oldChannelId={}, newChannelId={}",
|
||||
userId, oldChannel.id().asShortText(), channel.id().asShortText());
|
||||
} catch (Exception e) {
|
||||
logger.error("关闭旧 channel 异常: userId={}", userId, e);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("用户上线: userId={}, channelId={}", userId, channel.id().asShortText());
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除用户绑定
|
||||
*/
|
||||
public static void removeUserById(String userId) {
|
||||
if (userId != null) {
|
||||
userChannelMap.remove(userId);
|
||||
if (userId == null) return;
|
||||
|
||||
Channel removed = userChannelMap.remove(userId);
|
||||
if (removed != null) {
|
||||
try {
|
||||
if (removed.isActive()) {
|
||||
removed.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("关闭 channel 异常: userId={}", userId, e);
|
||||
}
|
||||
logger.info("用户下线: userId={}, channelId={}", userId, removed.id().asShortText());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,5 +83,4 @@ public class UserChannelManager {
|
||||
Channel ch = userChannelMap.get(userId);
|
||||
return ch != null && ch.isActive();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,18 @@ public class ImMessage {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImMessage{" +
|
||||
"type='" + type + '\'' +
|
||||
", msg='" + msg + '\'' +
|
||||
", from='" + from + '\'' +
|
||||
", to='" + to + '\'' +
|
||||
", content='" + content + '\'' +
|
||||
", timestamp=" + timestamp +
|
||||
'}';
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.link.im.model;
|
||||
|
||||
public class ImRequest {
|
||||
private String type;
|
||||
private String from;
|
||||
private String to;
|
||||
private String content;
|
||||
private String orgId;
|
||||
private long timestamp;
|
||||
|
||||
// 无参构造
|
||||
public ImRequest() {}
|
||||
|
||||
// 全参构造
|
||||
public ImRequest(String type, String from, String to, String content, long timestamp,String orgId) {
|
||||
this.type = type;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.content = content;
|
||||
this.timestamp = timestamp;
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public String getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public void setTo(String to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImRequest{" +
|
||||
"type='" + type + '\'' +
|
||||
", from='" + from + '\'' +
|
||||
", to='" + to + '\'' +
|
||||
", content='" + content + '\'' +
|
||||
", timestamp=" + timestamp +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.link.im.model;
|
||||
|
||||
public class ImResponse {
|
||||
private String type;
|
||||
private int code;
|
||||
private String message;
|
||||
private long timestamp;
|
||||
private Object data;
|
||||
|
||||
// 无参构造
|
||||
public ImResponse() {}
|
||||
|
||||
// 全参构造
|
||||
public ImResponse(String type, int code, String message, long timestamp, Object data) {
|
||||
this.type = type;
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.timestamp = timestamp;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static ImResponse success(String type, Object data) {
|
||||
return new ImResponse(type, 200, "success", System.currentTimeMillis(), data);
|
||||
}
|
||||
|
||||
public static ImResponse success(String type, String message, Object data) {
|
||||
return new ImResponse(type, 200, message, System.currentTimeMillis(), data);
|
||||
}
|
||||
|
||||
public static ImResponse error(String type, String message) {
|
||||
return new ImResponse(type, 500, message, System.currentTimeMillis(), null);
|
||||
}
|
||||
|
||||
public static ImResponse error(String type, int code, String message) {
|
||||
return new ImResponse(type, code, message, System.currentTimeMillis(), null);
|
||||
}
|
||||
|
||||
// Getter & Setter
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Object data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImResponse{" +
|
||||
"type='" + type + '\'' +
|
||||
", code=" + code +
|
||||
", message='" + message + '\'' +
|
||||
", timestamp=" + timestamp +
|
||||
", data=" + data +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.link.im.utils;
|
||||
|
||||
public class CommonUtils {
|
||||
/**
|
||||
* 判断字符串是否为空(null 或 "")
|
||||
* @param str 待判断的字符串
|
||||
* @return true 如果字符串为 null 或 空串
|
||||
*/
|
||||
public static boolean isEmpty(String str) {
|
||||
return str == null || str.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否非空(不是 null 且不为空串)
|
||||
* @param str 待判断的字符串
|
||||
* @return true 如果字符串非空
|
||||
*/
|
||||
public static boolean isNotEmpty(String str) {
|
||||
return !isEmpty(str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.link.im.utils;
|
||||
|
||||
|
||||
import com.link.api.util.DruidDataSourceManager;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
public class DbUtils {
|
||||
|
||||
/**
|
||||
* 根据 SQL 查询数据
|
||||
*
|
||||
* @param orgCode 数据源组织编码
|
||||
* @param sql 查询 SQL
|
||||
* @return List<Map<String,Object>>,每一行作为 Map
|
||||
*/
|
||||
public static List<Map<String, Object>> queryForList(String orgCode, String sql) throws SQLException {
|
||||
List<Map<String, Object>> resultList = new ArrayList<>();
|
||||
|
||||
try (Connection conn = DruidDataSourceManager.getConnection(orgCode);
|
||||
PreparedStatement stmt = conn.prepareStatement(sql);
|
||||
ResultSet rs = stmt.executeQuery()) {
|
||||
|
||||
ResultSetMetaData metaData = rs.getMetaData();
|
||||
int columnCount = metaData.getColumnCount();
|
||||
|
||||
while (rs.next()) {
|
||||
Map<String, Object> rowMap = new LinkedHashMap<>();
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
String columnName = metaData.getColumnLabel(i);
|
||||
Object value = rs.getObject(i);
|
||||
rowMap.put(columnName, value);
|
||||
}
|
||||
resultList.add(rowMap);
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
url=jdbc:sqlserver://127.0.0.1:1433;databaseName=G3HY2025
|
||||
url=jdbc:sqlserver://192.168.1.189:1433;databaseName=G3-Link;encrypt=false
|
||||
username=sa
|
||||
password=g3soft
|
||||
driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
Reference in new issue
Block a user