import { carrierApi, personnelApi, vehicleApi, type Carrier, type Personnel, type PersonnelQuery, type Vehicle, type VehicleDetail, type VehicleQuery } from '@/api/pl' import { pickBxData, pickBxList } from '@/utils/http/bx' const REMOTE_PAGE_SIZE = 100 type IdItem = { id: string } function keepSelected( rows: T[], selectedId: string | undefined, currentList: T[] ): T[] { if (!selectedId) return rows if (rows.some(item => item.id === selectedId)) return rows const kept = currentList.find(item => item.id === selectedId) return kept ? [kept, ...rows] : rows } function keepSelectedByPlate( rows: Vehicle[], selectedPlate: string | undefined, currentList: Vehicle[] ): Vehicle[] { const plate = selectedPlate?.trim() if (!plate) return rows if (rows.some(item => item.licensePlate === plate)) return rows const kept = currentList.find(item => item.licensePlate === plate) return kept ? [kept, ...rows] : rows } /** 车辆下拉:服务端按车牌 q 检索 */ export function usePlRemoteVehicleOptions(options?: { getSelectedId?: () => string | undefined getSelectedPlate?: () => string | undefined /** 默认按 id 保留已选项;选车牌字符串时传 licensePlate */ valueMode?: 'id' | 'licensePlate' listParams?: Omit }) { const list = ref([]) const loading = ref(false) const loaded = ref(false) const valueMode = options?.valueMode ?? 'id' async function search(keyword: string) { loading.value = true try { const res = await vehicleApi.list({ ...(options?.listParams || {}), ...(keyword.trim() ? { q: keyword.trim() } : {}), page: 1, pageSize: REMOTE_PAGE_SIZE }) const rows = pickBxList(res) list.value = valueMode === 'licensePlate' ? keepSelectedByPlate(rows, options?.getSelectedPlate?.(), list.value) : keepSelected(rows, options?.getSelectedId?.(), list.value) loaded.value = true } catch (error) { console.error('加载车辆选项失败', error) list.value = [] } finally { loading.value = false } } function onFocus() { if (!loaded.value) void search('') } function reset() { list.value = [] loaded.value = false } async function ensureById(vehicleId: string) { if (!vehicleId || list.value.some(item => item.id === vehicleId)) return try { const res = await vehicleApi.get(vehicleId) const detail = pickBxData(res) if (detail?.id) list.value = [detail, ...list.value] } catch { // ignore } } return { list, loading, loaded, search, onFocus, reset, ensureById } } /** 承运商下拉:服务端按 q 检索 */ export function usePlRemoteCarrierOptions(options?: { getSelectedId?: () => string | undefined listParams?: { status?: string; auditStatus?: string } }) { const list = ref([]) const loading = ref(false) const loaded = ref(false) async function search(keyword: string) { loading.value = true try { const res = await carrierApi.list({ ...(options?.listParams || {}), ...(keyword.trim() ? { q: keyword.trim() } : {}), page: 1, pageSize: REMOTE_PAGE_SIZE }) list.value = keepSelected( pickBxList(res), options?.getSelectedId?.(), list.value ) loaded.value = true } catch (error) { console.error('加载承运商选项失败', error) list.value = [] } finally { loading.value = false } } function onFocus() { if (!loaded.value) void search('') } function reset() { list.value = [] loaded.value = false } async function ensureById(carrierId: string) { if (!carrierId || list.value.some(item => item.id === carrierId)) return try { const res = await carrierApi.get(carrierId) const detail = pickBxData(res) if (detail?.id) list.value = [detail, ...list.value] } catch { // ignore } } return { list, loading, loaded, search, onFocus, reset, ensureById } } /** 人员下拉:服务端按姓名/手机号 q 检索 */ export function usePlRemotePersonnelOptions(options?: { getSelectedId?: () => string | undefined listParams?: Omit | (() => Omit) }) { const list = ref([]) const loading = ref(false) const loaded = ref(false) async function search(keyword: string) { loading.value = true try { const extra = typeof options?.listParams === 'function' ? options.listParams() : options?.listParams || {} const res = await personnelApi.list({ ...extra, ...(keyword.trim() ? { q: keyword.trim() } : {}), page: 1, pageSize: REMOTE_PAGE_SIZE }) list.value = keepSelected( pickBxList(res), options?.getSelectedId?.(), list.value ) loaded.value = true } catch (error) { console.error('加载人员选项失败', error) list.value = [] } finally { loading.value = false } } function onFocus() { if (!loaded.value) void search('') } function reset() { list.value = [] loaded.value = false } /** 切换归属等过滤条件后需重新拉取 */ function invalidate() { loaded.value = false } async function ensureById(personnelId: string) { if (!personnelId || list.value.some(item => item.id === personnelId)) return try { const res = await personnelApi.get(personnelId) const detail = pickBxData(res) if (detail?.id) list.value = [detail, ...list.value] } catch { // ignore } } return { list, loading, loaded, search, onFocus, reset, invalidate, ensureById } }