新增revisionId参数到路由、服务及导出接口,实现不同评估版本的隔离访问。删除已废弃的需求相关服务文件,移除取消采集的融资金额、期限和用途字段,更新相关页面提示文本。同时更新文档,说明评估版本、最新资料及产品展示规则的调整,支持前台正常业务名称显示,去除环境标签。
282 lines
34 KiB
Plaintext
282 lines
34 KiB
Plaintext
<template>
|
||
<view class="page" :style="pageStyle()">
|
||
<view class="status-bar" :style="statusStyle(0)"></view>
|
||
<view class="report-header">
|
||
<view class="header-back" @click="back"><AppIcon name="chevron-right" :size="40" class="back-icon" /></view>
|
||
<view class="header-title-area" :style="reportTitleStyle()"><text class="header-title">我的融资报告</text></view>
|
||
<view v-if="report != null" class="header-export" :style="navigationActionStyle(96, 1)"><ReportExport :assessmentId="assessmentId" :revisionId="revisionId" :toolbar="true" @authrequired="login" @sessionchanged="loadReport" @statuschange="exportStatus" /></view>
|
||
</view>
|
||
<view class="tabs"><view v-for="item in tabs" :key="item.id" :class="tab == item.id ? 'tab active' : 'tab'" @click="switchTab(item.id)"><text :class="tab == item.id ? 'tab-label selected' : 'tab-label'">{{ item.label }}</text></view></view>
|
||
<scroll-view scroll-y :style="contentStyle(report == null ? 178 : 314, false)">
|
||
<view class="report-content" :style="bottomStyle(24)">
|
||
<!-- 离页清空报告时只切换可见性,避免在页面销毁过程中重新挂载文本节点。 -->
|
||
<text v-show="report == null" class="eyebrow">评估记录 #{{ assessmentId.length > 0 ? assessmentId : '待选择' }}</text>
|
||
<text v-if="loading" class="body-text">正在读取已保存报告…</text>
|
||
<view v-if="error.length > 0" class="panel"><text class="section-title">报告暂不可读取</text><text class="body-text">{{ error }}</text><button v-if="routeError.length == 0" class="secondary" @click="loadReport">重新加载报告</button><text class="action" @click="history">前往融资档案</text></view>
|
||
<template v-if="report != null">
|
||
<text v-if="report!.isPreviousResult" class="revision-notice">当前查看第 {{ report!.revisionNo }} 版结果。最新提交{{ report!.currentStatus == 'processing' ? '正在评估,成功后更新结果。' : (report!.currentStatus == 'failed' ? '评估失败,已保留上次成功结果。' : '已有新版本,可从档案查看。') }}</text>
|
||
<text v-show="downloadStatus.length > 0" class="download-status">{{ downloadStatus }}</text>
|
||
<view v-if="report!.version == 1" class="legacy"><text class="report-note">这是一份旧版自填报告,当时未采集融资需求、未计算完整度与准备状态,也未执行产品匹配。历史内容保持原样。</text></view>
|
||
<template v-if="tab == 'overview'">
|
||
<view :class="report!.readinessLabel == '可进入资料核对' ? 'readiness-band ready' : 'readiness-band attention'"><text class="readiness-label">融资准备状态</text><text class="readiness-title">{{ report!.readinessLabel }}</text></view>
|
||
<text class="summary">{{ report!.summary }}</text>
|
||
<view class="priority-section"><text class="section-title">{{ priorityItems.length > 0 ? '需重点完善的 ' + priorityItems.slice(0, 3).length.toString() + ' 项' : '资料核验与准备' }}</text><view v-for="(item, index) in priorityItems.slice(0, 3)" :key="item" class="priority-row"><text class="priority-number">{{ index + 1 }}</text><text class="priority-text">{{ item }}</text></view><text v-if="priorityItems.length == 0" class="report-note">本次暂无额外改善项,请按机构要求核实资料。</text><text v-if="priorityItems.length > 3" class="more-advice" @click="switchTab('improvements')">查看全部 {{ priorityItems.length }} 项改善建议 ›</text></view>
|
||
<!-- 首屏保持原型的状态、摘要和编号改善项;完整度与所有冻结依据按需展开。 -->
|
||
<view class="details-toggle" @click="detailsOpen = !detailsOpen"><text class="details-label">查看完整报告</text><text class="details-action">{{ detailsOpen ? '收起' : '展开' }}</text></view>
|
||
<template v-if="detailsOpen">
|
||
<view v-if="report!.suggestions.length > 0" class="panel"><text class="section-title">改善建议与依据</text><text v-for="item in report!.suggestions" :key="item" class="body-text">{{ item }}</text></view>
|
||
<view class="panel"><view class="panel-heading"><text class="section-title">资料完整度</text><text class="percent">{{ report!.completenessPercent == null ? '—' : report!.completenessPercent!.toString() + '%' }}</text></view><view v-if="report!.completenessPercent != null" class="progress-track"><view class="progress-fill" :style="'width:' + report!.completenessPercent!.toString() + '%;'"></view></view><text class="report-note">{{ report!.completenessText }}</text><text class="report-note">完整度不代表信用评分、资料真实性或获批概率。</text></view>
|
||
<view v-if="report!.demand.length > 0" class="panel"><text class="section-title">本次资金需求</text><view class="fact-row" v-for="fact in report!.demand" :key="fact.label"><text class="fact-label">{{ fact.label }}</text><text class="fact-value">{{ fact.value }}</text></view></view>
|
||
<view v-if="report!.version == 2" class="panel"><text class="section-title">准备状态依据</text><text v-if="report!.readinessBasis.length == 0" class="report-note">本次没有可展示的准备状态依据。</text><text class="body-text" v-for="(item, index) in report!.readinessBasis" :key="index">{{ item }}</text><text class="report-note">资料未经核验;完整度达到100%仍需核对机构要求。</text></view>
|
||
<view class="panel"><text class="section-title">{{ report!.version == 2 ? '主要优势' : '资料解读' }}</text><text v-if="report!.observations.length == 0" class="report-note">暂无有充分依据的优势说明。</text><text class="body-text" v-for="(item, index) in report!.observations" :key="index">{{ item }}</text></view>
|
||
<view class="panel"><view class="panel-heading" @click="factsOpen = !factsOpen"><text class="section-title">本次提交的事实</text><text class="toggle">{{ factsOpen ? '收起' : '展开' }}</text></view><text class="report-note">来源:用户自填,未经外部核验;未填写不等于零。</text><template v-if="factsOpen"><view class="fact-row" v-for="fact in report!.facts" :key="fact.label"><text class="fact-label">{{ fact.label }}</text><text class="fact-value">{{ fact.value }}</text></view><text v-if="report!.facts.length == 0" class="report-note">暂无可展示的事实。</text></template></view>
|
||
<view v-if="report!.version == 2" class="panel"><view class="panel-heading" @click="completenessOpen = !completenessOpen"><text class="section-title">逐项填写情况</text><text class="toggle">{{ completenessOpen ? '收起' : '展开' }}</text></view><template v-if="completenessOpen"><view class="fact-row" v-for="item in report!.completenessItems" :key="item.label"><text class="fact-label">{{ item.label }}</text><text class="fact-value">{{ item.value }}</text></view><text v-if="report!.completenessItems.length == 0" class="report-note">本次未评定逐项完整度。</text></template></view>
|
||
<view class="panel"><text class="section-title">{{ report!.version == 2 ? '风险与核验边界' : '待补充信息' }}</text><text class="body-text" v-for="(item, index) in report!.warnings" :key="'system-' + index">{{ item }}</text><text class="body-text" v-for="(item, index) in report!.dataGaps" :key="index">{{ item }}</text><text v-if="report!.warnings.length == 0 && report!.dataGaps.length == 0" class="report-note">本次暂无额外提示,不代表资料已核验或无风险。</text></view>
|
||
</template>
|
||
</template>
|
||
<template v-else-if="tab == 'matches'">
|
||
<text class="headline">本次需求的可选方向</text><text class="intro">以下为评估时的条件判断。展示顺序不代表优劣,也不代表机构审批。</text>
|
||
<view v-if="report!.matching.status == 'completed'" class="stats"><view class="stat" @click="allMatches('eligible')"><text class="stat-number">{{ report!.matching.eligible }}</text><text class="stat-label">符合已知条件</text></view><view class="stat" @click="allMatches('ineligible')"><text class="stat-number">{{ report!.matching.ineligible }}</text><text class="stat-label">条件不符</text></view><view class="stat" @click="allMatches('unknown')"><text class="stat-number">{{ report!.matching.unknown }}</text><text class="stat-label">待核实</text></view></view>
|
||
<text class="report-note">{{ report!.matchingMessage }}</text>
|
||
<view v-if="report!.matching.status != 'completed'" class="panel"><text class="section-title">本次未执行产品匹配</text><text class="body-text">这与“已匹配但没有候选”不同。历史报告不会自动补算;需要采用新资料与当前产品条件时,请重新评估。</text></view>
|
||
<template v-else>
|
||
<text v-if="candidateLoading" class="body-text">正在读取历史候选…</text>
|
||
<view v-if="candidateError.length > 0" class="panel"><text class="section-title">候选读取失败</text><text class="body-text">{{ candidateError }}</text><button class="secondary" @click="loadCandidates">重试候选</button></view>
|
||
<view v-if="!candidateLoading && candidateError.length == 0 && candidates.length == 0" class="panel"><text class="section-title">暂无符合已知条件的产品</text><text class="body-text">本次已执行匹配,可查看条件不符或待核实原因。没有候选不代表永久无法融资。</text></view>
|
||
<view v-for="item in candidates" :key="item.id" class="product-card" @click="openProduct(item.id)"><view class="panel-heading"><text class="product-name">{{ item.product.name }}</text><text class="version">v{{ item.product.version }}</text></view><text class="report-note">{{ item.product.bank }} · {{ item.stateLabel }}</text><text class="amount">{{ item.product.amount }}</text><view class="metrics"><text class="metric">年化 {{ item.product.rate }}</text><text class="metric">{{ item.product.term }}</text></view><text class="reason" v-for="reason in item.positive.slice(0, 2)" :key="reason.id">{{ reason.text }}</text><text v-if="item.availability != 'available'" class="availability">{{ item.availabilityLabel }};仍保留历史参数。</text><text class="action">查看匹配依据与详情 ›</text></view>
|
||
<text v-if="candidates.length > 0" class="report-note">摘要最多展示3项符合已知条件的产品,全部分组见完整匹配列表。</text>
|
||
<button class="primary" @click="allMatches('eligible')">查看全部匹配结果</button><view class="links"><text class="action" @click="allMatches('ineligible')">查看不符原因</text><text class="action" @click="allMatches('unknown')">查看待核实项</text></view>
|
||
</template>
|
||
</template>
|
||
<template v-else>
|
||
<text class="headline">改善建议</text><text class="intro">依据本次报告整理 · 改善不保证获批</text>
|
||
<view class="priority-section"><text class="section-title">{{ priorityItems.length > 0 ? '需重点完善的 ' + priorityItems.length.toString() + ' 项' : '资料核验与准备' }}</text><view v-for="(item, index) in priorityItems" :key="item" class="priority-row"><text class="priority-number">{{ index + 1 }}</text><text class="priority-text">{{ item }}</text></view><text v-if="priorityItems.length == 0" class="report-note">本次暂无额外改善项,请按机构要求核实资料。</text></view>
|
||
<view v-if="report!.suggestions.length > 0" class="panel"><view class="panel-heading" @click="detailsOpen = !detailsOpen"><text class="section-title">建议依据</text><text class="toggle">{{ detailsOpen ? '收起' : '展开' }}</text></view><template v-if="detailsOpen"><text v-for="item in report!.suggestions" :key="item" class="body-text">{{ item }}</text></template></view>
|
||
<view v-if="report!.version == 2" class="panel"><text class="section-title">优先补充与核实</text><text v-if="missingItems.length == 0" class="report-note">{{ report!.completenessPercent == null ? '本次未评定缺失字段,不能据此认为资料齐全。' : '本次字段清单没有待补充或格式待核实项,仍需准备核验材料。' }}</text><view class="fact-row" v-for="item in missingItems" :key="item.label"><text class="fact-label">{{ item.label }}</text><text class="fact-value">{{ item.value }}</text></view><text class="body-text" v-for="(item, index) in report!.readinessBasis" :key="index">{{ item }}</text></view>
|
||
<view v-if="report!.matching.status != 'completed'" class="panel"><text class="section-title">产品条件提示</text><text class="report-note">本次未执行产品匹配,没有可关联的产品改善依据。</text></view>
|
||
<template v-else><view v-for="group in adviceGroups" :key="group.id" class="panel"><text class="section-title">{{ group.label }}</text><text class="report-note">仅展示本组前3项产品的已有依据,可进入完整列表查看更多。</text><text v-if="group.loading" class="body-text">正在读取产品依据…</text><template v-if="group.error.length > 0"><text class="body-text">{{ group.error }}</text><button class="secondary" @click="loadAdvice(group.id)">重试{{ group.label }}</button></template><text v-if="!group.loading && group.error.length == 0 && group.items.length == 0" class="report-note">本组暂无产品依据。</text><view v-for="item in group.items" :key="item.id" class="advice-product"><text class="product-name" @click="openProduct(item.id)">{{ item.product.name }} ›</text><text class="source-note">{{ item.stateLabel }} · 评估时版本 v{{ item.product.version }}</text><view v-for="reason in adviceReasons(item)" :key="reason.id"><text class="body-text">{{ reason.text }}</text><text v-for="line in reason.evidence" :key="line" class="evidence">{{ line }}</text></view><text v-if="item.availability != 'available'" class="availability">{{ item.availabilityLabel }}</text></view><text class="action" @click="allMatches(group.id)">查看全部{{ group.label }} ›</text></view></template>
|
||
</template>
|
||
<view class="report-links"><text class="report-link" @click="nextStep">下一步行动 ›</text><text class="report-link" @click="consult">咨询AI ›</text></view>
|
||
<view class="details-toggle" @click="metadataOpen = !metadataOpen"><text class="metadata-toggle">报告信息</text><text class="details-action">{{ metadataOpen ? '收起' : '展开' }}</text></view>
|
||
<view v-if="metadataOpen" class="metadata"><text class="report-note">评估 #{{ assessmentId }} · 第 {{ report!.revisionNo }} 版 · {{ report!.generatedAt }}</text><text class="report-note">分析来源:用户自填资料 · {{ report!.modelCode }}</text><text class="report-note">报告已保存至融资档案。导出不含身份信息,请妥善保管下载文件。</text><text class="disclaimer">{{ report!.disclaimer }}</text><view class="report-links"><text class="report-link" @click="start">发起新评估</text><text class="report-link" @click="history">历史评估</text></view></view>
|
||
<text v-show="!metadataOpen" class="disclaimer">自填资料未经核验,结果仅供参考,不代表授信或获批。</text>
|
||
</template>
|
||
</view>
|
||
</scroll-view>
|
||
<view v-if="report != null" class="report-footer" :style="bottomStyle(24)"><button class="reevaluate-button" @click="editAssessment">重新评估</button></view>
|
||
</view>
|
||
</template>
|
||
<script setup lang="uts">
|
||
import AppIcon from '@/components/AppIcon.uvue'
|
||
import ReportExport from '@/packages/finance/components/ReportExport.uvue'
|
||
import { usePageLayout } from '@/services/layout.uts'
|
||
import { getSession } from '@/services/api.uts'
|
||
import { assistantRoute } from '@/packages/finance/services/assistant.uts'
|
||
import { clearAssessmentFlow } from '@/services/assessment-flow.uts'
|
||
import { AnalysisReport, AssessmentField, fetchAnalysisReport } from '@/packages/finance/services/records.uts'
|
||
import { MatchPage, MatchView, MatchReason, fetchMatchPage, validRecordId } from '@/packages/finance/services/matches.uts'
|
||
type ReportTab = { id: string, label: string }
|
||
type AdviceGroup = { id: string, label: string, loading: boolean, error: string, items: MatchView[] }
|
||
const { contentStyle, pageStyle, statusStyle, bottomStyle, navigationTitleStyle, navigationActionStyle } = usePageLayout()
|
||
const reportTitleStyle = (): string => {
|
||
// 小程序标题须同时避让PDF按钮和右侧胶囊,窄屏也不能覆盖操作入口。
|
||
// #ifdef MP-WEIXIN
|
||
const windowWidth = uni.getWindowInfo().windowWidth
|
||
const capsule = uni.getMenuButtonBoundingClientRect()
|
||
const reserved = capsule.left > 0 && capsule.left < windowWidth ? windowWidth - capsule.left + 8 : 104
|
||
return 'left:50px;right:' + (reserved + 40) + 'px;'
|
||
// #endif
|
||
// #ifndef MP-WEIXIN
|
||
return navigationTitleStyle()
|
||
// #endif
|
||
}
|
||
const tabs: ReportTab[] = [{ id: 'overview', label: '评估概况' }, { id: 'matches', label: '匹配结果' }, { id: 'improvements', label: '改善建议' }]
|
||
const revisionId = ref(''); const assessmentId = ref(''); const tab = ref('overview'); const loading = ref(false); const error = ref(''); const routeError = ref('')
|
||
const report = ref<AnalysisReport | null>(null); const factsOpen = ref(false); const completenessOpen = ref(false)
|
||
// 日期与导出说明按需展开,首屏优先呈现准备状态和当前栏目的内容。
|
||
const metadataOpen = ref(false)
|
||
const detailsOpen = ref(false); const downloadStatus = ref('')
|
||
const exportStatus = (message: string) => { downloadStatus.value = message }
|
||
const candidates = ref<MatchView[]>([]); const candidateLoading = ref(false); const candidateError = ref('')
|
||
const adviceGroups = ref<AdviceGroup[]>([])
|
||
let generation = 0; let visible = false
|
||
const login = () => { uni.redirectTo({ url: '/packages/account/login/login?resumeReport=1&assessmentId=' + assessmentId.value + (revisionId.value.length > 0 ? '&revisionId=' + revisionId.value : '') + '&tab=' + tab.value }) }
|
||
const missingItems = computed((): AssessmentField[] => report.value == null ? [] : report.value!.completenessItems.filter((item: AssessmentField): boolean => ['待补充','需核实'].includes(item.value)))
|
||
const priorityItems = computed((): string[] => {
|
||
const value = report.value
|
||
if (value == null) return []
|
||
// 使用已保存建议及真实缺失项,不补造原型中的固定三条或融资评分。
|
||
const items = value.suggestionSummaries.concat(missingItems.value.map((item: AssessmentField): string => (item.value == '待补充' ? '补充' : '核实') + item.label))
|
||
return items.filter((item: string, index: number): boolean => item.trim().length > 0 && items.indexOf(item) == index)
|
||
})
|
||
const adviceReasons = (item: MatchView): MatchReason[] => item.state == 'ineligible' ? item.blocking.concat(item.cautions) : item.cautions
|
||
const reset = () => { report.value = null; candidates.value = []; adviceGroups.value = []; candidateLoading.value = false; candidateError.value = ''; factsOpen.value = false; completenessOpen.value = false; metadataOpen.value = false; detailsOpen.value = false; downloadStatus.value = '' }
|
||
const current = (request: number, token: string): boolean => visible && request == generation && getSession()?.getString('token') == token
|
||
const sessionChanged = (request: number, token: string): boolean => {
|
||
if (!visible || request != generation) return true
|
||
if (getSession()?.getString('token') == token) return false
|
||
generation++; reset(); loading.value = false
|
||
if (getSession() == null) login()
|
||
else error.value = '账户已切换,请重新加载本人报告。'
|
||
return true
|
||
}
|
||
const verifyMatches = (page: MatchPage) => {
|
||
const value = report.value
|
||
if (value == null || page.assessmentId != assessmentId.value || page.revisionId != value.revisionId || page.resultVersion != value.version || page.status != 'completed' || page.snapshotId != value.matching.snapshotId || page.ruleVersion != value.matching.ruleVersion || page.orderingVersion != value.matching.orderingVersion || page.eligible != value.matching.eligible || page.ineligible != value.matching.ineligible || page.unknown != value.matching.unknown) throw new Error('产品结果与本报告的冻结版本不一致,请重新加载报告。')
|
||
}
|
||
const loadCandidates = async () => {
|
||
if (candidateLoading.value || report.value?.matching.status != 'completed') return
|
||
const request = generation; const token = getSession()?.getString('token') ?? ''
|
||
candidateLoading.value = true; candidateError.value = ''; candidates.value = []
|
||
try {
|
||
const result = await fetchMatchPage(assessmentId.value, 'eligible', '', revisionId.value)
|
||
if (!current(request, token)) { sessionChanged(request, token); return }
|
||
verifyMatches(result); candidates.value = result.items
|
||
} catch (err) { if (!sessionChanged(request, token)) candidateError.value = err instanceof Error ? err.message : '候选读取失败' }
|
||
finally { if (request == generation) candidateLoading.value = false }
|
||
}
|
||
const loadAdvice = async (id: string) => {
|
||
const group = adviceGroups.value.find((item: AdviceGroup): boolean => item.id == id)
|
||
if (group == null || group.loading || report.value?.matching.status != 'completed') return
|
||
const request = generation; const token = getSession()?.getString('token') ?? ''
|
||
group.loading = true; group.error = ''; group.items = []
|
||
try {
|
||
const result = await fetchMatchPage(assessmentId.value, id, '', revisionId.value)
|
||
if (!current(request, token)) { sessionChanged(request, token); return }
|
||
verifyMatches(result); group.items = result.items
|
||
} catch (err) { if (!sessionChanged(request, token)) group.error = err instanceof Error ? err.message : '产品依据读取失败' }
|
||
finally { if (request == generation) group.loading = false }
|
||
}
|
||
const loadReport = async () => {
|
||
const request = ++generation; reset(); error.value = ''; loading.value = false
|
||
if (routeError.value.length > 0) { error.value = routeError.value; return }
|
||
const session = getSession()
|
||
if (session == null) { login(); return }
|
||
const token = session.getString('token') ?? ''; loading.value = true
|
||
try {
|
||
const result = await fetchAnalysisReport(assessmentId.value, revisionId.value)
|
||
if (!current(request, token)) { sessionChanged(request, token); return }
|
||
report.value = result; revisionId.value = result.revisionId
|
||
if (tab.value == 'matches') loadCandidates()
|
||
if (tab.value == 'improvements') {
|
||
adviceGroups.value = [{ id: 'ineligible', label: '不符条件', loading: false, error: '', items: [] }, { id: 'unknown', label: '待核实项', loading: false, error: '', items: [] }]
|
||
if (result.matching.status == 'completed') { loadAdvice('ineligible'); loadAdvice('unknown') }
|
||
}
|
||
} catch (err) { if (!sessionChanged(request, token)) error.value = err instanceof Error ? err.message : '报告加载失败,请重试' }
|
||
finally { if (request == generation) loading.value = false }
|
||
}
|
||
// 切栏替换当前路由,刷新恢复所选栏目;只读取已保存快照,不提交评估或触发模型。
|
||
const switchTab = (value: string) => { if (value != tab.value && routeError.value.length == 0) uni.redirectTo({ url: '/packages/finance/report/report?assessmentId=' + assessmentId.value + (revisionId.value.length > 0 ? '&revisionId=' + revisionId.value : '') + '&tab=' + value }) }
|
||
const editAssessment = () => { uni.navigateTo({ url: '/packages/finance/assessment/assessment?editId=' + assessmentId.value }) }
|
||
const history = () => { uni.navigateTo({ url: '/packages/finance/archive/archive' }) }
|
||
const consult = () => { uni.navigateTo({ url: assistantRoute(assessmentId.value, [], 'report', '', revisionId.value) }) }
|
||
const nextStep = () => { if (report.value != null) uni.navigateTo({ url: '/packages/finance/next-step/next-step?assessmentId=' + assessmentId.value + (revisionId.value.length > 0 ? '&revisionId=' + revisionId.value : '') + '§ion=actions' }) }
|
||
const back = () => { if (getCurrentPages().length > 1) uni.navigateBack(); else uni.redirectTo({ url: '/packages/finance/archive/archive' }) }
|
||
const allMatches = (group: string) => { uni.navigateTo({ url: '/packages/finance/matches/matches?assessmentId=' + assessmentId.value + (revisionId.value.length > 0 ? '&revisionId=' + revisionId.value : '') + '&group=' + group }) }
|
||
const openProduct = (id: string) => { uni.navigateTo({ url: '/packages/finance/product/product?assessmentId=' + assessmentId.value + (revisionId.value.length > 0 ? '&revisionId=' + revisionId.value : '') + '&productId=' + id + '&tab=explanation&from=report' }) }
|
||
const start = () => {
|
||
const token = getSession()?.getString('token') ?? ''; const request = generation
|
||
uni.showActionSheet({ itemList: ['个人评估','企业评估'], success: (result) => {
|
||
if (!current(request, token)) return
|
||
clearAssessmentFlow()
|
||
uni.navigateTo({ url: '/packages/finance/assessment/assessment?type=' + (result.tapIndex == 1 ? 'enterprise' : 'personal') })
|
||
} })
|
||
}
|
||
onLoad((options) => {
|
||
revisionId.value = options?.['revisionId'] ?? '';
|
||
if (revisionId.value.length > 0 && !validRecordId(revisionId.value)) routeError.value = '版本编号无效,请返回重新选择。'
|
||
assessmentId.value = options?.['assessmentId'] ?? ''; tab.value = options?.['tab'] ?? 'overview'
|
||
if (!validRecordId(assessmentId.value)) routeError.value = '请从融资档案选择有效的评估记录。'
|
||
if (!['overview','matches','improvements'].includes(tab.value)) routeError.value = '报告栏目参数无效,请从融资档案重新进入。'
|
||
})
|
||
onShow(() => { visible = true; loadReport() })
|
||
// 离页丢弃个人数据;旧请求不得覆盖新页面或新登录账户。
|
||
onHide(() => { visible = false; generation++; reset(); loading.value = false; error.value = '' })
|
||
onUnload(() => { visible = false; generation++; reset() })
|
||
</script>
|
||
<style>
|
||
.page { background-color: #fff; }
|
||
.status-bar { background-color: #fff; }
|
||
.report-header { height: 96rpx; padding: 0 28rpx; flex-direction: row; align-items: center; justify-content: space-between; position: relative; background-color: #fff; }
|
||
.header-back { width: 64rpx; height: 96rpx; justify-content: center; align-items: flex-start; }
|
||
.back-icon { transform: rotate(180deg); }
|
||
.header-title-area { position: absolute; left: 140rpx; right: 140rpx; top: 0; bottom: 0; align-items: center; justify-content: center; }
|
||
.header-title { color: #17243b; font-size: 32rpx; font-weight: 700; }
|
||
.header-export { align-items: center; justify-content: center; }
|
||
/* #ifdef MP-WEIXIN */
|
||
.header-title { font-size: 27rpx; }
|
||
/* #endif */
|
||
.tabs { height: 82rpx; flex-direction: row; background-color: #fff; padding: 0 28rpx; border-bottom: 1rpx solid #eff2f6; }
|
||
.tab { flex: 1; align-items: center; justify-content: center; }
|
||
.active { border-bottom: 4rpx solid #0868f7; }
|
||
.tab-label { font-size: 26rpx; color: #737e90; }
|
||
.selected { color: #0868f7; font-weight: 700; }
|
||
.revision-notice { font-size: 24rpx; line-height: 38rpx; color: #886934; padding: 18rpx 22rpx; background-color: #fff8eb; border-radius: 12rpx; margin-bottom: 12rpx; }
|
||
.download-status { font-size: 23rpx; line-height: 36rpx; color: #547292; padding-bottom: 18rpx; }
|
||
.report-content { padding: 28rpx 30rpx 24rpx; }
|
||
.eyebrow { color: #778ba3; font-size: 22rpx; }
|
||
.headline { color: #1a3859; font-size: 34rpx; font-weight: 700; margin-top: 22rpx; }
|
||
.intro { color: #73869d; font-size: 24rpx; line-height: 40rpx; margin-top: 14rpx; }
|
||
.metadata-toggle { color: #8893a2; font-size: 22rpx; line-height: 36rpx; }
|
||
.metadata { padding: 0 0 12rpx; }
|
||
.readiness-band { padding: 28rpx 30rpx; min-height: 154rpx; background-color: #eef9f3; }
|
||
.attention { background-color: #fff8ed; }
|
||
.readiness-label { color: #526272; font-size: 25rpx; line-height: 38rpx; }
|
||
.readiness-title { color: #17a46b; font-size: 46rpx; line-height: 64rpx; font-weight: 700; margin-top: 9rpx; }
|
||
.attention .readiness-title { color: #a57925; }
|
||
.summary { font-size: 26rpx; line-height: 44rpx; color: #4d5869; margin-top: 24rpx; }
|
||
.priority-section { margin-top: 30rpx; }
|
||
.priority-row { flex-direction: row; align-items: flex-start; padding: 24rpx 0; border-bottom: 1rpx solid #edf0f4; min-height: 88rpx; }
|
||
.priority-number { width: 36rpx; height: 36rpx; border-radius: 18rpx; background-color: #f66f4e; text-align: center; color: #fff; font-size: 22rpx; line-height: 36rpx; margin-right: 18rpx; margin-top: 2rpx; flex-shrink: 0; }
|
||
.priority-text { flex: 1; font-size: 26rpx; line-height: 40rpx; color: #485568; }
|
||
.more-advice { font-size: 23rpx; line-height: 38rpx; color: #0868f7; margin-top: 18rpx; }
|
||
.details-toggle { flex-direction: row; align-items: center; justify-content: space-between; padding: 22rpx 0; border-bottom: 1rpx solid #edf0f4; }
|
||
.details-label { font-size: 24rpx; color: #738094; }
|
||
.details-action { font-size: 23rpx; color: #8794a5; }
|
||
.report-links { flex-direction: row; align-items: center; justify-content: space-between; margin-top: 22rpx; }
|
||
.report-link { font-size: 24rpx; line-height: 38rpx; color: #4e77aa; padding: 8rpx 0; }
|
||
.report-footer { position: fixed; left: 0; right: 0; bottom: 0; padding: 20rpx 30rpx 24rpx; background-color: #fff; }
|
||
.reevaluate-button { width: 100%; height: 92rpx; line-height: 92rpx; font-size: 28rpx; font-weight: 600; border-radius: 14rpx; background-color: #0868f7; color: #fff; margin: 0; }
|
||
.percent { color: #285c9d; font-size: 30rpx; font-weight: 700; }
|
||
.progress-track { height: 8rpx; border-radius: 4rpx; background-color: #dbe7f8; margin-top: 12rpx; overflow: hidden; }
|
||
.progress-fill { height: 8rpx; background-color: #4c8beb; border-radius: 4rpx; }
|
||
.panel { margin-top: 28rpx; padding: 0 0 24rpx; border-bottom: 1rpx solid #edf0f4; }
|
||
.panel-heading { flex-direction: row; justify-content: space-between; align-items: center; }
|
||
.section-title { color: #233750; font-size: 28rpx; font-weight: 700; line-height: 42rpx; }
|
||
.toggle { font-size: 24rpx; color: #0868f7; padding: 10rpx; }
|
||
.body-text { margin-top: 20rpx; font-size: 26rpx; color: #425b78; line-height: 44rpx; }
|
||
.report-note { font-size: 23rpx; line-height: 38rpx; color: #78889e; margin-top: 12rpx; }
|
||
.source-note { color: #8796a8; font-size: 22rpx; line-height: 36rpx; margin-top: 16rpx; }
|
||
.fact-row { flex-direction: row; padding: 22rpx 0; border-bottom: 1rpx solid #edf1f6; }
|
||
.fact-label { flex: 1; font-size: 25rpx; line-height: 39rpx; color: #738198; }
|
||
.fact-value { flex: 1; text-align: right; font-size: 25rpx; line-height: 39rpx; color: #233e5e; }
|
||
.legacy { background-color: #fff5e7; padding: 16rpx 22rpx 24rpx; border-radius: 14rpx; margin-top: 20rpx; }
|
||
.stats { flex-direction: row; padding: 26rpx 8rpx; border-top: 1rpx solid #edf0f4; border-bottom: 1rpx solid #edf0f4; margin-top: 26rpx; }
|
||
.stat { flex: 1; align-items: center; }
|
||
.stat-number { font-size: 39rpx; color: #1b5ebd; font-weight: 700; }
|
||
.stat-label { font-size: 22rpx; color: #5c7799; margin-top: 12rpx; }
|
||
.product-card { padding: 28rpx; border-radius: 14rpx; background-color: #fff; border: 1rpx solid #e0eaf7; margin-top: 24rpx; }
|
||
.product-name { flex: 1; color: #284566; font-size: 28rpx; line-height: 42rpx; font-weight: 700; }
|
||
.version { color: #8b9aab; font-size: 22rpx; margin-left: 14rpx; }
|
||
.demo { color: #9b762d; font-size: 22rpx; margin-top: 12rpx; }
|
||
.amount { color: #164b86; font-size: 38rpx; font-weight: 700; margin-top: 22rpx; }
|
||
.metrics { flex-direction: row; justify-content: space-between; margin-top: 16rpx; }
|
||
.metric { color: #5c7491; font-size: 23rpx; line-height: 37rpx; }
|
||
.reason { color: #6e8097; font-size: 23rpx; line-height: 38rpx; margin-top: 14rpx; }
|
||
.availability { color: #a07436; font-size: 23rpx; line-height: 38rpx; margin-top: 16rpx; }
|
||
.action { padding: 24rpx 0; color: #0868f7; font-size: 25rpx; }
|
||
.links { flex-direction: row; justify-content: space-between; }
|
||
.advice-product { border-top: 1rpx solid #e8eef6; padding-top: 24rpx; margin-top: 24rpx; }
|
||
.evidence { color: #8494a8; font-size: 22rpx; line-height: 36rpx; margin-top: 12rpx; }
|
||
.primary { background-color: #0868f7; color: #fff; font-size: 27rpx; border-radius: 12rpx; margin-top: 24rpx; }
|
||
.secondary { background-color: #eaf3ff; color: #0868f7; font-size: 25rpx; border-radius: 12rpx; margin-top: 22rpx; }
|
||
.disclaimer { color: #939caa; font-size: 21rpx; line-height: 34rpx; margin-top: 18rpx; }
|
||
/* #ifndef APP */
|
||
@media (min-width: 768px) {
|
||
.report-content { max-width: 720px; margin: 0 auto; }
|
||
.report-footer { align-items: center; }
|
||
.reevaluate-button { max-width: 690px; }
|
||
}
|
||
/* #endif */
|
||
</style>
|