feat(ContentSelection): 添加搜索功能并优化分页逻辑

- 在PopupHeader组件中添加onSearch回调支持
- 将Input组件替换为Input.Search以支持搜索按钮
- 重构selectionPopup组件,移除useCallback并优化搜索和分页处理
- 减少每页显示数量从20改为10
- 简化空状态显示逻辑
This commit is contained in:
超级老白兔
2025-08-28 17:56:12 +08:00
parent 7430f4deb8
commit e2ff3dd7c5
2 changed files with 56 additions and 54 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from "react";
import React, { useState, useEffect } from "react";
import { Checkbox, Popup } from "antd-mobile";
import { getContentLibraryList } from "./api";
import style from "./index.module.scss";
@@ -15,7 +15,7 @@ interface SelectionPopupProps {
onConfirm?: (libraries: ContentItem[]) => void;
}
const PAGE_SIZE = 20;
const PAGE_SIZE = 10;
// 类型标签文本
const getTypeText = (type?: number) => {
@@ -60,40 +60,39 @@ const SelectionPopup: React.FC<SelectionPopupProps> = ({
);
// 获取内容库列表支持keyword和分页
const fetchLibraries = useCallback(
async (page: number, keyword: string = "") => {
setLoading(true);
try {
const params: any = {
page,
limit: PAGE_SIZE,
};
if (keyword.trim()) {
params.keyword = keyword.trim();
}
const response = await getContentLibraryList(params);
if (response && response.list) {
setLibraries(response.list);
setTotalLibraries(response.total || 0);
setTotalPages(Math.ceil((response.total || 0) / PAGE_SIZE));
} else {
// 如果没有返回列表数据,设置为空数组
setLibraries([]);
setTotalLibraries(0);
setTotalPages(1);
}
} catch (error) {
console.error("获取内容库列表失败:", error);
// 请求失败时,设置为空数组
const fetchLibraries = async (page: number, keyword: string = "") => {
setLoading(true);
try {
const params: any = {
page,
limit: PAGE_SIZE,
};
if (keyword.trim()) {
params.keyword = keyword.trim();
}
const response = await getContentLibraryList(params);
if (response && response.list) {
setLibraries(response.list);
setTotalLibraries(response.total || 0);
setTotalPages(Math.ceil((response.total || 0) / PAGE_SIZE));
} else {
// 如果没有返回列表数据,设置为空数组
setLibraries([]);
setTotalLibraries(0);
setTotalPages(1);
} finally {
setLoading(false);
}
},
[],
);
} catch (error) {
console.error("获取内容库列表失败:", error);
// 请求失败时,设置为空数组
setLibraries([]);
setTotalLibraries(0);
setTotalPages(1);
} finally {
setTimeout(() => {
setLoading(false);
});
}
};
// 打开弹窗时获取第一页
useEffect(() => {
@@ -109,23 +108,26 @@ const SelectionPopup: React.FC<SelectionPopupProps> = ({
// 关闭弹窗时重置加载状态,确保下次打开时显示加载中
setLoading(true);
}
}, [visible, fetchLibraries, selectedOptions]);
}, [visible, selectedOptions]);
// 搜索防抖
useEffect(() => {
// 搜索处理函数
const handleSearch = (query: string) => {
if (!visible) return;
const timer = setTimeout(() => {
setCurrentPage(1);
fetchLibraries(1, searchQuery);
}, 500);
return () => clearTimeout(timer);
}, [searchQuery, visible, fetchLibraries]);
setCurrentPage(1);
fetchLibraries(1, query);
};
// 翻页时重新请求
useEffect(() => {
if (!visible || currentPage === 1) return;
fetchLibraries(currentPage, searchQuery);
}, [currentPage, visible, fetchLibraries, searchQuery]);
// 搜索输入变化时的处理
const handleSearchChange = (query: string) => {
setSearchQuery(query);
};
// 翻页处理函数
const handlePageChange = (page: number) => {
if (!visible || page === currentPage) return;
setCurrentPage(page);
fetchLibraries(page, searchQuery);
};
// 处理内容库选择
const handleLibraryToggle = (library: ContentItem) => {
@@ -175,11 +177,7 @@ const SelectionPopup: React.FC<SelectionPopupProps> = ({
</div>
) : (
<div className={style.emptyBox}>
<div className={style.emptyText}>
{searchQuery
? `没有找到包含"${searchQuery}"的内容库`
: "没有找到内容库"}
</div>
<div className={style.emptyText}></div>
</div>
);
};
@@ -197,9 +195,10 @@ const SelectionPopup: React.FC<SelectionPopupProps> = ({
<PopupHeader
title="选择内容库"
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
setSearchQuery={handleSearchChange}
searchPlaceholder="搜索内容库"
loading={loading}
onSearch={handleSearch}
onRefresh={() => fetchLibraries(currentPage, searchQuery)}
/>
}
@@ -210,7 +209,7 @@ const SelectionPopup: React.FC<SelectionPopupProps> = ({
totalPages={totalPages}
loading={loading}
selectedCount={tempSelectedOptions.length}
onPageChange={setCurrentPage}
onPageChange={handlePageChange}
onCancel={onClose}
onConfirm={handleConfirm}
/>

View File

@@ -11,6 +11,7 @@ interface PopupHeaderProps {
searchPlaceholder?: string;
loading?: boolean;
onRefresh?: () => void;
onSearch?: (query: string) => void;
showRefresh?: boolean;
showSearch?: boolean;
showTabs?: boolean;
@@ -28,6 +29,7 @@ const PopupHeader: React.FC<PopupHeaderProps> = ({
searchPlaceholder = "搜索...",
loading = false,
onRefresh,
onSearch,
showRefresh = true,
showSearch = true,
showTabs = false,
@@ -42,10 +44,11 @@ const PopupHeader: React.FC<PopupHeaderProps> = ({
{showSearch && (
<div className={style.popupSearchRow}>
<div className={style.popupSearchInputWrap}>
<Input
<Input.Search
placeholder={searchPlaceholder}
value={searchQuery}
onChange={e => setSearchQuery(e.target.value)}
onSearch={() => onSearch && onSearch(searchQuery)}
prefix={<SearchOutlined />}
size="large"
/>