Files
airz-uniapp/services/assessment.uts
T
hujun dcf12a4471 refactor: 重构存储与接口适配,统一金额单位与会话管理
- 新增配置、存储、金额转换工具服务
- 按userId隔离本地缓存,替换旧设备级存储
- 统一移动端金额单位为万元,新增转换适配逻辑
- 重构认证与请求逻辑,支持真实后端会话
- 调整搜索、帮助、融资模块的模拟开关与数据适配
- 更新文档说明开发状态与配置规则
2026-09-22 17:25:52 +08:00

131 lines
9.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { getUserStorage, setUserStorage } from '@/services/storage.uts'
import { wanAmountValid, yuanToWan, wanToYuan } from './money.uts'
export type AssessmentForm = {
name: string, idCard: string, phone: string, city: string, maritalStatus: string,
occupation: string, company: string, monthlyIncome: string, socialSecurity: string,
housingFund: 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
}
export type SelectedDocument = { name: string, path: string }
export type DataAuthorization = { key: string, name: string, selected: boolean }
export function emptyAssessmentForm(): AssessmentForm {
return { name: '', idCard: '', phone: '', city: '', maritalStatus: '', occupation: '', company: '', monthlyIncome: '', socialSecurity: '', housingFund: '', house: '', car: '', savings: '', creditCard: '', otherAssets: '', creditLoanCount: '', totalDebtBalance: '', monthlyLoanPayment: '', creditCardCount: '', creditCardTotalLimit: '', creditCardUsedLimit: '', enterpriseName: '', businessCode: '', annualRevenue: '', operatingYears: '' }
}
export function draftText(saved: UTSJSONObject, key: string): string {
const value = saved[key]
return typeof value == 'string' ? value as string : ''
}
export function activeAssessmentType(): string {
const type = getUserStorage('assessmentActiveType')
if (type == 'enterprise' || type == 'personal') return type as string
const legacy = getUserStorage('assessmentDraft')
if (legacy != null && typeof legacy == 'object' && draftText(legacy as UTSJSONObject, 'type') == 'enterprise') return 'enterprise'
return 'personal'
}
export function loadAssessmentDraft(type: string): UTSJSONObject | null {
const scoped = getUserStorage('assessmentDraft:' + type)
if (scoped != null && typeof scoped == 'object') return normalizeAssessmentDraft(scoped as UTSJSONObject)
const legacy = getUserStorage('assessmentDraft')
if (legacy != null && typeof legacy == 'object') {
const saved = legacy as UTSJSONObject
if (draftText(saved, 'type') == type) return normalizeAssessmentDraft(saved)
}
return null
}
export function normalizeAssessmentDraft(saved: UTSJSONObject): UTSJSONObject {
if (saved['moneyUnit'] == 'wan') return saved
const result: UTSJSONObject = { ...saved, moneyUnit: 'wan', draftVersion: 2 }
// 老草稿只有年营收以万元保存,其余金额均为元;只转换一次。
const keys = ['monthlyIncome', 'totalDebtBalance', 'monthlyLoanPayment', 'creditCardTotalLimit', 'creditCardUsedLimit']
if (saved['moneyUnit'] == 'yuan') keys.push('annualRevenue')
keys.forEach((key) => { result[key] = yuanToWan(draftText(saved, key)) })
return result
}
export function assessmentApiPayload(saved: UTSJSONObject): UTSJSONObject {
const normalized = normalizeAssessmentDraft(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) : ''
})
return result
}
export function formFromDraft(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'),
house: ownershipFromDraft(saved, 'house'), car: ownershipFromDraft(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')
}
}
export function ownershipFromDraft(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 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 万元,最多六位小数'
}
return ''
}
export function documentsFromDraft(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')
if (name.length > 0 && path.length > 0) { const document: SelectedDocument = { name, path }; results.push(document) }
})
return results
}
export function saveAssessmentDraft(type: string, step: number, form: AssessmentForm, documents: SelectedDocument[], authorizations: DataAuthorization[], documentConsent: boolean, dataConsent: boolean): void {
const files: UTSJSONObject[] = documents.map((item): UTSJSONObject => ({ name: item.name, path: item.path }))
const grants: string[] = authorizations.filter((item) => item.selected).map((item) => item.key)
const payload: UTSJSONObject = {
type, step, moneyUnit: 'wan', draftVersion: 2, 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,
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,
documents: files, authorizations: grants, documentConsent, dataConsent
}
setUserStorage('assessmentActiveType', type)
setUserStorage('assessmentDraft:' + type, payload)
// 保留现有提交与档案入口读取的活动草稿。
setUserStorage('assessmentDraft', payload)
}
export function showAgreementNotice(title: string): void {
uni.showModal({ title, content: '完整协议将在相关服务开放时提供。当前勾选仅保存您的选择,不会发起实名认证、查询外部数据或上传资料。', showCancel: false, confirmText: '我知道了' })
}
export type AssessmentProgress = { percent: number, basicDone: boolean, incomeDone: boolean, assetsDone: boolean, authorizationSelected: boolean }
export function assessmentProgress(type: string): AssessmentProgress {
const saved = loadAssessmentDraft(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', 'operatingYears', '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(formFromDraft(saved)).length == 0, authorizationSelected: documentsFromDraft(saved).length > 0 || (grants != null && grants.length > 0) }
}