- 新增微信小程序胶囊区域避让布局逻辑 - 统一首页导航与标题对齐规则 - 更新多处演示提示文案为正式表述 - 调整个人中心账户状态显示 - 优化产品页分享按钮条件渲染
121 lines
10 KiB
Plaintext
121 lines
10 KiB
Plaintext
<template>
|
|
<view class="page page-white" :style="pageStyle()">
|
|
<AppHeader title="确认信息" />
|
|
<scroll-view scroll-y :style="contentStyle(96, false)">
|
|
<view class="confirm-content">
|
|
<view class="confirm-progress"><view class="progress-line"><view class="progress-segment" v-for="i in 5" :key="i"></view></view><text class="progress-count">5/5</text></view>
|
|
<view class="confirm-tip"><view class="tip-icon"><text class="tip-mark">✓</text></view><view class="tip-copy"><text class="tip-title">{{ assessmentType == 'enterprise' ? '企业融资信息' : '个人融资信息' }}</text><text class="tip-desc">请确认后再开始评估,可随时返回修改。</text></view></view>
|
|
<text v-if="!hasDraft" class="empty-hint">还没有评估信息,请先完成信息填写。</text>
|
|
<view class="info-section" v-for="section in sections" :key="section.title"><view class="section-bar"><text class="section-name">{{ section.title }}</text><text class="edit" @click="edit(section.step)">编辑</text></view><template v-for="(row, index) in section.rows" :key="row.label"><view v-if="index < 3 || section.expanded" class="info-row"><text class="info-label">{{ row.label }}</text><text class="info-value">{{ row.value }}</text></view></template><text v-if="section.rows.length > 3" class="expand-link" @click="section.expanded = !section.expanded">{{ section.expanded ? '收起详情' : '查看其余信息' }}</text></view>
|
|
<text class="assessment-note">提交信息用于融资评估,不代表已向金融机构提交贷款申请。</text>
|
|
<view class="scroll-spacer" :style="bottomStyle(24)"></view>
|
|
</view>
|
|
</scroll-view>
|
|
<view class="submit-bar" :style="bottomStyle(20)"><button class="primary-button submit-button" :disabled="submitting" @click="submit">{{ !hasDraft ? '去填写信息' : (submitting ? '提交中…' : '确认并开始评估') }}</button></view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
import { usePageLayout } from '@/services/layout.uts'
|
|
import AppHeader from '@/components/AppHeader.uvue'
|
|
import { submitAssessment } from '@/packages/finance/services/api.uts'
|
|
import { activeAssessmentType, loadAssessmentDraft, draftText, documentsFromDraft } from '@/services/assessment.uts'
|
|
const { pageStyle, contentStyle, bottomStyle } = usePageLayout()
|
|
type InfoRow = { label: string, value: string }
|
|
type InfoSection = { title: string, step: number, rows: InfoRow[], expanded: boolean }
|
|
const submitting = ref(false)
|
|
const hasDraft = ref(false)
|
|
const assessmentType = ref('personal')
|
|
const sections = ref<InfoSection[]>([])
|
|
const payload = ref<UTSJSONObject>({ source: 'mobile', confirmed: false })
|
|
const mask = (value: string, left: number, right: number): string => { if (value.length <= left + right) return value; return value.substring(0, left) + '****' + value.substring(value.length - right) }
|
|
const displayValue = (saved: UTSJSONObject, key: string): string => { const value = draftText(saved, key); return value.length > 0 ? value : '未填写' }
|
|
const appendRow = (rows: InfoRow[], label: string, value: string) => { const row: InfoRow = { label, value }; rows.push(row) }
|
|
const loadDraft = () => {
|
|
assessmentType.value = activeAssessmentType()
|
|
const saved = loadAssessmentDraft(assessmentType.value)
|
|
if (saved == null) { hasDraft.value = false; sections.value = []; return }
|
|
hasDraft.value = true
|
|
const enterprise = assessmentType.value == 'enterprise'
|
|
const basicRows: InfoRow[] = []
|
|
if (enterprise) {
|
|
appendRow(basicRows, '企业名称', displayValue(saved, 'enterpriseName'))
|
|
appendRow(basicRows, '信用代码', mask(displayValue(saved, 'businessCode'), 4, 4))
|
|
}
|
|
appendRow(basicRows, enterprise ? '联系人' : '姓名', displayValue(saved, 'name'))
|
|
appendRow(basicRows, '手机号', mask(displayValue(saved, 'phone'), 3, 4))
|
|
appendRow(basicRows, '所在城市', displayValue(saved, 'city'))
|
|
if (!enterprise) {
|
|
appendRow(basicRows, '身份证号', mask(displayValue(saved, 'idCard'), 4, 4))
|
|
appendRow(basicRows, '婚姻状况', displayValue(saved, 'maritalStatus'))
|
|
}
|
|
const incomeRows: InfoRow[] = enterprise ? [
|
|
{ label: '经营行业', value: displayValue(saved, 'occupation') }, { label: '经营年限', value: displayValue(saved, 'operatingYears') }, { label: '年营业收入', value: draftText(saved, 'annualRevenue').length > 0 ? draftText(saved, 'annualRevenue') + ' 万元' : '未填写' }
|
|
] : [
|
|
{ label: '职业类型', value: displayValue(saved, 'occupation') }, { label: '月收入', value: draftText(saved, 'monthlyIncome').length > 0 ? draftText(saved, 'monthlyIncome') + ' 元' : '未填写' }, { label: '工作单位', value: displayValue(saved, 'company') }, { label: '社保缴纳', value: displayValue(saved, 'socialSecurity') }, { label: '公积金缴纳', value: displayValue(saved, 'housingFund') }
|
|
]
|
|
const files = documentsFromDraft(saved)
|
|
const fileNames = files.map((file) => file.name).join('、')
|
|
const grants = saved['authorizations'] as string[] | null
|
|
const grantNames: string[] = []
|
|
if (grants != null) { if (grants.includes('credit')) grantNames.push('征信'); if (grants.includes('business')) grantNames.push('经营'); if (grants.includes('fund')) grantNames.push('公积金') }
|
|
sections.value = [
|
|
{ title: '基本信息', step: 0, rows: basicRows, expanded: false },
|
|
{ title: enterprise ? '经营信息' : '职业与收入', step: 1, rows: incomeRows, expanded: false },
|
|
{ title: '资产与负债', step: 2, rows: [{ label: '房产情况', value: displayValue(saved, 'house') }, { label: '车辆情况', value: displayValue(saved, 'car') }, { label: '存款情况', value: displayValue(saved, 'savings') }, { label: '信用卡使用', value: displayValue(saved, 'creditCard') }, { label: '其他资产', value: displayValue(saved, 'otherAssets') }], expanded: false },
|
|
{ title: '资料与授权', step: 3, rows: [{ label: '本地资料', value: fileNames.length > 0 ? fileNames : '未选择' }, { label: '授权意向', value: grantNames.length > 0 ? grantNames.join('、') : '未选择' }, { label: '当前状态', value: '资料未上传 · 数据未查询' }], expanded: false }
|
|
]
|
|
payload.value = { ...saved, source: 'mobile', confirmed: true }
|
|
}
|
|
onShow(() => loadDraft())
|
|
const edit = (step: number) => {
|
|
uni.setStorageSync('assessmentEditStep', step)
|
|
const pages = getCurrentPages()
|
|
if (pages.length > 1 && pages[pages.length - 2].route == 'packages/finance/assessment/assessment') uni.navigateBack({ delta: 1 })
|
|
else uni.navigateTo({ url: '/packages/finance/assessment/assessment?type=' + assessmentType.value })
|
|
}
|
|
const submit = async () => {
|
|
if (!hasDraft.value) { edit(0); return }
|
|
if (submitting.value) return
|
|
const saved = payload.value
|
|
const amount = draftText(saved, assessmentType.value == 'enterprise' ? 'annualRevenue' : 'monthlyIncome')
|
|
if (draftText(saved, 'name').length < 2 || !/^1[3-9][0-9]{9}$/.test(draftText(saved, 'phone')) || draftText(saved, 'city').length == 0) { uni.showToast({ title: '请先完善基本信息', icon: 'none' }); edit(0); return }
|
|
if (assessmentType.value == 'personal' && !/(^[0-9]{15}$)|(^[0-9]{17}[0-9Xx]$)/.test(draftText(saved, 'idCard'))) { uni.showToast({ title: '请补全身份证信息', icon: 'none' }); edit(0); return }
|
|
if (assessmentType.value == 'enterprise' && (draftText(saved, 'enterpriseName').length < 2 || !/^[0-9A-Z]{18}$/.test(draftText(saved, 'businessCode').toUpperCase()))) { uni.showToast({ title: '请补全企业信息', icon: 'none' }); edit(0); return }
|
|
if (amount.length == 0 || parseFloat(amount) <= 0 || isNaN(parseFloat(amount))) { uni.showToast({ title: '请先完善收入信息', icon: 'none' }); edit(1); return }
|
|
const grants = saved['authorizations'] as string[] | null
|
|
if ((documentsFromDraft(saved).length > 0 && saved['documentConsent'] != true) || (grants != null && grants.length > 0 && saved['dataConsent'] != true)) { uni.showToast({ title: '请确认资料与授权选择', icon: 'none' }); edit(3); return }
|
|
submitting.value = true
|
|
try { await submitAssessment(payload.value); uni.redirectTo({ url: '/packages/finance/analyzing/analyzing' }) }
|
|
catch (error) { uni.showToast({ title: error instanceof Error ? error.message : '提交失败,请重试', icon: 'none' }) }
|
|
finally { submitting.value = false }
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.confirm-content { padding: 26rpx 30rpx 0; }
|
|
.confirm-progress { flex-direction: row; align-items: center; margin-bottom: 24rpx; }
|
|
.progress-line { flex: 1; flex-direction: row; }
|
|
.progress-segment { flex: 1; height: 8rpx; margin-right: 8rpx; border-radius: 8rpx; background-color: #0868f7; }
|
|
.progress-count { font-size: 24rpx; color: #758297; margin-left: 20rpx; }
|
|
.confirm-tip { padding: 24rpx; border-radius: 18rpx; background-color: #eff6ff; flex-direction: row; align-items: center; }
|
|
.tip-icon { width: 56rpx; height: 56rpx; border-radius: 28rpx; background-color: #0868f7; align-items: center; justify-content: center; margin-right: 18rpx; flex-shrink: 0; }
|
|
.tip-mark { color: #fff; font-size: 28rpx; }
|
|
.tip-copy { flex: 1; min-width: 0; }
|
|
.tip-title { color: #22324b; font-size: 29rpx; font-weight: 600; }
|
|
.tip-desc { color: #738198; font-size: 24rpx; line-height: 36rpx; margin-top: 7rpx; }
|
|
.empty-hint { font-size: 28rpx; line-height: 44rpx; color: #778499; margin-top: 40rpx; }
|
|
.info-section { margin-top: 18rpx; border-bottom: 1rpx solid #e9eef5; padding-bottom: 14rpx; }
|
|
.section-bar { height: 74rpx; flex-direction: row; align-items: center; justify-content: space-between; }
|
|
.section-name { font-size: 29rpx; font-weight: 600; color: #22324b; }
|
|
.edit { padding: 16rpx 0 16rpx 24rpx; color: #0868f7; font-size: 25rpx; }
|
|
.info-row { min-height: 62rpx; flex-direction: row; align-items: flex-start; padding: 9rpx 0; }
|
|
.info-label { color: #758297; font-size: 25rpx; line-height: 38rpx; width: 176rpx; flex-shrink: 0; margin-right: 16rpx; }
|
|
.info-value { flex: 1; min-width: 0; text-align: right; color: #26374f; font-size: 26rpx; line-height: 38rpx; }
|
|
.expand-link { color: #7387a3; font-size: 24rpx; padding: 15rpx 0 10rpx; }
|
|
.assessment-note { font-size: 23rpx; line-height: 36rpx; color: #8490a3; margin-top: 24rpx; }
|
|
.scroll-spacer { min-height: 152rpx; }
|
|
.submit-bar { position: fixed; left: 0; right: 0; bottom: 0; padding: 20rpx 30rpx; border-top: 1rpx solid #edf1f6; background-color: #fff; }
|
|
.submit-button { margin: 0; }
|
|
</style>
|