hookehuyr

refactor(PersonPickerField): 适配新后端人员类型数据格式优化处理逻辑

补充缺失的Vue组合式API导入,修复computed未导入的bug
重写人员类型归一化函数,适配后端返回的带title/value字段的新数据格式
移除硬编码的人员类型标签映射表,改为动态查找允许的类型选项
调整默认搜索类型逻辑,多类型场景默认显示全部类型并向后端传空字符串
修复搜索参数构建的代码bug,优化人员过滤的类型判断逻辑
简化整体代码结构,提升可维护性
...@@ -126,7 +126,7 @@ ...@@ -126,7 +126,7 @@
126 </template> 126 </template>
127 127
128 <script setup> 128 <script setup>
129 -import { inject, ref } from 'vue'; 129 +import { computed, inject, onMounted, ref } from 'vue';
130 import { useRoute } from 'vue-router'; 130 import { useRoute } from 'vue-router';
131 import { useCustomFieldValue } from '@vant/use'; 131 import { useCustomFieldValue } from '@vant/use';
132 import Cookies from 'js-cookie'; 132 import Cookies from 'js-cookie';
...@@ -204,15 +204,21 @@ const normalizeStoredPersonList = (value) => { ...@@ -204,15 +204,21 @@ const normalizeStoredPersonList = (value) => {
204 }; 204 };
205 205
206 /** 206 /**
207 - * 后端现在明确返回 person_types 数组,这里只做去重和空值过滤 207 + * 后端返回的人员类型配置已经自带 title/value,这里只做结构清洗和按 value 去重
208 * 208 *
209 - * @param {string[]} personTypes 人员类型数组 209 + * @param {Array} personTypes 人员类型配置
210 - * @returns {string[]} 210 + * @returns {{ title: string, value: string }[]}
211 */ 211 */
212 const normalizePersonTypes = (personTypes = []) => { 212 const normalizePersonTypes = (personTypes = []) => {
213 - return _.uniq(personTypes 213 + return _.uniqBy(
214 - .map((item) => String(item || '').trim()) 214 + personTypes
215 - .filter(Boolean)); 215 + .map((item) => ({
216 + title: String(item?.title || '').trim(),
217 + value: String(item?.value || '').trim(),
218 + }))
219 + .filter((item) => item.title && item.value),
220 + 'value',
221 + );
216 }; 222 };
217 223
218 /** 224 /**
...@@ -223,16 +229,16 @@ const syncFieldValue = () => { ...@@ -223,16 +229,16 @@ const syncFieldValue = () => {
223 props.value = fieldValue.value; 229 props.value = fieldValue.value;
224 }; 230 };
225 231
226 -/** 232 +const findPersonTypeOption = (type) => {
227 - * 人员类型的中文展示统一收口在这里,接口和筛选值仍保持英文原值。 233 + if (!type) {
228 - */ 234 + return null;
229 -const PERSON_TYPE_LABEL_MAP = { 235 + }
230 - volunteer: '义工', 236 +
231 - contact: '联系人', 237 + return allowedPersonTypes.value.find((item) => item.value === type) || null;
232 }; 238 };
233 239
234 const formatPersonType = (type) => { 240 const formatPersonType = (type) => {
235 - return PERSON_TYPE_LABEL_MAP[type] || type || '人员'; 241 + return findPersonTypeOption(type)?.title || type || '人员';
236 }; 242 };
237 243
238 const formatPersonTitle = (person) => { 244 const formatPersonTitle = (person) => {
...@@ -254,10 +260,10 @@ const allowedPersonTypes = computed(() => { ...@@ -254,10 +260,10 @@ const allowedPersonTypes = computed(() => {
254 }); 260 });
255 261
256 /** 262 /**
257 - * 当只允许一种人员类型时,默认锁定这个筛选值 263 + * 多类型字段默认停在“全部类型”,发请求时显式传空字符串给后端
258 */ 264 */
259 const defaultSearchType = computed(() => { 265 const defaultSearchType = computed(() => {
260 - return allowedPersonTypes.value.length === 1 ? allowedPersonTypes.value[0] : ''; 266 + return '';
261 }); 267 });
262 268
263 /** 269 /**
...@@ -268,9 +274,9 @@ const typeFilterOptions = computed(() => { ...@@ -268,9 +274,9 @@ const typeFilterOptions = computed(() => {
268 return []; 274 return [];
269 } 275 }
270 276
271 - const allowedOptions = allowedPersonTypes.value.map((type) => ({ 277 + const allowedOptions = allowedPersonTypes.value.map((typeOption) => ({
272 - text: formatPersonType(type), 278 + text: typeOption.title,
273 - value: type, 279 + value: typeOption.value,
274 })); 280 }));
275 281
276 if (allowedOptions.length === 1) { 282 if (allowedOptions.length === 1) {
...@@ -281,7 +287,7 @@ const typeFilterOptions = computed(() => { ...@@ -281,7 +287,7 @@ const typeFilterOptions = computed(() => {
281 }); 287 });
282 288
283 const getSearchType = () => { 289 const getSearchType = () => {
284 - return defaultSearchType.value || selectedTypeFilter.value || ''; 290 + return selectedTypeFilter.value || defaultSearchType.value || '';
285 }; 291 };
286 292
287 /** 293 /**
...@@ -294,7 +300,9 @@ const filterPersonListByType = (personList) => { ...@@ -294,7 +300,9 @@ const filterPersonListByType = (personList) => {
294 const searchType = getSearchType(); 300 const searchType = getSearchType();
295 301
296 return personList.filter((person) => { 302 return personList.filter((person) => {
297 - if (allowedPersonTypes.value.length && !allowedPersonTypes.value.includes(person.type)) { 303 + const allowedTypeValues = allowedPersonTypes.value.map((item) => item.value);
304 +
305 + if (allowedTypeValues.length && !allowedTypeValues.includes(person.type)) {
298 return false; 306 return false;
299 } 307 }
300 308
...@@ -412,6 +420,7 @@ const onSelectSearchType = async (action) => { ...@@ -412,6 +420,7 @@ const onSelectSearchType = async (action) => {
412 * 组装人员搜索接口参数。 420 * 组装人员搜索接口参数。
413 * 421 *
414 * @param {number} page 页码,从 0 开始 422 * @param {number} page 页码,从 0 开始
423 + * @param {string} searchType 本次请求对应的人员类型
415 * @returns {{ form_code: string, field_name: string, keyword: string, page: number, limit: number, type?: string, force_back?: string }} 424 * @returns {{ form_code: string, field_name: string, keyword: string, page: number, limit: number, type?: string, force_back?: string }}
416 */ 425 */
417 const buildSearchParams = (page) => { 426 const buildSearchParams = (page) => {
...@@ -421,12 +430,8 @@ const buildSearchParams = (page) => { ...@@ -421,12 +430,8 @@ const buildSearchParams = (page) => {
421 keyword: searchKeyword.value.trim(), 430 keyword: searchKeyword.value.trim(),
422 page, 431 page,
423 limit: searchLimit.value, 432 limit: searchLimit.value,
433 + type: getSearchType(),
424 }; 434 };
425 -
426 - const searchType = getSearchType();
427 - if (searchType) {
428 - params.type = searchType;
429 - }
430 if ($route.query.force_back) { 435 if ($route.query.force_back) {
431 params.force_back = $route.query.force_back; 436 params.force_back = $route.query.force_back;
432 } 437 }
......