/** * 功能:为资源表单和详情页加载、缓存并搜索关联资源选项。 * 版本:v1.0.0 */ import { Message } from '@arco-design/web-vue'; import { reactive } from 'vue'; import { resourceApi } from '@/api/resource'; import type { ResourceField } from '@/api/resources'; import type { ResourceRow } from '@/api/resource-page-rules'; export function useResourceRelations() { const options = reactive>({}); const loading = reactive>({}); const timers = new Map>(); /** 加载一类关联资源,工作人员关系默认只选择配送人员。 */ async function load(resource: string, keyword = '') { loading[resource] = true; try { const filters: Record = keyword ? { keyword } : {}; if (resource === '/staff_account') filters.role_code = 'delivery'; options[resource] = ( await resourceApi.list(resource, 1, 100, filters) ).list; } catch (error) { Message.error(`关联数据加载失败:${(error as Error).message}`); } finally { loading[resource] = false; } } /** 预加载当前页面实际使用的全部关系字段。 */ async function preload(fields: ResourceField[]) { const resources = new Set( fields .map((field) => field.relation) .filter((value): value is string => Boolean(value)), ); await Promise.all([...resources].map((resource) => load(resource))); } /** 对远程关系选项进行防抖搜索。 */ function search(resource: string | undefined, keyword: string) { if (!resource) return; const timer = timers.get(resource); if (timer) clearTimeout(timer); timers.set( resource, setTimeout(() => load(resource, keyword.trim()), 250), ); } return { options, loading, load, preload, search }; }