import { getSession } from './api.uts' import { readAssessmentFlow, writeAssessmentFlow, clearAssessmentFlow } from './assessment-flow.uts' export { clearAssessmentFlow } from './assessment-flow.uts' import { contributionBaseVisible, contributionBaseValid, contributionBaseYuan } from './contribution.uts' import { wanAmountValid, wanToYuan, wanToCents } from './money.uts' import { showAgreementNotice as openAgreementNotice } from './agreements.uts' export type AssessmentForm = { name: string, idCard: string, phone: string, city: string, maritalStatus: string, occupation: string, company: string, monthlyIncome: string, socialSecurity: string, housingFund: string, socialSecurityBase: string, housingFundBase: string, house: string, car: string, savings: string, creditCard: string, creditLoanCount: string, totalDebtBalance: string, monthlyLoanPayment: string, creditCardCount: string, creditCardTotalLimit: string, creditCardUsedLimit: string, otherAssets: string, enterpriseName: string, businessCode: string, annualRevenue: string, operatingYears: string, operatingMonths: string } export type SelectedDocument = { name: string, path: string, documentId: string, consentId: string, deletePending: boolean } export type DataAuthorization = { key: string, name: string, selected: boolean } export function emptyAssessmentForm(): AssessmentForm { return { name: '', idCard: '', phone: '', city: '', maritalStatus: '', occupation: '', company: '', monthlyIncome: '', socialSecurity: '', housingFund: '', socialSecurityBase: '', housingFundBase: '', house: '', car: '', savings: '', creditCard: '', otherAssets: '', creditLoanCount: '', totalDebtBalance: '', monthlyLoanPayment: '', creditCardCount: '', creditCardTotalLimit: '', creditCardUsedLimit: '', enterpriseName: '', businessCode: '', annualRevenue: '', operatingYears: '', operatingMonths: '' } } export function draftText(saved: UTSJSONObject, key: string): string { const value = saved[key] return typeof value == 'string' ? value as string : '' } function flowToken(): string { const session = getSession(); return session == null ? '' : session['token'] as string } export function activeAssessmentType(): string { const current = readAssessmentFlow(flowToken()) return current == null ? 'personal' : draftText(current, 'type') } export function getAssessmentInput(type: string): UTSJSONObject | null { const current = readAssessmentFlow(flowToken()) return current != null && current['type'] == type ? current : null } export function assessmentApiPayload(saved: UTSJSONObject): UTSJSONObject { const normalized = saved const result: UTSJSONObject = { ...normalized, moneyUnit: 'yuan' } const keys = ['annualRevenue', 'monthlyIncome', 'totalDebtBalance', 'monthlyLoanPayment', 'creditCardTotalLimit', 'creditCardUsedLimit'] keys.forEach((key) => { const value = draftText(normalized, key) result[key] = value.length > 0 ? wanToYuan(value) : '' }) const baseKeys = ['socialSecurityBase', 'housingFundBase'] baseKeys.forEach((key) => { const value = draftText(normalized, key); result[key] = value.length > 0 ? contributionBaseYuan(value) : '' }) return result } export function formFromInput(saved: UTSJSONObject): AssessmentForm { return { name: draftText(saved, 'name'), idCard: draftText(saved, 'idCard'), phone: draftText(saved, 'phone'), city: draftText(saved, 'city'), maritalStatus: draftText(saved, 'maritalStatus'), occupation: draftText(saved, 'occupation'), company: draftText(saved, 'company'), monthlyIncome: draftText(saved, 'monthlyIncome'), socialSecurity: draftText(saved, 'socialSecurity'), housingFund: draftText(saved, 'housingFund'), socialSecurityBase: draftText(saved, 'socialSecurityBase'), housingFundBase: draftText(saved, 'housingFundBase'), house: ownershipFromInput(saved, 'house'), car: ownershipFromInput(saved, 'car'), savings: draftText(saved, 'savings'), creditCard: draftText(saved, 'creditCard'), otherAssets: draftText(saved, 'otherAssets'), creditLoanCount: draftText(saved, 'creditLoanCount'), totalDebtBalance: draftText(saved, 'totalDebtBalance'), monthlyLoanPayment: draftText(saved, 'monthlyLoanPayment'), creditCardCount: draftText(saved, 'creditCardCount'), creditCardTotalLimit: draftText(saved, 'creditCardTotalLimit'), creditCardUsedLimit: draftText(saved, 'creditCardUsedLimit'), enterpriseName: draftText(saved, 'enterpriseName'), businessCode: draftText(saved, 'businessCode'), annualRevenue: draftText(saved, 'annualRevenue'), operatingYears: draftText(saved, 'operatingYears'), operatingMonths: draftText(saved, 'operatingMonths') } } export function ownershipFromInput(saved: UTSJSONObject, key: string): string { const value = draftText(saved, key) if (value == '有' || value == '无') return value if (value == '无房产' || value == '无车辆') return '无' if (['全款房产', '按揭房产', '全款车辆', '按揭车辆'].includes(value)) return '有' return '' } export function contributionValidationMessage(form: AssessmentForm): string { const bases = [form.socialSecurityBase, form.housingFundBase] const durations = [form.socialSecurity, form.housingFund] const labels = ['社保', '公积金'] for (let i = 0; i < bases.length; i++) { if (bases[i].length == 0) continue if (!contributionBaseVisible(durations[i])) return labels[i] + '基数须与缴纳情况一致' if (!contributionBaseValid(bases[i])) return labels[i] + '基数请输入大于 0 的万元金额,最多六位小数' } return '' } export function assetValidationMessage(form: AssessmentForm): string { const counts = [form.creditLoanCount, form.creditCardCount] const countLabels = ['信用贷款笔数', '银行信用卡张数'] for (let i = 0; i < counts.length; i++) { if (counts[i].length > 0 && !/^[0-9]{1,4}$/.test(counts[i])) return countLabels[i] + '请输入非负整数' } const amounts = [form.totalDebtBalance, form.monthlyLoanPayment, form.creditCardTotalLimit, form.creditCardUsedLimit] const amountLabels = ['欠款总余额', '贷款月还款金额', '总额度', '已使用总额度'] for (let i = 0; i < amounts.length; i++) { if (amounts[i].length > 0 && !wanAmountValid(amounts[i])) return amountLabels[i] + '范围为 0–99999.999999 万元,最多六位小数' } if (form.creditCardTotalLimit.length > 0 && form.creditCardUsedLimit.length > 0 && wanToCents(form.creditCardUsedLimit) > wanToCents(form.creditCardTotalLimit)) return '信用卡已使用额度不能大于总额度' return '' } export function documentsFromInput(saved: UTSJSONObject): SelectedDocument[] { const results: SelectedDocument[] = [] const items = saved['documents'] as UTSJSONObject[] | null if (items == null) return results items.forEach((item) => { const name = draftText(item, 'name'); const path = draftText(item, 'path') const documentId = draftText(item, 'documentId'); const consentId = draftText(item, 'consentId') if (name.length > 0 && (path.length > 0 || documentId.length > 0)) { const document: SelectedDocument = { name, path, documentId, consentId, deletePending: item.getBoolean('deletePending') ?? false }; results.push(document) } }) return results } export function setAssessmentInput(type: string, step: number, form: AssessmentForm, documents: SelectedDocument[], authorizations: DataAuthorization[], documentConsent: boolean, dataConsent: boolean, editAssessmentId: string = '', baseRevisionId: string = ''): void { const files: UTSJSONObject[] = documents.map((item): UTSJSONObject => ({ name: item.name, path: '', documentId: item.documentId, consentId: item.consentId, deletePending: item.deletePending })) const grants: string[] = authorizations.filter((item) => item.selected).map((item) => item.key) const payload: UTSJSONObject = { type, step, editAssessmentId, baseRevisionId, moneyUnit: 'wan', name: form.name, idCard: form.idCard, phone: form.phone, city: form.city, maritalStatus: form.maritalStatus, occupation: form.occupation, company: form.company, monthlyIncome: form.monthlyIncome, socialSecurity: form.socialSecurity, housingFund: form.housingFund, socialSecurityBase: form.socialSecurityBase, housingFundBase: form.housingFundBase, house: form.house, car: form.car, savings: form.savings, creditCard: form.creditCard, otherAssets: form.otherAssets, creditLoanCount: form.creditLoanCount, totalDebtBalance: form.totalDebtBalance, monthlyLoanPayment: form.monthlyLoanPayment, creditCardCount: form.creditCardCount, creditCardTotalLimit: form.creditCardTotalLimit, creditCardUsedLimit: form.creditCardUsedLimit, enterpriseName: form.enterpriseName, businessCode: form.businessCode, annualRevenue: form.annualRevenue, operatingYears: form.operatingYears, operatingMonths: form.operatingMonths, documents: files, authorizations: grants, documentConsent, dataConsent } writeAssessmentFlow(flowToken(), payload) } export function showAgreementNotice(title: string): void { openAgreementNotice(title) } export type AssessmentProgress = { percent: number, basicDone: boolean, incomeDone: boolean, assetsDone: boolean, authorizationSelected: boolean } export function assessmentProgress(type: string): AssessmentProgress { const saved = getAssessmentInput(type) if (saved == null) return { percent: 0, basicDone: false, incomeDone: false, assetsDone: false, authorizationSelected: false } const basic = type == 'enterprise' ? ['enterpriseName', 'businessCode', 'name', 'phone', 'city'] : ['name', 'idCard', 'phone', 'city', 'maritalStatus'] const income = type == 'enterprise' ? ['occupation', 'operatingMonths', 'annualRevenue'] : ['occupation', 'company', 'monthlyIncome', 'socialSecurity', 'housingFund'] const assets = ['house', 'car', 'creditLoanCount', 'totalDebtBalance', 'monthlyLoanPayment', 'creditCardCount', 'creditCardTotalLimit', 'creditCardUsedLimit'] const keys = basic.concat(income).concat(assets) const filled = keys.filter((key) => draftText(saved, key).trim().length > 0).length const grants = saved['authorizations'] as string[] | null return { percent: Math.round(filled / keys.length * 100), basicDone: basic.every((key) => draftText(saved, key).length > 0), incomeDone: income.every((key) => draftText(saved, key).length > 0), assetsDone: assets.every((key) => draftText(saved, key).trim().length > 0) && assetValidationMessage(formFromInput(saved)).length == 0, authorizationSelected: documentsFromInput(saved).length > 0 || (grants != null && grants.length > 0) } }