using Common; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Net.Http; using System.Text.Json; using System.Threading.Tasks; using System.Web; namespace WxCheckApi.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class CheckController : ControllerBase { private readonly MySqlConnection _connection; private readonly HttpClient _httpClient; private readonly IConfiguration _configuration; public CheckController(MySqlConnection connection, IHttpClientFactory httpClientFactory, IConfiguration configuration) { _connection = connection; _httpClient = httpClientFactory.CreateClient(); _configuration = configuration; } // 将经纬度转换为地址信息 public async Task ConvertCoordinatesToAddress(string longitude,string latitude) { try { // 使用高德地图API进行逆地理编码 string apiKey = _configuration["AmapApi:ApiKey"] ?? "4d5cb7818664ada68ae5f68783b8bd4c"; string url = $"https://restapi.amap.com/v3/geocode/regeo?output=json&location={longitude},{latitude}&key={apiKey}&radius=1000&extensions=all"; var response = await _httpClient.GetStringAsync(url); var jsonDoc = JsonDocument.Parse(response); var root = jsonDoc.RootElement; if (root.GetProperty("status").GetString() == "1" && root.TryGetProperty("regeocode", out var regeocodeElement) && regeocodeElement.ValueKind != JsonValueKind.Null) { if (regeocodeElement.TryGetProperty("formatted_address", out var formatted_address)) { return formatted_address.ToString(); } if (regeocodeElement.TryGetProperty("addressComponent", out var addressComponent)) { string province = addressComponent.TryGetProperty("province", out var provinceElement) && provinceElement.ValueKind == JsonValueKind.String ? provinceElement.GetString() : ""; string city = addressComponent.TryGetProperty("city", out var cityElement) && cityElement.ValueKind == JsonValueKind.String ? cityElement.GetString() : ""; string district = addressComponent.TryGetProperty("district", out var districtElement) && districtElement.ValueKind == JsonValueKind.String ? districtElement.GetString() : ""; string township = addressComponent.TryGetProperty("township", out var townshipElement) && townshipElement.ValueKind == JsonValueKind.String ? townshipElement.GetString() : ""; // 获取街道和门牌号信息 string street = ""; string streetNumber = ""; double distance = 0; // 方法1:从addressComponent获取街道信息 if (addressComponent.TryGetProperty("streetNumber", out var streetNumberElement) && streetNumberElement.ValueKind == JsonValueKind.Object) { street = streetNumberElement.TryGetProperty("street", out var streetElement) && streetElement.ValueKind == JsonValueKind.String ? streetElement.GetString() : ""; streetNumber = streetNumberElement.TryGetProperty("number", out var numberElement) && numberElement.ValueKind == JsonValueKind.String ? numberElement.GetString() : ""; // 获取距离信息 if (streetNumberElement.TryGetProperty("distance", out var distanceElement) && distanceElement.ValueKind == JsonValueKind.String) { double.TryParse(distanceElement.GetString(), out distance); } } // 方法2:如果方法1没有获取到街道信息,尝试从aoi信息中获取 if (string.IsNullOrEmpty(street) && regeocodeElement.TryGetProperty("aois", out var aoisElement) && aoisElement.ValueKind == JsonValueKind.Array) { var aoisArray = aoisElement.EnumerateArray(); foreach (var aoi in aoisArray) { if (aoi.TryGetProperty("name", out var aoiNameElement) && aoiNameElement.ValueKind == JsonValueKind.String) { street = aoiNameElement.GetString(); break; // 取第一个AOI作为街道信息 } } } // 方法3:如果前两种方法都没有获取到街道信息,尝试从pois信息中获取 if (string.IsNullOrEmpty(street) && regeocodeElement.TryGetProperty("pois", out var poisElement) && poisElement.ValueKind == JsonValueKind.Array) { var poisArray = poisElement.EnumerateArray(); foreach (var poi in poisArray) { if (poi.TryGetProperty("name", out var poiNameElement) && poiNameElement.ValueKind == JsonValueKind.String) { street = poiNameElement.GetString(); break; // 取第一个POI作为街道信息 } } } // 方法4:如果以上方法都没有获取到街道信息,尝试从formatted_address中解析 if (string.IsNullOrEmpty(street) && regeocodeElement.TryGetProperty("formatted_address", out var formattedAddressElement) && formattedAddressElement.ValueKind == JsonValueKind.String) { string formattedAddress = formattedAddressElement.GetString(); // 尝试从格式化地址中提取街道信息 // 格式化地址通常格式为:省 市 区 街道 具体地址 // 使用字符串数组作为分隔符 string[] separators = { " ", "省", "市", "区", "县", "镇", "街道", "路", "巷", "号" }; var addressParts = formattedAddress.Split(separators, StringSplitOptions.RemoveEmptyEntries); // 查找可能包含街道信息的部分 for (int i = 0; i < addressParts.Length; i++) { var part = addressParts[i]; // 如果部分包含"路"、"街"、"巷"等关键词,可能是街道信息 if (part.Contains("路") || part.Contains("街") || part.Contains("巷") || part.Contains("道")) { street = part; // 如果下一个部分存在且不是区县名称,可能是门牌号 if (i + 1 < addressParts.Length && !addressParts[i + 1].Contains("区") && !addressParts[i + 1].Contains("县")) { streetNumber = addressParts[i + 1]; } break; } } } // 方法5:如果仍然没有获取到街道信息,尝试从nearestRoad信息中获取 if (string.IsNullOrEmpty(street) && regeocodeElement.TryGetProperty("streetNumber", out var nearestStreetElement) && nearestStreetElement.ValueKind == JsonValueKind.Object) { if (nearestStreetElement.TryGetProperty("street", out var nearestStreetNameElement) && nearestStreetNameElement.ValueKind == JsonValueKind.String) { street = nearestStreetNameElement.GetString(); } } // 构建详细地址字符串 string address = ""; if (!string.IsNullOrEmpty(province)) { address += province; } if (!string.IsNullOrEmpty(city) && city != province) { address += " " + city; } if (!string.IsNullOrEmpty(district)) { address += " " + district; } if (!string.IsNullOrEmpty(township)) { address += " " + township; } if (!string.IsNullOrEmpty(street)) { address += " " + street; } if (!string.IsNullOrEmpty(streetNumber)) { address += " " + streetNumber; } // 如果有距离信息,添加到地址后面 if (distance > 0) { address += $" {distance:F1}米"; } if (string.IsNullOrEmpty(address)) { return "未获取到位置信息(高德返回值为空) " + latitude + "," + longitude; } return address.Trim(); } } return latitude + "," + longitude; ; // 如果API调用失败,返回原始值 } catch (Exception) { return latitude + "," + longitude; ; // 如果发生异常,返回原始值 } } [HttpPost] public async Task CheckAddress([FromBody] CheckAddressRequest request) { try { if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(); } // 从数据库查询经纬度信息 string latitude = ""; string longitude = ""; using (MySqlCommand cmd = new MySqlCommand("SELECT Latitude, Longitude FROM xcx_conversation WHERE Guid = @Guid AND IsDeleted = 0", _connection)) { cmd.Parameters.AddWithValue("@Guid", request.Guid); using (var reader = await cmd.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { latitude = reader.IsDBNull(0) ? "" : reader.GetString(0); longitude = reader.IsDBNull(1) ? "" : reader.GetString(1); } else { return NotFound(new { success = false, message = "记录不存在或已被删除" }); } } } // 转换经纬度为地址 var address = await ConvertCoordinatesToAddress(longitude, latitude); // 更新数据库中的UserLocation字段 using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET UserLocation = @UserLocation WHERE Guid = @Guid AND IsDeleted = 0", _connection)) { cmd.Parameters.AddWithValue("@Guid", request.Guid); cmd.Parameters.AddWithValue("@UserLocation", address); int rowsAffected = await cmd.ExecuteNonQueryAsync(); if (rowsAffected == 0) { return NotFound(new { success = false, message = "记录不存在或已被删除" }); } } return Ok(new { success = true, message = "地址更新成功", address = address }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = "更新失败", error = ex.Message }); } finally { if (_connection.State == ConnectionState.Open) { await _connection.CloseAsync(); } } } // 添加会话记录 [HttpPost] public async Task AddConversation([FromBody] ConversationRequest request) { DateTime nowtime = DateTime.Now; try { if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(); } // 解析经纬度并转换为地址 string address = ""; string latitude = ""; string longitude = ""; // 否则尝试从UserLocation字段解析 if (!string.IsNullOrEmpty(request.UserLocation)) { string[] parts = request.UserLocation.Split(','); if (parts.Length == 2) { if (double.TryParse(parts[0], out double lat) && double.TryParse(parts[1], out double lng)) { longitude = lng.ToString(); latitude = lat.ToString(); address = "";// await ConvertCoordinatesToAddress(latitude, longitude); } } } // 生成GUID string conversationGuid = string.IsNullOrEmpty(request.Guid) ? Guid.NewGuid().ToString("N") : request.Guid; long conversationId = 0; using (MySqlCommand cmd = new MySqlCommand("INSERT INTO xcx_conversation (UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType, Guid, SpeakingTime) VALUES (@UserKey, @ConversationContent, @SendMethod, @UserLocation, @Latitude, @Longitude, @RecordTime, @RecordTimeUTCStamp, @IsDeleted, @CreateTime, @MessageType, @Guid, @SpeakingTime); SELECT LAST_INSERT_ID();", _connection)) { cmd.Parameters.AddWithValue("@UserKey", request.UserKey); cmd.Parameters.AddWithValue("@MessageType", request.MessageType); cmd.Parameters.AddWithValue("@ConversationContent", request.ConversationContent); cmd.Parameters.AddWithValue("@SendMethod", request.SendMethod); cmd.Parameters.AddWithValue("@UserLocation", address); cmd.Parameters.AddWithValue("@Latitude", latitude); cmd.Parameters.AddWithValue("@Longitude", longitude); cmd.Parameters.AddWithValue("@RecordTime", nowtime); cmd.Parameters.AddWithValue("@CreateTime", nowtime); cmd.Parameters.AddWithValue("@RecordTimeUTCStamp", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()); cmd.Parameters.AddWithValue("@IsDeleted", 0); cmd.Parameters.AddWithValue("@Guid", conversationGuid); cmd.Parameters.AddWithValue("@SpeakingTime", request.SpeakingTime); object result = await cmd.ExecuteScalarAsync(); conversationId = Convert.ToInt64(result); } // 查询刚插入的记录,并左连接用户表 if (conversationId > 0) { string query = @"SELECT convs.Id, convs.Guid, convs.UserKey, convs.ConversationContent, convs.SendMethod, convs.UserLocation, convs.Latitude, convs.Longitude, convs.RecordTime, convs.RecordTimeUTCStamp, convs.IsDeleted, convs.CreateTime, convs.MessageType, convs.SpeakingTime, users.UserName, users.WeChatName, users.PhoneNumber, users.AvatarUrl FROM xcx_conversation AS convs LEFT JOIN xcx_users AS users ON convs.UserKey = users.UserKey WHERE convs.Guid = @Guid"; using (MySqlCommand cmd = new MySqlCommand(query, _connection)) { cmd.Parameters.AddWithValue("@Guid", conversationGuid); using (var reader = await cmd.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { // 构建要发送到Redis的数据 var messageData = new Dictionary { ["Id"] = reader.GetInt64(0).ToString(), ["Guid"] = reader.IsDBNull(1) ? "" : reader.GetString(1), ["UserKey"] = reader.GetString(2), ["ConversationContent"] = reader.GetString(3), ["SendMethod"] = reader.GetString(4), ["UserLocation"] = reader.IsDBNull(5) ? "" : reader.GetString(5), ["Latitude"] = reader.IsDBNull(6) ? "" : reader.GetString(6), ["Longitude"] = reader.IsDBNull(7) ? "" : reader.GetString(7), ["RecordTime"] = reader.GetDateTime(8).ToString("yyyy-MM-dd HH:mm:ss"), ["RecordTimeUTCStamp"] = reader.GetInt64(9).ToString(), ["IsDeleted"] = reader.GetBoolean(10).ToString(), ["CreateTime"] = reader.GetDateTime(11).ToString("yyyy-MM-dd HH:mm:ss"), ["MessageType"] = reader.GetInt32(12).ToString(), ["SpeakingTime"] = reader.IsDBNull(13) ? "" : reader.GetInt32(13).ToString(), ["UserName"] = reader.IsDBNull(14) ? "" : reader.GetString(14), ["WeChatName"] = reader.IsDBNull(15) ? "" : reader.GetString(15), ["PhoneNumber"] = reader.IsDBNull(16) ? "" : reader.GetString(16), ["AvatarUrl"] = reader.IsDBNull(17) ? "" : reader.GetString(17) }; // 发送到Redis Stream try { // 确保Stream和Group存在 CSRedisCacheHelper.XGroupCreate("xcx_msg", "xcx_group", "0"); // 将Dictionary转换为params (string, string)[]格式 var fieldValues = messageData.SelectMany(kvp => new (string, string)[] { (kvp.Key, kvp.Value) }).ToArray(); // 添加消息到Stream string messageId = CSRedisCacheHelper.XAdd("xcx_msg", fieldValues); // 记录日志(可选) System.Diagnostics.Debug.WriteLine($"消息已发送到Redis Stream: {messageId}"); } catch (Exception ex) { // 记录错误但不影响主流程 System.Diagnostics.Debug.WriteLine($"发送到Redis Stream失败: {ex.Message}"); } } } } } return Ok(new { success = true, message = "收到!", conversationGuid, receivedTime = nowtime.ToString("yyyy-MM-dd HH:mm:ss") }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = "发送失败", error = ex.Message }); } finally { if (_connection.State == ConnectionState.Open) { await _connection.CloseAsync(); } } } // 根据UserKey查询会话记录 [HttpPost] public async Task GetConversations([FromBody] UserKeyRequest request) { try { if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(); } List conversations = new List(); // 构建查询SQL,根据MessageType参数决定是否添加过滤条件 string query = "SELECT Id, Guid, UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType, SpeakingTime FROM xcx_conversation WHERE UserKey = @UserKey AND IsDeleted = 0"; if (request.MessageType == 1) { query += " AND MessageType = @MessageType"; } query += " ORDER BY RecordTimeUTCStamp DESC"; using (MySqlCommand cmd = new MySqlCommand(query, _connection)) { cmd.Parameters.AddWithValue("@UserKey", request.UserKey); using (var reader = await cmd.ExecuteReaderAsync()) { while (await reader.ReadAsync()) { conversations.Add(new ConversationResponse { Id = reader.GetInt64(0), Guid = reader.IsDBNull(1) ? "" : reader.GetString(1), UserKey = reader.GetString(2), ConversationContent = reader.GetString(3), SendMethod = reader.GetString(4), UserLocation = reader.IsDBNull(5) ? "" : reader.GetString(5), Latitude = reader.IsDBNull(6) ? "" : reader.GetString(6), Longitude = reader.IsDBNull(7) ? "" : reader.GetString(7), RecordTime = reader.GetDateTime(8), RecordTimeUTCStamp = reader.GetInt64(9), IsDeleted = reader.GetBoolean(10), CreateTime = reader.GetDateTime(11), MessageType = reader.GetInt32(12), SpeakingTime = reader.IsDBNull(13) ? null : reader.GetInt32(13) }); } } } return Ok(new { success = true, data = conversations.OrderBy(z => z.RecordTimeUTCStamp) }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = "查询失败", error = ex.Message }); } finally { if (_connection.State == ConnectionState.Open) { await _connection.CloseAsync(); } } } // 更新会话记录 [HttpPost] public async Task UpdateConversation([FromBody] UpdateConversationRequest request) { try { if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(); } DateTime nowtime = DateTime.Now; using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET ConversationContent = @ConversationContent, SendMethod = @SendMethod, UserLocation = @UserLocation, MessageType = @MessageType, RecordTime = @RecordTime WHERE Guid = @Guid AND UserKey = @UserKey", _connection)) { cmd.Parameters.AddWithValue("@Guid", request.Guid); cmd.Parameters.AddWithValue("@UserKey", request.UserKey); cmd.Parameters.AddWithValue("@ConversationContent", request.ConversationContent); cmd.Parameters.AddWithValue("@SendMethod", request.SendMethod); cmd.Parameters.AddWithValue("@UserLocation", request.UserLocation ?? ""); cmd.Parameters.AddWithValue("@MessageType", request.MessageType); cmd.Parameters.AddWithValue("@RecordTime", nowtime); int rowsAffected = await cmd.ExecuteNonQueryAsync(); if (rowsAffected == 0) { return NotFound(new { success = false, message = "记录不存在或无权限修改" }); } } return Ok(new { success = true, message = "更新成功" , receivedTime = nowtime.ToString("yyyy-MM-dd HH:mm:ss") }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = "更新失败", error = ex.Message }); } finally { if (_connection.State == ConnectionState.Open) { await _connection.CloseAsync(); } } } // 软删除会话记录 [HttpPost] public async Task DeleteConversation([FromBody] DeleteConversationRequest request) { try { if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(); } using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET IsDeleted = 1 WHERE Guid = @Guid AND UserKey = @UserKey AND IsDeleted = 0", _connection)) { cmd.Parameters.AddWithValue("@Guid", request.Guid); cmd.Parameters.AddWithValue("@UserKey", request.UserKey); int rowsAffected = await cmd.ExecuteNonQueryAsync(); if (rowsAffected == 0) { return NotFound(new { success = false, message = "记录不存在或已被删除" }); } } return Ok(new { success = true, message = "删除成功" }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = "删除失败", error = ex.Message }); } finally { if (_connection.State == ConnectionState.Open) { await _connection.CloseAsync(); } } } // 根据GUID查询会话记录(不考虑IsDeleted状态) [HttpPost] public async Task GetConversationByGuid([FromBody] GetConversationByGuidRequest request) { try { if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(); } // 查询记录,不考虑IsDeleted状态 string query = @"SELECT Id, Guid, UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType, SpeakingTime FROM xcx_conversation WHERE Guid = @Guid"; using (MySqlCommand cmd = new MySqlCommand(query, _connection)) { cmd.Parameters.AddWithValue("@Guid", request.Guid); using (var reader = await cmd.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { var conversation = new ConversationResponse { Id = reader.GetInt64(0), Guid = reader.IsDBNull(1) ? "" : reader.GetString(1), UserKey = reader.GetString(2), ConversationContent = reader.GetString(3), SendMethod = reader.GetString(4), UserLocation = reader.IsDBNull(5) ? "" : reader.GetString(5), Latitude = reader.IsDBNull(6) ? "" : reader.GetString(6), Longitude = reader.IsDBNull(7) ? "" : reader.GetString(7), RecordTime = reader.GetDateTime(8), RecordTimeUTCStamp = reader.GetInt64(9), IsDeleted = reader.GetBoolean(10), CreateTime = reader.GetDateTime(11), MessageType = reader.GetInt32(12), SpeakingTime = reader.IsDBNull(13) ? null : reader.GetInt32(13) }; return Ok(new { success = true, message = "查询成功", data = conversation }); } else { return NotFound(new { success = false, message = "未找到该记录" }); } } } } catch (Exception ex) { return StatusCode(500, new { success = false, message = "查询失败", error = ex.Message }); } finally { if (_connection.State == ConnectionState.Open) { await _connection.CloseAsync(); } } } // 分页查询会话记录 [HttpPost] public async Task GetConversationsByPage([FromBody] PaginationRequest request) { try { if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(); } // 验证并设置默认值 if (request.Page < 1) request.Page = 1; if (request.PageSize < 1 || request.PageSize > 100) request.PageSize = 10; int offset = (request.Page - 1) * request.PageSize; List conversations = new List(); // 构建分页查询SQL,根据MessageType参数决定是否添加过滤条件 string query = @"SELECT Id, Guid, UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType, SpeakingTime FROM xcx_conversation WHERE UserKey = @UserKey AND IsDeleted = 0"; if (request.MessageType == 1) { query += " AND MessageType = @MessageType"; } query += " ORDER BY RecordTimeUTCStamp DESC LIMIT @Offset, @Limit"; using (MySqlCommand cmd = new MySqlCommand(query, _connection)) { cmd.Parameters.AddWithValue("@UserKey", request.UserKey); if (request.MessageType == 1) { cmd.Parameters.AddWithValue("@MessageType", request.MessageType); } cmd.Parameters.AddWithValue("@Offset", offset); cmd.Parameters.AddWithValue("@Limit", request.PageSize); using (var reader = await cmd.ExecuteReaderAsync()) { while (await reader.ReadAsync()) { conversations.Add(new ConversationResponse { Id = reader.GetInt64(0), Guid = reader.IsDBNull(1) ? "" : reader.GetString(1), UserKey = reader.GetString(2), ConversationContent = reader.GetString(3), SendMethod = reader.GetString(4), UserLocation = reader.IsDBNull(5) ? "" : reader.GetString(5), Latitude = reader.IsDBNull(6) ? "" : reader.GetString(6), Longitude = reader.IsDBNull(7) ? "" : reader.GetString(7), RecordTime = reader.GetDateTime(8), RecordTimeUTCStamp = reader.GetInt64(9), IsDeleted = reader.GetBoolean(10), CreateTime = reader.GetDateTime(11), MessageType = reader.GetInt32(12), SpeakingTime = reader.IsDBNull(13) ? null : reader.GetInt32(13) }); } } } // 查询总数,根据MessageType参数决定是否添加过滤条件 int totalCount = 0; string countQuery = "SELECT COUNT(*) FROM xcx_conversation WHERE UserKey = @UserKey AND IsDeleted = 0"; if (request.MessageType == 1) { countQuery += " AND MessageType = @MessageType"; } using (MySqlCommand countCmd = new MySqlCommand(countQuery, _connection)) { countCmd.Parameters.AddWithValue("@UserKey", request.UserKey); if (request.MessageType == 1) { countCmd.Parameters.AddWithValue("@MessageType", request.MessageType); } totalCount = Convert.ToInt32(await countCmd.ExecuteScalarAsync()); } int totalPages = (int)Math.Ceiling((double)totalCount / request.PageSize); return Ok(new { success = true, data = new { conversations = conversations.OrderBy(z => z.RecordTimeUTCStamp), totalCount = totalCount, page = request.Page, pageSize = request.PageSize, totalPages = totalPages } }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = "查询失败", error = ex.Message }); } finally { if (_connection.State == ConnectionState.Open) { await _connection.CloseAsync(); } } } // 从Redis Stream读取消息 [HttpPost] public async Task ReadMessageFromRedis([FromBody] RedisMessageRequest request) { try { // 确保Stream和Group存在 CSRedisCacheHelper.XGroupCreate("xcx_msg", "xcx_group", "0"); // 从Redis Stream读取消息 string groupName = request.GroupName ?? "xcx_group"; string consumerName = request.ConsumerName ?? "consumer_" + DateTime.Now.Ticks; string messages = CSRedisCacheHelper.XReadGroup("xcx_msg", groupName, consumerName, request.Count ?? 1); if (string.IsNullOrEmpty(messages)) { return Ok(new { success = true, message = "没有新消息", data = new List() }); } // 解析消息 var messageList = new List(); try { var messageEntries = System.Text.Json.JsonSerializer.Deserialize>>(messages); if (messageEntries != null) { foreach (var entry in messageEntries) { if (entry.TryGetValue("Id", out var id) && entry.TryGetValue("Values", out var values)) { var messageData = new Dictionary(); // 如果Values是JsonElement,需要进一步解析 if (values is JsonElement valuesElement && valuesElement.ValueKind == JsonValueKind.Object) { foreach (var property in valuesElement.EnumerateObject()) { messageData[property.Name] = property.Value.GetString() ?? ""; } } else if (values is Dictionary valuesDict) { messageData = valuesDict; } messageData["MessageId"] = id.ToString(); messageList.Add(messageData); } } } } catch (Exception parseEx) { // 如果解析失败,尝试直接返回原始消息 System.Diagnostics.Debug.WriteLine($"解析消息失败: {parseEx.Message}"); messageList.Add(new { RawMessage = messages }); } return Ok(new { success = true, message = "成功读取消息", data = messageList }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = "读取消息失败", error = ex.Message }); } } } // 请求和响应模型 public class ConversationRequest { public string UserKey { get; set; } public string ConversationContent { get; set; } public string SendMethod { get; set; } public string UserLocation { get; set; } public double Latitude { get; set; } public double Longitude { get; set; } public int MessageType { get; set; } = 1; // 1:公有,2:私有 public string? Guid { get; set; } // 会话唯一标识 public int? SpeakingTime { get; set; } // 对话时长 } public class UserKeyRequest { public string UserKey { get; set; } public int MessageType { get; set; } = 0; // 0:不判断消息类型,1:公有,2:私有 } public class PaginationRequest { public string UserKey { get; set; } public int Page { get; set; } = 1; // 默认第一页 public int PageSize { get; set; } = 10; // 默认每页10条 public int MessageType { get; set; } = 0; // 0:不判断消息类型,1:公有,2:私有 } public class UpdateConversationRequest { public long? Id { get; set; } public string Guid { get; set; } // 会话唯一标识 public string UserKey { get; set; } public string ConversationContent { get; set; } public string SendMethod { get; set; } public string UserLocation { get; set; } public int MessageType { get; set; } = 0; public int? SpeakingTime { get; set; } } public class DeleteConversationRequest { public long? Id { get; set; } public string Guid { get; set; } // 会话唯一标识 public string UserKey { get; set; } } public class CheckAddressRequest { public long? Id { get; set; } public string Guid { get; set; } // 会话唯一标识 } public class GetConversationByGuidRequest { public long? Id { get; set; } public string Guid { get; set; } // 会话唯一标识 } public class ConversationResponse { public long Id { get; set; } public string Guid { get; set; } // 会话唯一标识 public string UserKey { get; set; } public string ConversationContent { get; set; } public string SendMethod { get; set; } public string UserLocation { get; set; } public string Latitude { get; set; } public string Longitude { get; set; } public DateTime RecordTime { get; set; } public long RecordTimeUTCStamp { get; set; } public bool IsDeleted { get; set; } public DateTime CreateTime { get; set; } public int MessageType { get; set; } // 1:公有消息,2:私有消息 public int? SpeakingTime { get; set; } } public class RedisMessageRequest { public string GroupName { get; set; } = "xcx_group"; public string ConsumerName { get; set; } public int? Count { get; set; } = 1; } }