feat: 支持评估版本隔离的报告、匹配及PDF导出功能
新增revisionId参数到路由、服务及导出接口,实现不同评估版本的隔离访问。删除已废弃的需求相关服务文件,移除取消采集的融资金额、期限和用途字段,更新相关页面提示文本。同时更新文档,说明评估版本、最新资料及产品展示规则的调整,支持前台正常业务名称显示,去除环境标签。
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
import { requestJson } from './api.uts'
|
||||
import { wanAmountValid, wanToCents } from './money.uts'
|
||||
|
||||
export type FinancingPurpose = { type: string, code: string, label: string, requiresDetail: boolean }
|
||||
|
||||
// 用途由服务端发布;加载失败时提示重试,不用本机猜测字典后提交。
|
||||
export async function fetchFinancingPurposes(): Promise<FinancingPurpose[]> {
|
||||
const result = await requestJson('/dictionaries', 'GET', {})
|
||||
const versions = result['assessmentInputVersions'] as number[] | null
|
||||
const minimum = result['minNewAssessmentInputVersion'] as number | null
|
||||
if (versions == null || !versions.includes(2) || minimum == null || minimum > 2) throw new Error('评估版本已更新,请刷新页面后重试')
|
||||
const dictionary = result['financingPurposes'] as UTSJSONObject | null
|
||||
if (dictionary == null) throw new Error('资金用途暂不可用,请重试')
|
||||
const items = dictionary['items'] as UTSJSONObject[] | null
|
||||
if (items == null) throw new Error('资金用途暂不可用,请重试')
|
||||
const purposes: FinancingPurpose[] = []
|
||||
items.forEach((item: UTSJSONObject) => {
|
||||
if (item['enabled'] == true) purposes.push({ type: item['type'] as string, code: item['code'] as string, label: item['label'] as string, requiresDetail: item['requiresDetail'] == true } as FinancingPurpose)
|
||||
})
|
||||
if (purposes.length == 0) throw new Error('资金用途暂不可用,请重试')
|
||||
return purposes
|
||||
}
|
||||
|
||||
export function demandValidationMessage(amount: string, term: string, code: string, detail: string): string {
|
||||
if (!wanAmountValid(amount) || wanToCents(amount) <= 0) return '请填写大于零的融资金额(万元,最多六位小数)'
|
||||
if (!/^[1-9][0-9]{0,3}$/.test(term)) return '融资期限请输入1至9999的整数月'
|
||||
if (code.length == 0) return '请选择资金用途'
|
||||
if (code == 'other' && (detail.trim().length < 2 || detail.trim().length > 200 || /[<>\x00-\x1f\x7f]/.test(detail))) return '其他用途请填写2至200字说明,不含标签或控制字符'
|
||||
if (code != 'other' && detail.length > 0) return '仅其他用途需要填写说明'
|
||||
return ''
|
||||
}
|
||||
@@ -9,14 +9,13 @@ export type AssessmentForm = {
|
||||
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, operatingMonths: string,
|
||||
requestedAmountWan: string, requestedTermMonths: string, purposeCode: string, purposeLabel: string, purposeDetail: string
|
||||
otherAssets: string, enterpriseName: string, businessCode: string, annualRevenue: string, operatingYears: string, operatingMonths: 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: '', operatingMonths: '', requestedAmountWan: '', requestedTermMonths: '', purposeCode: '', purposeLabel: '', purposeDetail: '' }
|
||||
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: '', operatingMonths: '' }
|
||||
}
|
||||
export function draftText(saved: UTSJSONObject, key: string): string {
|
||||
const value = saved[key]
|
||||
@@ -48,8 +47,7 @@ export function formFromInput(saved: UTSJSONObject): AssessmentForm {
|
||||
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'),
|
||||
requestedAmountWan: draftText(saved, 'requestedAmountWan'), requestedTermMonths: draftText(saved, 'requestedTermMonths'), purposeCode: draftText(saved, 'purposeCode'), purposeLabel: draftText(saved, 'purposeLabel'), purposeDetail: draftText(saved, 'purposeDetail')
|
||||
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 {
|
||||
@@ -83,17 +81,16 @@ export function documentsFromInput(saved: UTSJSONObject): SelectedDocument[] {
|
||||
})
|
||||
return results
|
||||
}
|
||||
export function setAssessmentInput(type: string, step: number, form: AssessmentForm, documents: SelectedDocument[], authorizations: DataAuthorization[], documentConsent: boolean, dataConsent: boolean): void {
|
||||
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: item.path }))
|
||||
const grants: string[] = authorizations.filter((item) => item.selected).map((item) => item.key)
|
||||
const payload: UTSJSONObject = {
|
||||
type, step, moneyUnit: 'wan', name: form.name, idCard: form.idCard, phone: form.phone, city: form.city, maritalStatus: form.maritalStatus,
|
||||
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,
|
||||
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,
|
||||
requestedAmountWan: form.requestedAmountWan, requestedTermMonths: form.requestedTermMonths, purposeCode: form.purposeCode, purposeLabel: form.purposeLabel, purposeDetail: form.purposeDetail,
|
||||
documents: files, authorizations: grants, documentConsent, dataConsent
|
||||
}
|
||||
writeAssessmentFlow(flowToken(), payload)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// 登录返回只允许助手路由与编号;拒绝任意returnUrl,重新登录后仍由服务端校验归属。
|
||||
export function assistantReturnPath(assessmentId: string, productIds: string, chatId: string, from: string): string {
|
||||
export function assistantReturnPath(assessmentId: string, productIds: string, chatId: string, from: string, revisionId: string = ''): string {
|
||||
const valid = (id: string): boolean => /^[1-9][0-9]{0,9}$/.test(id)
|
||||
if ((assessmentId.length > 0 && !valid(assessmentId)) || (chatId.length > 0 && !valid(chatId))) return ''
|
||||
const ids = productIds.length == 0 ? [] as string[] : productIds.split(',')
|
||||
@@ -7,5 +7,6 @@ export function assistantReturnPath(assessmentId: string, productIds: string, ch
|
||||
const seen: string[] = []
|
||||
for (let i = 0; i < ids.length; i++) { if (!valid(ids[i]) || seen.includes(ids[i])) return ''; seen.push(ids[i]) }
|
||||
if (!['','matches','product','compare','report','next-step','archive'].includes(from)) return ''
|
||||
return '/packages/finance/assistant/assistant?from=' + from + (assessmentId.length > 0 ? '&assessmentId=' + assessmentId + '&productIds=' + productIds : '') + (chatId.length > 0 ? '&chatId=' + chatId : '')
|
||||
if (revisionId.length > 0 && !/^[1-9][0-9]{0,9}$/.test(revisionId)) return ''
|
||||
return '/packages/finance/assistant/assistant?from=' + from + (assessmentId.length > 0 ? '&assessmentId=' + assessmentId + '&productIds=' + productIds : '') + (chatId.length > 0 ? '&chatId=' + chatId : '') + (revisionId.length > 0 ? '&revisionId=' + revisionId : '')
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 登录回跳只接受固定页面和白名单参数,不接受外部 URL;页面仍需重新鉴权。
|
||||
export function nextStepRoute(assessmentId: string, productId: string = '', section: string = 'actions'): string {
|
||||
export function nextStepRoute(assessmentId: string, productId: string = '', section: string = 'actions', revisionId: string = ''): string {
|
||||
const valid = (id: string): boolean => /^[1-9][0-9]{0,9}$/.test(id)
|
||||
if (!valid(assessmentId) || (productId.length > 0 && !valid(productId)) || !['actions', 'prepare'].includes(section)) return ''
|
||||
return '/packages/finance/next-step/next-step?assessmentId=' + assessmentId + (productId.length > 0 ? '&productId=' + productId : '') + '§ion=' + section
|
||||
if (revisionId.length > 0 && !/^[1-9][0-9]{0,9}$/.test(revisionId)) return ''
|
||||
return '/packages/finance/next-step/next-step?assessmentId=' + assessmentId + (productId.length > 0 ? '&productId=' + productId : '') + '§ion=' + section + (revisionId.length > 0 ? '&revisionId=' + revisionId : '')
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// 登录后只恢复本人报告的编号和栏目,不接受任意回跳URL。
|
||||
export function reportRoute(assessmentId: string, tab: string = 'overview'): string {
|
||||
export function reportRoute(assessmentId: string, tab: string = 'overview', revisionId: string = ''): string {
|
||||
if (!/^[1-9][0-9]{0,9}$/.test(assessmentId) || !['overview', 'matches', 'improvements'].includes(tab)) return ''
|
||||
return '/packages/finance/report/report?assessmentId=' + assessmentId + '&tab=' + tab
|
||||
if (revisionId.length > 0 && !/^[1-9][0-9]{0,9}$/.test(revisionId)) return ''
|
||||
return '/packages/finance/report/report?assessmentId=' + assessmentId + '&tab=' + tab + (revisionId.length > 0 ? '&revisionId=' + revisionId : '')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user