feat: 统一列表模糊搜索行为

- 统一管理端和用户中心搜索参数及多字段包含匹配

- 修复聊天搜索竞态并优化部门重名路径展示

- 补充部门展开、模型空白词和聊天查询回归测试
This commit is contained in:
2026-08-13 22:29:59 +08:00
parent 765006747a
commit 64a85c6a5b
83 changed files with 1134 additions and 208 deletions

View File

@@ -1,5 +1,5 @@
<script setup>
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { ArrowDown } from '@element-plus/icons-vue';
import {
@@ -31,6 +31,10 @@ const props = defineProps({
type: Number,
default: 3,
},
initialValue: {
type: String,
default: '',
},
// 搜索框占位符
searchPlaceholder: {
type: String,
@@ -38,10 +42,17 @@ const props = defineProps({
},
});
const emit = defineEmits(['search', 'button-click', 'buttonClick']);
const emit = defineEmits(['search', 'button-click', 'buttonClick', 'reset']);
// 搜索值
const searchValue = ref('');
const searchValue = ref(props.initialValue);
watch(
() => props.initialValue,
(value) => {
searchValue.value = value;
},
);
// 计算显示的按钮
const visibleButtons = computed(() => {
@@ -55,11 +66,19 @@ const dropdownButtons = computed(() => {
// 处理搜索
const handleSearch = () => {
searchValue.value = searchValue.value.trim();
emit('search', searchValue.value);
};
const handleClear = () => {
searchValue.value = '';
emit('search', '');
};
const handleReset = () => {
searchValue.value = '';
emit('reset');
emit('search', '');
};
// 处理按钮点击
@@ -91,10 +110,11 @@ const handleDropdownClick = (button) => {
<div>
<ElInput
v-model="searchValue"
:placeholder="$t('common.searchPlaceholder')"
:placeholder="searchPlaceholder"
class="search-input"
@keyup.enter="handleSearch"
clearable
@clear="handleClear"
@keyup.enter="handleSearch"
/>
</div>
<div>

View File

@@ -113,8 +113,10 @@ function removeBotFromRecentlyUsed(botId: any) {
<h1 class="text-2xl font-medium">助理市场</h1>
<ElSpace :size="20">
<ElInput
placeholder="搜索"
v-model="queryParams.title"
v-model="queryParams.keyword"
clearable
placeholder="搜索助理名称或描述"
@clear="getBotList"
@keyup.enter="getBotList"
:prefix-icon="Search"
/>

View File

@@ -61,8 +61,10 @@ function handleTagClick(tag: any) {
<h1 class="text-2xl font-medium">智能体</h1>
<ElSpace :size="20">
<ElInput
placeholder="搜索"
v-model="queryParams.title"
v-model="queryParams.keyword"
clearable
placeholder="搜索工作流名称或描述"
@clear="getWorkflowList"
@keyup.enter="getWorkflowList"
:prefix-icon="Search"
/>

View File

@@ -42,6 +42,8 @@ const queryParams = ref({
pageNumber: 1,
pageSize: 20,
});
const appliedSessionKeyword = ref('');
let latestSessionRequestId = 0;
const pageState = ref({
total: 0,
@@ -73,20 +75,7 @@ const variantSwitchController = createChatVariantSwitchController<
});
const filteredSessions = computed(() => {
const keyword = queryParams.value.keyword.trim().toLowerCase();
if (!keyword) {
return sessions.value;
}
return sessions.value.filter((item) => {
const title = String(item.title || '').toLowerCase();
const preview = String(item.lastMessagePreview || '').toLowerCase();
const assistantName = String(item.assistantName || '').toLowerCase();
return (
title.includes(keyword) ||
preview.includes(keyword) ||
assistantName.includes(keyword)
);
});
return sessions.value;
});
onMounted(async () => {
@@ -127,13 +116,19 @@ async function fetchAssistants() {
async function fetchSessions() {
loading.value = true;
const requestId = ++latestSessionRequestId;
const requestParams = {
assistantId: queryParams.value.assistantId,
keyword: appliedSessionKeyword.value || undefined,
pageNumber: queryParams.value.pageNumber,
pageSize: queryParams.value.pageSize,
};
const [, res] = await tryit(api.get)('/userCenter/chatHistory/sessions', {
params: {
assistantId: queryParams.value.assistantId,
pageNumber: queryParams.value.pageNumber,
pageSize: queryParams.value.pageSize,
},
params: requestParams,
});
if (requestId !== latestSessionRequestId) {
return;
}
loading.value = false;
if (res?.errorCode === 0) {
sessions.value = res.data?.records || [];
@@ -141,6 +136,19 @@ async function fetchSessions() {
}
}
function handleSessionSearch() {
const keyword = queryParams.value.keyword.trim();
queryParams.value.keyword = keyword;
appliedSessionKeyword.value = keyword;
queryParams.value.pageNumber = 1;
void fetchSessions();
}
function handleAssistantChange() {
queryParams.value.pageNumber = 1;
void fetchSessions();
}
async function openSession(sessionId: string | number) {
drawerLoading.value = true;
const [, summaryRes] = await tryit(api.get)(
@@ -387,13 +395,16 @@ function formatTime(value?: string) {
placeholder="筛选聊天助理"
:options="assistantList"
class="!w-[220px]"
@change="fetchSessions"
@change="handleAssistantChange"
/>
<ElInput
v-model="queryParams.keyword"
class="max-w-[320px]"
placeholder="搜索标题或最近消息"
clearable
placeholder="搜索标题、最近消息或助理"
:prefix-icon="Search"
@clear="handleSessionSearch"
@keyup.enter="handleSessionSearch"
/>
</div>
</ElSpace>