feat(ContentSelection): 添加搜索功能并优化分页逻辑
- 在PopupHeader组件中添加onSearch回调支持 - 将Input组件替换为Input.Search以支持搜索按钮 - 重构selectionPopup组件,移除useCallback并优化搜索和分页处理 - 减少每页显示数量从20改为10 - 简化空状态显示逻辑
This commit is contained in:
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user