From f5a6c6685cdb0b125013d57c30915c7437637b9f Mon Sep 17 00:00:00 2001 From: zhx Date: Thu, 14 May 2026 11:19:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=97=AA=E7=83=81=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/rooms/hooks/useRoomPinsPage.js | 54 ++++++++++++++++++--- src/features/rooms/pages/RoomPinsPage.jsx | 12 ++++- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/features/rooms/hooks/useRoomPinsPage.js b/src/features/rooms/hooks/useRoomPinsPage.js index 2ec6e9a..437165c 100644 --- a/src/features/rooms/hooks/useRoomPinsPage.js +++ b/src/features/rooms/hooks/useRoomPinsPage.js @@ -24,8 +24,10 @@ export function useRoomPinsPage() { const [activeAction, setActiveAction] = useState(""); const [form, setForm] = useState(emptyForm); const [loadingAction, setLoadingAction] = useState(""); - const [roomSearch, setRoomSearch] = useState(""); + const [roomInput, setRoomInput] = useState(""); + const [roomKeyword, setRoomKeyword] = useState(""); const [roomOptionsState, setRoomOptionsState] = useState({ error: "", loading: false, options: [] }); + const [selectedRoom, setSelectedRoom] = useState(null); const filters = useMemo( () => ({ keyword: query, @@ -58,7 +60,7 @@ export function useRoomPinsPage() { setRoomOptionsState((current) => ({ ...current, error: "", loading: true })); try { const data = await listRooms({ - keyword: roomSearch.trim(), + keyword: roomKeyword.trim(), page: 1, page_size: 20, status: "active", @@ -77,7 +79,17 @@ export function useRoomPinsPage() { cancelled = true; window.clearTimeout(timer); }; - }, [activeAction, roomSearch]); + }, [activeAction, roomKeyword]); + + const roomOptions = useMemo(() => { + if (!selectedRoom) { + return roomOptionsState.options; + } + if (roomOptionsState.options.some((room) => room.roomId === selectedRoom.roomId)) { + return roomOptionsState.options; + } + return [selectedRoom, ...roomOptionsState.options]; + }, [roomOptionsState.options, selectedRoom]); const changeQuery = (value) => { setQuery(value); @@ -103,7 +115,9 @@ export function useRoomPinsPage() { const openCreate = () => { setForm(emptyForm()); - setRoomSearch(""); + setRoomInput(""); + setRoomKeyword(""); + setSelectedRoom(null); setRoomOptionsState({ error: "", loading: false, options: [] }); setActiveAction("create"); }; @@ -151,7 +165,23 @@ export function useRoomPinsPage() { } }; - const selectedRoom = roomOptionsState.options.find((room) => room.roomId === form.roomId) || null; + const changeRoomInput = (value) => { + setRoomInput(value); + setRoomKeyword(value); + if (selectedRoom && roomOptionLabel(selectedRoom) !== value) { + setSelectedRoom(null); + setForm((current) => ({ ...current, roomId: "" })); + } + }; + + const selectRoom = (room) => { + setSelectedRoom(room || null); + setRoomInput(room ? roomOptionLabel(room) : ""); + if (!room) { + setRoomKeyword(""); + } + setForm((current) => ({ ...current, roomId: room?.roomId || "" })); + }; return { abilities, @@ -174,15 +204,23 @@ export function useRoomPinsPage() { regionOptions, reload, resetFilters, - roomOptions: roomOptionsState.options, + changeRoomInput, + roomInput, + roomOptions, roomOptionsError: roomOptionsState.error, roomOptionsLoading: roomOptionsState.loading, - roomSearch, + selectRoom, selectedRoom, setForm, setPage, - setRoomSearch, status, submitCreate, }; } + +function roomOptionLabel(room) { + if (!room) { + return ""; + } + return [room.title, room.roomShortId, room.roomId].filter(Boolean).join(" / "); +} diff --git a/src/features/rooms/pages/RoomPinsPage.jsx b/src/features/rooms/pages/RoomPinsPage.jsx index b675cc3..22afc22 100644 --- a/src/features/rooms/pages/RoomPinsPage.jsx +++ b/src/features/rooms/pages/RoomPinsPage.jsx @@ -163,6 +163,7 @@ export function RoomPinsPage() { isOptionEqualToValue={(option, value) => option.roomId === value.roomId} loading={page.roomOptionsLoading} noOptionsText="当前无数据" + inputValue={page.roomInput} options={page.roomOptions} renderInput={(params) => ( page.setForm({ ...page.form, roomId: option?.roomId || "" })} - onInputChange={(_, value) => page.setRoomSearch(value)} + onChange={(_, option) => page.selectRoom(option)} + onInputChange={(_, value, reason) => { + if (reason === "input") { + page.changeRoomInput(value); + } + if (reason === "clear") { + page.selectRoom(null); + } + }} />