You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
4.0 KiB
JavaScript

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()
}),
)
}