From 5e40dee0e0a4e4cff4a1aafca2444f61c39cbf32 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期四, 19 三月 2026 11:17:14 +0800
Subject: [PATCH] #AI.会话能力增强
---
rsf-admin/src/layout/AiChatDrawer.jsx | 132 +++++++++++++++++++++++++++++++++++++++++--
1 files changed, 125 insertions(+), 7 deletions(-)
diff --git a/rsf-admin/src/layout/AiChatDrawer.jsx b/rsf-admin/src/layout/AiChatDrawer.jsx
index c86e221..e8e2a07 100644
--- a/rsf-admin/src/layout/AiChatDrawer.jsx
+++ b/rsf-admin/src/layout/AiChatDrawer.jsx
@@ -6,6 +6,10 @@
Box,
Button,
Chip,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
Divider,
Drawer,
IconButton,
@@ -26,7 +30,11 @@
import CloseIcon from "@mui/icons-material/Close";
import AddCommentOutlinedIcon from "@mui/icons-material/AddCommentOutlined";
import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined";
-import { getAiRuntime, getAiSessions, removeAiSession, streamAiChat } from "@/api/ai/chat";
+import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
+import PushPinOutlinedIcon from "@mui/icons-material/PushPinOutlined";
+import PushPinIcon from "@mui/icons-material/PushPin";
+import SearchOutlinedIcon from "@mui/icons-material/SearchOutlined";
+import { getAiRuntime, getAiSessions, pinAiSession, removeAiSession, renameAiSession, streamAiChat } from "@/api/ai/chat";
const DEFAULT_PROMPT_CODE = "home.default";
@@ -51,6 +59,8 @@
const [streaming, setStreaming] = useState(false);
const [usage, setUsage] = useState(null);
const [drawerError, setDrawerError] = useState("");
+ const [sessionKeyword, setSessionKeyword] = useState("");
+ const [renameDialog, setRenameDialog] = useState({ open: false, sessionId: null, title: "" });
const promptCode = runtime?.promptCode || DEFAULT_PROMPT_CODE;
@@ -78,7 +88,7 @@
const initializeDrawer = async (targetSessionId = null) => {
await Promise.all([
loadRuntime(targetSessionId),
- loadSessions(),
+ loadSessions(sessionKeyword),
]);
};
@@ -100,9 +110,9 @@
}
};
- const loadSessions = async () => {
+ const loadSessions = async (keyword = sessionKeyword) => {
try {
- const data = await getAiSessions(DEFAULT_PROMPT_CODE);
+ const data = await getAiSessions(DEFAULT_PROMPT_CODE, keyword);
setSessions(data);
} catch (error) {
const message = error.message || "鑾峰彇 AI 浼氳瘽鍒楄〃澶辫触";
@@ -120,6 +130,16 @@
setUsage(null);
setDrawerError("");
};
+
+ useEffect(() => {
+ if (!open) {
+ return;
+ }
+ const timer = window.setTimeout(() => {
+ loadSessions(sessionKeyword);
+ }, 250);
+ return () => window.clearTimeout(timer);
+ }, [sessionKeyword, open]);
const handleSwitchSession = async (targetSessionId) => {
if (streaming || targetSessionId === sessionId) {
@@ -140,9 +160,52 @@
startNewSession();
await loadRuntime(null);
}
- await loadSessions();
+ await loadSessions(sessionKeyword);
} catch (error) {
const message = error.message || "鍒犻櫎 AI 浼氳瘽澶辫触";
+ setDrawerError(message);
+ notify(message, { type: "error" });
+ }
+ };
+
+ const handlePinSession = async (targetSessionId, pinned) => {
+ if (streaming || !targetSessionId) {
+ return;
+ }
+ try {
+ await pinAiSession(targetSessionId, pinned);
+ notify(pinned ? "浼氳瘽宸茬疆椤�" : "浼氳瘽宸插彇娑堢疆椤�");
+ await loadSessions(sessionKeyword);
+ } catch (error) {
+ const message = error.message || "鏇存柊浼氳瘽缃《鐘舵�佸け璐�";
+ setDrawerError(message);
+ notify(message, { type: "error" });
+ }
+ };
+
+ const openRenameDialog = (item) => {
+ setRenameDialog({
+ open: true,
+ sessionId: item?.sessionId || null,
+ title: item?.title || "",
+ });
+ };
+
+ const closeRenameDialog = () => {
+ setRenameDialog({ open: false, sessionId: null, title: "" });
+ };
+
+ const handleRenameSubmit = async () => {
+ if (streaming || !renameDialog.sessionId) {
+ return;
+ }
+ try {
+ await renameAiSession(renameDialog.sessionId, renameDialog.title);
+ notify("浼氳瘽宸查噸鍛藉悕");
+ closeRenameDialog();
+ await loadSessions(sessionKeyword);
+ } catch (error) {
+ const message = error.message || "閲嶅懡鍚嶄細璇濆け璐�";
setDrawerError(message);
notify(message, { type: "error" });
}
@@ -254,7 +317,7 @@
if (completed) {
await Promise.all([
loadRuntime(completedSessionId),
- loadSessions(),
+ loadSessions(sessionKeyword),
]);
}
}
@@ -313,6 +376,17 @@
鏂板缓浼氳瘽
</Button>
</Stack>
+ <TextField
+ value={sessionKeyword}
+ onChange={(event) => setSessionKeyword(event.target.value)}
+ fullWidth
+ size="small"
+ placeholder="鎼滅储浼氳瘽鏍囬"
+ InputProps={{
+ startAdornment: <SearchOutlinedIcon fontSize="small" sx={{ mr: 1, color: "text.secondary" }} />,
+ }}
+ sx={{ mb: 1.25 }}
+ />
<Paper variant="outlined" sx={{ overflow: "hidden" }}>
{!sessions.length ? (
<Box px={1.5} py={1.25}>
@@ -332,16 +406,41 @@
>
<ListItemText
primary={item.title || `浼氳瘽 ${item.sessionId}`}
- secondary={item.lastMessageTime || `Session ${item.sessionId}`}
+ secondary={item.lastMessagePreview || item.lastMessageTime || `Session ${item.sessionId}`}
primaryTypographyProps={{
noWrap: true,
fontSize: 14,
+ fontWeight: item.pinned ? 700 : 400,
}}
secondaryTypographyProps={{
noWrap: true,
fontSize: 12,
}}
/>
+ <IconButton
+ size="small"
+ edge="end"
+ disabled={streaming}
+ onClick={(event) => {
+ event.stopPropagation();
+ handlePinSession(item.sessionId, !item.pinned);
+ }}
+ title={item.pinned ? "鍙栨秷缃《" : "缃《浼氳瘽"}
+ >
+ {item.pinned ? <PushPinIcon fontSize="small" /> : <PushPinOutlinedIcon fontSize="small" />}
+ </IconButton>
+ <IconButton
+ size="small"
+ edge="end"
+ disabled={streaming}
+ onClick={(event) => {
+ event.stopPropagation();
+ openRenameDialog(item);
+ }}
+ title="閲嶅懡鍚嶄細璇�"
+ >
+ <EditOutlinedIcon fontSize="small" />
+ </IconButton>
<IconButton
size="small"
edge="end"
@@ -476,6 +575,25 @@
</Box>
</Box>
</Box>
+ <Dialog open={renameDialog.open} onClose={closeRenameDialog} fullWidth maxWidth="xs">
+ <DialogTitle>閲嶅懡鍚嶄細璇�</DialogTitle>
+ <DialogContent>
+ <TextField
+ value={renameDialog.title}
+ onChange={(event) => setRenameDialog((prev) => ({ ...prev, title: event.target.value }))}
+ autoFocus
+ margin="dense"
+ label="浼氳瘽鏍囬"
+ fullWidth
+ />
+ </DialogContent>
+ <DialogActions>
+ <Button onClick={closeRenameDialog}>鍙栨秷</Button>
+ <Button onClick={handleRenameSubmit} variant="contained" disabled={streaming || !renameDialog.title.trim()}>
+ 淇濆瓨
+ </Button>
+ </DialogActions>
+ </Dialog>
</Drawer>
);
};
--
Gitblit v1.9.1