import { getCompanyRisk, searchCompanyPage } from '@/api/company.js' import { encryptAesEcb } from '@/utils/aesEcb.js' const healthCache = new Map() const healthInflight = new Map() const listLen = (value) => (Array.isArray(value) ? value.length : 0) const personIdCard = (row) => String(row?.idCard || '').trim() const mapPool = async (items, limit, mapper) => { const result = new Array(items.length) let cursor = 0 const worker = async () => { while (cursor < items.length) { const index = cursor cursor += 1 result[index] = await mapper(items[index], index) } } const size = Math.min(Math.max(limit, 1), items.length || 1) await Promise.all(Array.from({ length: size }, () => worker())) return result } const fetchCompanyList = async (zjhm) => { const pageSize = 50 let pageNum = 1 let all = [] let total = 0 while (pageNum <= 10) { const res = await searchCompanyPage({ zjhm, pageNum, pageSize }) const list = Array.isArray(res?.data) ? res.data : [] total = Number(res?.count) || 0 all = all.concat(list) if (list.length < pageSize || (total > 0 && all.length >= total)) break pageNum += 1 } return all } const buildHealth = (companies, risks) => { let violation = 0 let undeclare = 0 let owing = 0 let abnormal = 0 const details = companies.map((company, index) => { const risk = risks[index] || null const nsr = risk?.nsrxx || {} const wfwz = listLen(risk?.wfwzxxList) const wsb = listLen(risk?.sfzwsbList) + listLen(risk?.cwbbwsbList) const qj = listLen(risk?.sfqjxxList) violation += wfwz undeclare += wsb owing += qj const ztDm = String(nsr.nsrztDm || company.nsrztDm || '') if (ztDm && ztDm !== '03') abnormal += 1 return { nsrmc: nsr.nsrmc || company.nsrmc || '', nsrsbh: nsr.shxydm || nsr.nsrsbh || company.nsrsbh || '', djxh: nsr.djxh || company.djxh || '', nsrztDm: ztDm, nsrztmc: nsr.nsrztmc || '', fddbrxm: nsr.fddbrxm || company.fddbrxm || '', violation: wfwz, undeclare: wsb, owing: qj, } }) return { companyCount: companies.length, abnormal, violation, undeclare, owing, details, } } const queryPersonHealth = async (idCard) => { const zjhm = encryptAesEcb(idCard) const companies = await fetchCompanyList(zjhm) const risks = await mapPool(companies, 3, async (company) => { const djxh = String(company?.djxh || '').trim() if (!djxh) return null try { const res = await getCompanyRisk({ zjhm, djxh: encryptAesEcb(djxh), }) return res?.data || null } catch (error) { return null } }) return buildHealth(companies, risks) } export const getHealthState = (row) => { const idCard = personIdCard(row) if (!idCard) { return { unavailable: true, reason: '无身份证,暂无法体检' } } if (healthCache.has(idCard)) { return healthCache.get(idCard) } return { loading: true } } export const loadHealthForRecords = async (records, onUpdate) => { const list = Array.isArray(records) ? records : [] const need = [] const seen = new Set() list.forEach((row) => { const idCard = personIdCard(row) if (!idCard || seen.has(idCard)) return seen.add(idCard) if (healthCache.has(idCard) || healthInflight.has(idCard)) return need.push(idCard) }) if (!need.length) return if (typeof onUpdate === 'function') onUpdate() await Promise.all( need.map(async (idCard) => { const task = queryPersonHealth(idCard) .then((health) => { healthCache.set(idCard, health) return health }) .catch(() => { const failed = { queryFail: true, reason: '体检查询失败' } healthCache.set(idCard, failed) return failed }) .finally(() => { healthInflight.delete(idCard) }) healthInflight.set(idCard, task) await task if (typeof onUpdate === 'function') onUpdate() }), ) }