Skip to content

Commit dc40590

Browse files
committed
feat(chat): 优化私聊消息处理,支持批量未读消息解析
1 parent d3b7bd9 commit dc40590

File tree

4 files changed

+70
-34
lines changed

4 files changed

+70
-34
lines changed

client/src/app.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::sync::Arc;
55

66
use crate::commands::{CommandContext, CommandRegistry};
77
use crate::ui::{CrosstermInputHandler, GLOBAL_COMMAND_CONTEXT};
8-
use crate::utils::AuthService;
8+
use crate::utils::{AuthService, strip_html_tags_chatroom};
99
use fishpi_rust::services::notice_service::ListenerId;
1010

1111
pub struct App {
@@ -39,6 +39,7 @@ impl App {
3939
if self.notice_listener_id.is_some() {
4040
return;
4141
}
42+
let client_clone = self.client.clone();
4243

4344
let listener_id = self.client.notice
4445
.add_listener(move |notice_msg| {
@@ -54,12 +55,28 @@ impl App {
5455
}
5556
}
5657
"newIdleChatMessage" => {
57-
println!(
58-
"\r{} {}: {}",
59-
"[新私信]".blue(),
60-
notice_msg.sender_name().green(),
61-
notice_msg.preview_text()
62-
);
58+
let client = client_clone.clone();
59+
let sender_name = notice_msg.sender_name().to_string();
60+
let preview = notice_msg.preview_text().to_string();
61+
62+
tokio::spawn(async move {
63+
let message = client.chat.get_messages(&sender_name, 1, 1, true).await;
64+
if let Some(last_msg) = message.data.and_then(|mut msgs| msgs.pop()) {
65+
println!(
66+
"\r{} {}: {}",
67+
"[新私信]".blue(),
68+
sender_name.green(),
69+
strip_html_tags_chatroom(last_msg.content_text()).bright_black()
70+
);
71+
} else {
72+
println!(
73+
"\r{} {}: {}",
74+
"[新私信]".blue(),
75+
sender_name.green(),
76+
preview
77+
);
78+
}
79+
});
6380
}
6481
_ => {
6582
log::warn!("未知通知类型: {}", notice_msg.command);

src/api/chat_api.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,38 +77,30 @@ impl ChatApi {
7777

7878
/// 获取未读消息
7979
pub async fn has_unread(&self) -> Result<Value> {
80-
let url = "chat/has-unread";
8180
let token = self.client.get_token().await;
8281
if token.is_none() {
8382
return Err(anyhow::anyhow!("未登录,无法获取未读消息"));
8483
}
84+
let url = "chat/has-unread?apiKey=".to_string() + &token.unwrap();
8585

86-
let mut params = HashMap::new();
87-
if let Some(token_value) = token {
88-
params.insert("apiKey".to_string(), token_value);
89-
}
90-
91-
let response = self.client.get::<Value>(url, Some(params)).await?;
86+
let response = self.client.get::<Value>(&url,None).await?;
9287
Ok(response)
9388
}
9489

9590
/// 撤回私聊消息
9691
///
9792
/// * `msg_id` - 消息ID
9893
pub async fn revoke(&self, msg_id: &str) -> Result<Value> {
99-
let url = "chat/revoke";
10094
let token = self.client.get_token().await;
10195
if token.is_none() {
10296
return Err(anyhow::anyhow!("未登录,无法撤回消息"));
10397
}
98+
let url = "chat/revoke?apiKey=".to_string() + &token.unwrap();
10499

105100
let mut params = HashMap::new();
106-
if let Some(token_value) = token {
107-
params.insert("apiKey".to_string(), token_value);
108-
}
109101
params.insert("oId".to_string(), msg_id.to_string());
110102

111-
let response = self.client.get::<Value>(url, Some(params)).await?;
103+
let response = self.client.get::<Value>(&url, Some(params)).await?;
112104
Ok(response)
113105
}
114106

src/models/chat.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::fmt::Display;
12
use serde::{Deserialize, Serialize};
23
use serde_json::Value;
34

@@ -128,39 +129,53 @@ pub struct ChatNotice {
128129
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
129130
pub struct ChatData {
130131
/// 接收 id
131-
#[serde(rename = "toId")]
132+
#[serde(rename = "toId", default)]
132133
pub to_id: String,
133134
/// 预览内容
135+
#[serde(default)]
134136
pub preview: String,
135137
/// 用户会话
136-
#[serde(rename = "user_session")]
138+
#[serde(rename = "user_session", default)]
137139
pub user_session: String,
138140
/// 发送者头像
139-
#[serde(rename = "senderAvatar")]
141+
#[serde(rename = "senderAvatar", default)]
140142
pub sender_avatar: String,
141143
/// markdown内容
144+
#[serde(default)]
142145
pub markdown: String,
143146
/// 接收者头像
144-
#[serde(rename = "receiverAvatar")]
147+
#[serde(rename = "receiverAvatar", default)]
145148
pub receiver_avatar: String,
146149
/// 消息ID
147-
#[serde(rename = "oId")]
150+
#[serde(rename = "oId", default)]
148151
pub oid: String,
149152
/// 时间
153+
#[serde(default)]
150154
pub time: String,
151155
/// 发送 id
152-
#[serde(rename = "fromId")]
156+
#[serde(rename = "fromId", default)]
153157
pub from_id: String,
154158
/// 发送者用户名
155-
#[serde(rename = "senderUserName")]
159+
#[serde(rename = "senderUserName", default)]
156160
pub sender_user_name: String,
157161
/// 内容
162+
#[serde(default)]
158163
pub content: String,
159164
/// 接收者用户名
160-
#[serde(rename = "receiverUserName")]
165+
#[serde(rename = "receiverUserName", default)]
161166
pub receiver_user_name: String,
162167
}
163168

169+
impl Display for ChatData {
170+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
171+
write!(
172+
f,
173+
"{} 给你发送了私信",
174+
self.sender_name(),
175+
)
176+
}
177+
}
178+
164179
impl ChatData {
165180
pub fn from_json(value: &Value) -> Option<Self> {
166181
serde_json::from_value(value.clone()).ok()
@@ -206,6 +221,13 @@ impl ChatData {
206221
}
207222
}
208223

224+
pub fn count(sender: &str, count: usize)-> String {
225+
if count == 1 {
226+
format!("{} 给你发送了 1 条私信", sender)
227+
} else {
228+
format!("{} 给你发送了 {} 条私信", sender, count)
229+
}
230+
}
209231
}
210232

211233
/// 聊天撤回

src/services/chat_service.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,21 @@ impl ChatService {
207207
}
208208

209209
/// 获取未读私聊消息
210-
pub async fn unread(&self) -> Response<ChatData> {
210+
pub async fn unread(&self) -> Response<Vec<ChatData>> {
211211
match self.chat_api.has_unread().await {
212212
Ok(data) => {
213-
if let Some(chat_data) = data.get("data").and_then(ChatData::from_json) {
214-
Response::success(chat_data)
213+
if let Some(chat_data_list) = data.get("data").and_then(|d| d.as_array()) {
214+
let parsed_data: Vec<ChatData> = chat_data_list
215+
.iter()
216+
.filter_map(ChatData::from_json)
217+
.collect();
218+
if !parsed_data.is_empty() {
219+
Response::success(parsed_data)
220+
} else {
221+
Response::error("解析未读消息失败:数据为空")
222+
}
215223
} else {
216-
Response::error("解析未读消息失败")
224+
Response::error("解析未读消息失败:数据格式错误")
217225
}
218226
}
219227
Err(e) => Response::error(&format!("获取未读私聊消息失败: {}", e)),
@@ -594,9 +602,6 @@ impl ChatService {
594602

595603
// 确保有监听器
596604
let listener_manager = self.get_or_create_listener_manager(user).await;
597-
if listener_manager.is_empty().await {
598-
return Err("没有监听器,无法建立有效连接".to_string());
599-
}
600605

601606
// 获取连接对象
602607
let connection = self.get_connection(user).await;

0 commit comments

Comments
 (0)