From c85370d925401c800961e9573b12b9c12d535e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E5=BA=86=E6=B3=B0?= <12369755+htcloud1@user.noreply.gitee.com> Date: Thu, 20 Aug 2026 22:20:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=8D=95=E4=BD=8D?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E6=94=B9=20el-select=20=E5=A4=9A=E9=80=89=20?= =?UTF-8?q?(=E5=89=8D=E7=AB=AF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit manager/Projects.vue 顶部筛选区的「支持单位」从 el-input 升级为 el-select multiple + 远程搜索。 改动: - L6: el-input → el-select (multiple + filterable + remote + clearable + collapse-tags + collapse-tags-tooltip) - v-model: q.sponsorOrgName (string) → q.sponsorAdminUserIds (number[]) - remote-method: searchSponsorOrgsForFilter (新增) - loading: sponsorSearching (新增) - width: 260px (比输入框宽, 容纳标签) - L291: q ref 字段重命名 + 改类型 - L341: reset() 同步 - 新增: sponsorSearching ref (loading 指示) - 新增: _supporterFilterTimer (filter 防抖, 与 assignForm 的 _supporterTimer 分离) - 新增: searchSponsorOrgsForFilter(query) — 复用 listSponsorOrgs + sponsorOrgOptions - 200ms debounce - 已选项不在结果里时按 userId 单独拉回 (multi-select 必须保证每个 tag 都有 label) 未做 / 后续: - 执行方 (execOrgName) 同样可改多选, 沿用本次模式即可, 暂不动 - q.sponsorOrgName 字段已从源消失, 注释提到「sponsorOrgName」的 _self/manager_projects.md 待同步 (下一 commit) --- ry-vue3/src/views/manager/Projects.vue | 52 ++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/ry-vue3/src/views/manager/Projects.vue b/ry-vue3/src/views/manager/Projects.vue index d1a87dc..ece7eda 100644 --- a/ry-vue3/src/views/manager/Projects.vue +++ b/ry-vue3/src/views/manager/Projects.vue @@ -3,7 +3,23 @@ - + + + + + @@ -288,7 +304,7 @@ const userStore = useUserStore() const router = useRouter() const route = useRoute() -const q = ref({ sponsorOrgName: '', execOrgName: '', projectNo: '', projectName: '', projectForm: '', startTime: '', endTime: '', isFinished: '', isSettled: '', managerScore: '' }) +const q = ref({ sponsorAdminUserIds: [], execOrgName: '', projectNo: '', projectName: '', projectForm: '', startTime: '', endTime: '', isFinished: '', isSettled: '', managerScore: '' }) const rows = ref([]) const loading = ref(false) const page = reactive({ pageNum: 1, pageSize: 10, total: 0 }) @@ -338,7 +354,7 @@ async function doDelete(row) { } } -function reset() { q.value = { sponsorOrgName:'', execOrgName:'', projectNo:'', projectName:'', projectForm:'', startTime:'', endTime:'', isFinished:'', isSettled:'', managerScore:'' }; page.pageNum = 1; load() } +function reset() { q.value = { sponsorAdminUserIds:[], execOrgName:'', projectNo:'', projectName:'', projectForm:'', startTime:'', endTime:'', isFinished:'', isSettled:'', managerScore:'' }; page.pageNum = 1; load() } // 导出 function exportProjects() { ElMessage.info('导出项目功能开发中') } @@ -627,7 +643,10 @@ const assignForm = reactive({ deadlineDays: 30 }) const sponsorOrgOptions = ref([]) +const sponsorSearching = ref(false) let _supporterTimer = null +let _supporterFilterTimer = null + // 已分配场次合计 (实时) const assignedSessions = computed(() => @@ -701,6 +720,33 @@ async function loadSponsorOrgs(query) { function searchSponsorOrgs(q) { loadSponsorOrgs(q) } +// 顶部筛选区远程搜索 (多选 el-select, 复用 sponsorOrgOptions, 加 loading + 已选项重拉回) +function searchSponsorOrgsForFilter(query) { + if (_supporterFilterTimer) clearTimeout(_supporterFilterTimer) + sponsorSearching.value = true + _supporterFilterTimer = setTimeout(async () => { + try { + const params = {} + if (query) params.orgName = query + const r = await listSponsorOrgs(params) + sponsorOrgOptions.value = r.data || [] + // 已选项不在结果里时按 userId 单独拉回 (multi-select 必须保证每个已选 tag 都有 label) + const ids = q.value.sponsorAdminUserIds || [] + for (const uid of ids) { + if (!sponsorOrgOptions.value.find(u => u.userId === uid)) { + const r2 = await listSponsorOrgs({ userId: uid }) + const sel = (r2.data || []).find(u => u.userId === uid) + if (sel) sponsorOrgOptions.value = [sel, ...sponsorOrgOptions.value] + } + } + } catch (e) { + sponsorOrgOptions.value = [] + } finally { + sponsorSearching.value = false + } + }, 200) +} + // 选中支持方后回填 user_name (缓存到 biz_project.sponsor_admin_user_name) function onSponsorOrgPick(userId) { const u = sponsorOrgOptions.value.find(x => x.userId === userId)