|
@@ -119,7 +119,6 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
|
|
|
|
|
const [listLoading, setListLoading] = React.useState(false);
|
|
const [listLoading, setListLoading] = React.useState(false);
|
|
|
const [list, setList] = React.useState<Item[]>([]);
|
|
const [list, setList] = React.useState<Item[]>([]);
|
|
|
- const [originalList, setOriginalList] = React.useState<Item[]>([]); // 保存原始列表数据,用于前端过滤
|
|
|
|
|
const [page, setPage] = React.useState<PageInfo>({
|
|
const [page, setPage] = React.useState<PageInfo>({
|
|
|
pageNumber: 1,
|
|
pageNumber: 1,
|
|
|
pageSize: 10,
|
|
pageSize: 10,
|
|
@@ -156,23 +155,19 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
return newValue;
|
|
return newValue;
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
+ // 标记是否正在重置,避免触发 useEffect 循环
|
|
|
|
|
+ const isResettingRef = React.useRef(false);
|
|
|
|
|
+ // 标记是否正在分页切换,避免触发 useEffect 循环
|
|
|
|
|
+ const isPaginatingRef = React.useRef(false);
|
|
|
// 搜索输入框展开状态
|
|
// 搜索输入框展开状态
|
|
|
const [isSearchExpanded, setIsSearchExpanded] = React.useState(false);
|
|
const [isSearchExpanded, setIsSearchExpanded] = React.useState(false);
|
|
|
const searchWrapperRef = React.useRef<HTMLDivElement>(null);
|
|
const searchWrapperRef = React.useRef<HTMLDivElement>(null);
|
|
|
const searchInputRef = React.useRef<any>(null);
|
|
const searchInputRef = React.useRef<any>(null);
|
|
|
- // 标记是否正在重置,避免触发 useEffect 循环
|
|
|
|
|
- const isResettingRef = React.useRef(false);
|
|
|
|
|
|
|
|
|
|
const appApi = {
|
|
const appApi = {
|
|
|
- fetchList: async (typeId: any, projectId: any, forceRefresh: boolean = false, pageNumber?: number) => {
|
|
|
|
|
- const keyword = form.getFieldValue('keyword');
|
|
|
|
|
|
|
+ fetchList: async (typeId: any, projectId: any, forceRefresh: boolean = false, pageNumber?: number, name?: string) => {
|
|
|
const currentPageNumber = pageNumber !== undefined ? pageNumber : page.pageNumber;
|
|
const currentPageNumber = pageNumber !== undefined ? pageNumber : page.pageNumber;
|
|
|
-
|
|
|
|
|
- // 如果有关键字且不是强制刷新,直接从现有数据筛选,不请求接口
|
|
|
|
|
- if (keyword && keyword.trim() !== '' && !forceRefresh) {
|
|
|
|
|
- applyFrontendFilter(originalList, keyword, currentPageNumber);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const searchName = name !== undefined ? name : (form.getFieldValue('keyword') || '');
|
|
|
|
|
|
|
|
setListLoading(true);
|
|
setListLoading(true);
|
|
|
try {
|
|
try {
|
|
@@ -184,8 +179,8 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
userId: userId,
|
|
userId: userId,
|
|
|
typeId: typeId,
|
|
typeId: typeId,
|
|
|
projectId: projectId?.toString(),
|
|
projectId: projectId?.toString(),
|
|
|
- keyword: '', // 不传关键字给后端
|
|
|
|
|
- name: '', // 不传name给后端
|
|
|
|
|
|
|
+ keyword: '',
|
|
|
|
|
+ name: searchName, // 传递 name 参数给后端
|
|
|
})
|
|
})
|
|
|
const list = res.rows.map((item: any) => {
|
|
const list = res.rows.map((item: any) => {
|
|
|
return {
|
|
return {
|
|
@@ -211,9 +206,6 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
// 没有权限时排除 status='5' 的数据
|
|
// 没有权限时排除 status='5' 的数据
|
|
|
return item.status !== '5';
|
|
return item.status !== '5';
|
|
|
});
|
|
});
|
|
|
- // 保存原始数据
|
|
|
|
|
- setOriginalList(filteredList);
|
|
|
|
|
- // 没有关键字时,显示当前页的数据
|
|
|
|
|
setList(filteredList);
|
|
setList(filteredList);
|
|
|
setPage({
|
|
setPage({
|
|
|
pageNumber: currentPageNumber,
|
|
pageNumber: currentPageNumber,
|
|
@@ -313,15 +305,8 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- // 如果没有项目级应用的数据,过滤掉"项目级应用"类型
|
|
|
|
|
- const filteredList = list.filter((item: any) => {
|
|
|
|
|
- if (item.label === '项目级应用') {
|
|
|
|
|
- return uniqueProjectNames.size > 0;
|
|
|
|
|
- }
|
|
|
|
|
- return true;
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- setAppTypeList(filteredList);
|
|
|
|
|
|
|
+ // 不过滤项目级应用,始终显示所有类型
|
|
|
|
|
+ setAppTypeList(list);
|
|
|
} catch (error: any) {
|
|
} catch (error: any) {
|
|
|
console.error(error);
|
|
console.error(error);
|
|
|
}
|
|
}
|
|
@@ -420,6 +405,11 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
isResettingRef.current = false;
|
|
isResettingRef.current = false;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
+ // 如果正在分页切换,跳过执行,避免重复请求
|
|
|
|
|
+ if (isPaginatingRef.current) {
|
|
|
|
|
+ isPaginatingRef.current = false;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
setCreateFlag(LocalStorage.getStatusFlag('deepseek:application:create'));
|
|
setCreateFlag(LocalStorage.getStatusFlag('deepseek:application:create'));
|
|
|
setDeleteFlag(LocalStorage.getStatusFlag('deepseek:application:delete'));
|
|
setDeleteFlag(LocalStorage.getStatusFlag('deepseek:application:delete'));
|
|
|
setUpdateFlag(LocalStorage.getStatusFlag('deepseek:application:update'));
|
|
setUpdateFlag(LocalStorage.getStatusFlag('deepseek:application:update'));
|
|
@@ -485,81 +475,39 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
total: page.total,
|
|
total: page.total,
|
|
|
onChange: (pageNumber, pageSize) => {
|
|
onChange: (pageNumber, pageSize) => {
|
|
|
const keyword = form.getFieldValue('keyword');
|
|
const keyword = form.getFieldValue('keyword');
|
|
|
- // 根据是否有搜索关键字,决定使用哪个数据源
|
|
|
|
|
- const dataSource = keyword && keyword.trim() !== ''
|
|
|
|
|
- ? originalList.filter((item: Item) =>
|
|
|
|
|
- item.name && item.name.toLowerCase().includes(keyword.toLowerCase().trim())
|
|
|
|
|
- )
|
|
|
|
|
- : originalList;
|
|
|
|
|
|
|
+ const typeId = form.getFieldValue('proTypeId') || form.getFieldValue('typeId');
|
|
|
|
|
+ let projectId = form.getFieldValue('projectId');
|
|
|
|
|
+
|
|
|
|
|
+ // 处理类型ID
|
|
|
|
|
+ const finalTypeId = typeId === '全部' ? null : typeId;
|
|
|
|
|
+
|
|
|
|
|
+ // 处理项目ID
|
|
|
|
|
+ if (projectId instanceof Array && projectId.length === 2) {
|
|
|
|
|
+ projectId = projectId[1];
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 获取新页的数据
|
|
|
|
|
- const startIndex = (pageNumber - 1) * pageSize;
|
|
|
|
|
- const endIndex = startIndex + pageSize;
|
|
|
|
|
- const paginatedData = dataSource.slice(startIndex, endIndex);
|
|
|
|
|
|
|
+ // 标记正在分页切换,避免触发 useEffect
|
|
|
|
|
+ isPaginatingRef.current = true;
|
|
|
|
|
|
|
|
- setList(paginatedData);
|
|
|
|
|
|
|
+ // 更新页码和页大小
|
|
|
setPage({
|
|
setPage({
|
|
|
pageNumber: pageNumber,
|
|
pageNumber: pageNumber,
|
|
|
pageSize: pageSize,
|
|
pageSize: pageSize,
|
|
|
- total: dataSource.length,
|
|
|
|
|
|
|
+ total: page.total,
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
|
|
+ // 调用接口获取新页数据
|
|
|
|
|
+ appApi.fetchList(finalTypeId, projectId, true, pageNumber, keyword || '');
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- // 前端模糊查询过滤函数
|
|
|
|
|
- const applyFrontendFilter = (dataList: Item[], keyword: string | undefined, currentPageNumber: number = 1) => {
|
|
|
|
|
- if (!keyword || keyword.trim() === '') {
|
|
|
|
|
- // 如果没有关键字,显示所有数据
|
|
|
|
|
- const paginatedData = getPaginatedData(dataList, currentPageNumber, page.pageSize);
|
|
|
|
|
- setList(paginatedData);
|
|
|
|
|
- setPage(prev => ({
|
|
|
|
|
- ...prev,
|
|
|
|
|
- total: dataList.length,
|
|
|
|
|
- pageNumber: currentPageNumber,
|
|
|
|
|
- }));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 对标题进行模糊匹配(不区分大小写)
|
|
|
|
|
- const filtered = dataList.filter((item: Item) => {
|
|
|
|
|
- return item.name && item.name.toLowerCase().includes(keyword.toLowerCase().trim());
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 计算过滤后的总页数
|
|
|
|
|
- const totalPages = Math.ceil(filtered.length / page.pageSize);
|
|
|
|
|
- // 如果当前页码超出了总页数,调整到最后一页(至少为1)
|
|
|
|
|
- const adjustedPageNumber = Math.min(currentPageNumber, Math.max(1, totalPages));
|
|
|
|
|
-
|
|
|
|
|
- // 获取调整后页码的数据
|
|
|
|
|
- const paginatedData = getPaginatedData(filtered, adjustedPageNumber, page.pageSize);
|
|
|
|
|
- setList(paginatedData);
|
|
|
|
|
- setPage(prev => ({
|
|
|
|
|
- ...prev,
|
|
|
|
|
- total: filtered.length,
|
|
|
|
|
- pageNumber: adjustedPageNumber,
|
|
|
|
|
- }));
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- // 获取分页数据
|
|
|
|
|
- const getPaginatedData = (dataList: Item[], pageNumber: number, pageSize: number) => {
|
|
|
|
|
- const startIndex = (pageNumber - 1) * pageSize;
|
|
|
|
|
- const endIndex = startIndex + pageSize;
|
|
|
|
|
- return dataList.slice(startIndex, endIndex);
|
|
|
|
|
- };
|
|
|
|
|
|
|
|
|
|
// 点击查询
|
|
// 点击查询
|
|
|
const handleClickSearch = async () => {
|
|
const handleClickSearch = async () => {
|
|
|
form.validateFields().then(async (values) => {
|
|
form.validateFields().then(async (values) => {
|
|
|
const keyword = values.keyword;
|
|
const keyword = values.keyword;
|
|
|
|
|
|
|
|
- // 如果有关键字,直接从现有数据中筛选,不请求接口
|
|
|
|
|
- if (keyword && keyword.trim() !== '') {
|
|
|
|
|
- // 模糊查询:从现有数据中筛选,保持当前页码
|
|
|
|
|
- applyFrontendFilter(originalList, keyword, page.pageNumber);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 如果没有关键字,正常查询接口
|
|
|
|
|
|
|
+ // 处理类型ID
|
|
|
if (values.proTypeId) {
|
|
if (values.proTypeId) {
|
|
|
values.typeId = values.proTypeId;
|
|
values.typeId = values.proTypeId;
|
|
|
}
|
|
}
|
|
@@ -572,7 +520,8 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
// 重置到第一页
|
|
// 重置到第一页
|
|
|
setPage(prev => ({ ...prev, pageNumber: 1 }));
|
|
setPage(prev => ({ ...prev, pageNumber: 1 }));
|
|
|
await indexApi.fetchIndex(values.typeId, values.projectId);
|
|
await indexApi.fetchIndex(values.typeId, values.projectId);
|
|
|
- await appApi.fetchList(values.typeId, values.projectId, true); // 强制刷新
|
|
|
|
|
|
|
+ // 使用接口搜索,传递 name 参数
|
|
|
|
|
+ await appApi.fetchList(values.typeId, values.projectId, true, 1, keyword || '');
|
|
|
}).catch((error) => {
|
|
}).catch((error) => {
|
|
|
console.error(error);
|
|
console.error(error);
|
|
|
});
|
|
});
|
|
@@ -640,6 +589,7 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
const handleAppTypeChange = (value: string) => {
|
|
const handleAppTypeChange = (value: string) => {
|
|
|
if (value === '41') {
|
|
if (value === '41') {
|
|
|
// 如果是项目级应用,切换面板状态
|
|
// 如果是项目级应用,切换面板状态
|
|
@@ -652,14 +602,17 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
setSelectedType(value);
|
|
setSelectedType(value);
|
|
|
form.setFieldsValue({ typeId: value });
|
|
form.setFieldsValue({ typeId: value });
|
|
|
|
|
|
|
|
|
|
+ // 获取当前搜索关键字
|
|
|
|
|
+ const keyword = form.getFieldValue('keyword') || '';
|
|
|
|
|
+
|
|
|
// 自动提交逻辑
|
|
// 自动提交逻辑
|
|
|
if (value === '全部') {
|
|
if (value === '全部') {
|
|
|
// 全部选项,传递null给后端
|
|
// 全部选项,传递null给后端
|
|
|
- appApi.fetchList(null, null, true); // 强制刷新
|
|
|
|
|
|
|
+ appApi.fetchList(null, null, true, 1, keyword); // 强制刷新
|
|
|
indexApi.fetchIndex(null, null);
|
|
indexApi.fetchIndex(null, null);
|
|
|
} else {
|
|
} else {
|
|
|
// 其他选项,传递对应的typeId
|
|
// 其他选项,传递对应的typeId
|
|
|
- appApi.fetchList(value, null, true); // 强制刷新
|
|
|
|
|
|
|
+ appApi.fetchList(value, null, true, 1, keyword); // 强制刷新
|
|
|
indexApi.fetchIndex(value, null);
|
|
indexApi.fetchIndex(value, null);
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
@@ -745,7 +698,8 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
onChange={(value) => {
|
|
onChange={(value) => {
|
|
|
// 项目类型选择器自动提交逻辑
|
|
// 项目类型选择器自动提交逻辑
|
|
|
const currentProjectId = form.getFieldValue('projectId');
|
|
const currentProjectId = form.getFieldValue('projectId');
|
|
|
- appApi.fetchList(value, currentProjectId, true); // 强制刷新
|
|
|
|
|
|
|
+ const keyword = form.getFieldValue('keyword') || '';
|
|
|
|
|
+ appApi.fetchList(value, currentProjectId, true, 1, keyword); // 强制刷新
|
|
|
indexApi.fetchIndex(value, currentProjectId);
|
|
indexApi.fetchIndex(value, currentProjectId);
|
|
|
}}
|
|
}}
|
|
|
>
|
|
>
|
|
@@ -791,12 +745,13 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
onChange={(value) => {
|
|
onChange={(value) => {
|
|
|
// 项目选择器自动提交逻辑
|
|
// 项目选择器自动提交逻辑
|
|
|
const currentProTypeId = form.getFieldValue('proTypeId');
|
|
const currentProTypeId = form.getFieldValue('proTypeId');
|
|
|
|
|
+ const keyword = form.getFieldValue('keyword') || '';
|
|
|
let projectId: any = value;
|
|
let projectId: any = value;
|
|
|
// 如果是数组且长度为2,取第二个元素(项目ID)
|
|
// 如果是数组且长度为2,取第二个元素(项目ID)
|
|
|
if (projectId instanceof Array && projectId.length === 2) {
|
|
if (projectId instanceof Array && projectId.length === 2) {
|
|
|
projectId = projectId[1];
|
|
projectId = projectId[1];
|
|
|
}
|
|
}
|
|
|
- appApi.fetchList(currentProTypeId, projectId, true); // 强制刷新
|
|
|
|
|
|
|
+ appApi.fetchList(currentProTypeId, projectId, true, 1, keyword); // 强制刷新
|
|
|
indexApi.fetchIndex(currentProTypeId, projectId);
|
|
indexApi.fetchIndex(currentProTypeId, projectId);
|
|
|
}}
|
|
}}
|
|
|
/>
|
|
/>
|
|
@@ -824,7 +779,7 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
{/* </FormItem> */}
|
|
{/* </FormItem> */}
|
|
|
<FormItem>
|
|
<FormItem>
|
|
|
<Space size={12}>
|
|
<Space size={12}>
|
|
|
- {/* <div
|
|
|
|
|
|
|
+ <div
|
|
|
className={`search-expand-wrapper ${isSearchExpanded ? 'expanded' : ''}`}
|
|
className={`search-expand-wrapper ${isSearchExpanded ? 'expanded' : ''}`}
|
|
|
ref={searchWrapperRef}
|
|
ref={searchWrapperRef}
|
|
|
>
|
|
>
|
|
@@ -833,7 +788,7 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
<Input
|
|
<Input
|
|
|
ref={searchInputRef}
|
|
ref={searchInputRef}
|
|
|
className="search-input"
|
|
className="search-input"
|
|
|
- placeholder="请输入关键字"
|
|
|
|
|
|
|
+ placeholder="请输入应用名称"
|
|
|
allowClear
|
|
allowClear
|
|
|
onPressEnter={handleClickSearch}
|
|
onPressEnter={handleClickSearch}
|
|
|
onFocus={() => setIsSearchExpanded(true)}
|
|
onFocus={() => setIsSearchExpanded(true)}
|
|
@@ -843,6 +798,7 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
<Button
|
|
<Button
|
|
|
type='primary'
|
|
type='primary'
|
|
|
className="search-button-blue"
|
|
className="search-button-blue"
|
|
|
|
|
+ shape="circle"
|
|
|
onClick={() => {
|
|
onClick={() => {
|
|
|
if (isSearchExpanded) {
|
|
if (isSearchExpanded) {
|
|
|
handleClickSearch();
|
|
handleClickSearch();
|
|
@@ -852,7 +808,7 @@ const QuestionAnswerList: React.FC = () => {
|
|
|
}}
|
|
}}
|
|
|
icon={<SearchOutlined />}
|
|
icon={<SearchOutlined />}
|
|
|
/>
|
|
/>
|
|
|
- </div> */}
|
|
|
|
|
|
|
+ </div>
|
|
|
<Tooltip title="重置">
|
|
<Tooltip title="重置">
|
|
|
<Button
|
|
<Button
|
|
|
shape="circle"
|
|
shape="circle"
|