@@ -55,7 +55,20 @@
@ media ( max-width : 768px ) { . mobile-menu { display : flex ; font-size : 22 px ; min-width : 44 px ; height : 44 px ; align-items : center ; justify-content : center } # prototype-navigation { display : none !important ; position : fixed ; top : 68 px ; bottom : 0 ; left : 0 ; z-index : 30 ; min-height : 0 !important ; box-shadow : 0 16 px 48 px rgba ( 16 , 43 , 39 , .16 ) } # prototype-navigation . mobile-open { display : flex !important } body [ data-sd-id = "8" ] { padding : 20 px } body [ data-sd-id = "3" ] { padding : 8 px 12 px } body [ data-sd-id = "12" ] { font-size : 24 px } body [ data-sd-id = "19" ] { padding : 20 px } body [ data-sd-id = "82" ] { display : flex } body [ data-sd-id = "46" ] { display : grid ; grid-template-columns : 1 fr 1 fr } body [ data-sd-id = "53" ] { gap : 12 px } body [ data-sd-id = "60" ] { max-width : none ; text-align : center } body [ data-sd-id = "44" ] { display : none } . condition-grid { grid-template-columns : 1 fr } body [ data-sd-id = "37" ] { gap : 24 px } body [ data-sd-id = "26" ] { gap : 32 px } body [ data-sd-id = "14" ] { font-size : 14 px } . proto-panel { padding : 20 px } }
body [ data-sd-id = "60" ] { min-width : 112 px ; max-width : none ; white-space : nowrap ; text-align : center } input [ type = radio ] { accent-color : #17634C } # prototype-navigation > a . is-active { background : transparent }
# probability-hero { flex-wrap : wrap } # probability-hero > div { flex-wrap : wrap ; gap : 12 px } # probability-hero > div > span : last-child { white-space : nowrap } # sim-prob-delta { white-space : nowrap } # basis-dialog > div { padding : 0 ; height : auto !important } body [ data-sd-id = "9" ] { flex-shrink : 0 }
# probability-hero { flex-wrap : wrap } # probability-hero > div { flex-wrap : wrap ; gap : 12 px } # probability-hero > div > span : last-child { white-space : nowrap } # sim-prob-delta { white-space : nowrap } # basis-dialog > div { padding : 0 ; height : auto !important } body [ data-sd-id = "9" ] { flex-shrink : 0 }
. radar-polygon { transition : all 300 ms ease ; }
. radar-polygon-sandbox { fill : rgba ( 23 , 99 , 76 , 0.15 ) ; stroke : #17634C ; stroke-width : 2 ; }
. radar-polygon-baseline { fill : transparent ; stroke : #DCE4DF ; stroke-width : 1 ; stroke-dasharray : 4 ; }
. radar-axis { stroke : #DCE4DF ; stroke-width : 1 ; }
. radar-tick { stroke : #B1C6BE ; stroke-width : 1 ; }
. radar-label { font-size : 11 px ; fill : #52675C ; cursor : pointer ; }
. radar-label : hover { fill : #17634C ; font-weight : bold ; }
body # probability-hero { display : block ; width : 100 % ; background : #102B27 ; color : #F3F7F5 ; border : 1 px solid #244D41 ; border-radius : 12 px ; padding : 20 px ; background-image : linear-gradient ( #B1C6BE 08 1 px , transparent 1 px ) , linear-gradient ( 90 deg , #B1C6BE 08 1 px , transparent 1 px ) ; background-size : 24 px 24 px }
. cockpit-heading { display : flex ; justify-content : space-between ; gap : 12 px ; flex-wrap : wrap ; font-size : 12 px ; letter-spacing : 1 px ; color : #B1C6BE } . cockpit-badge { border : 1 px solid #52675C ; border-radius : 20 px ; padding : 3 px 10 px } . cockpit-grid { display : grid ; grid-template-columns : minmax ( 190 px , .8 fr ) minmax ( 260 px , 1.2 fr ) ; gap : 16 px ; align-items : center } . probability-center { text-align : center } . probability-ring { position : relative ; width : 200 px ; height : 200 px ; margin : 0 auto } . probability-ring svg { width : 100 % ; height : 100 % } . ring-ticks { fill : none ; stroke : #52675C ; stroke-width : 2 ; stroke-dasharray : 1 7 } . ring-track { fill : none ; stroke : #244D41 ; stroke-width : 8 } . ring-value { fill : none ; stroke : #B1C6BE ; stroke-width : 8 ; stroke-linecap : round ; transform : rotate ( -90 deg ) ; transform-origin : 100 px 100 px } . ring-copy { position : absolute ; inset : 0 ; display : flex ; flex-direction : column ; justify-content : center ; align-items : center ; gap : 8 px } . ring-copy strong { font-size : 46 px ; line-height : 1 ; font-weight : 600 ; letter-spacing : -2 px } . ring-copy span { font-size : 12 px ; color : #B1C6BE } . cockpit-button { border : 1 px solid #B1C6BE ; border-radius : 8 px ; padding : 10 px 16 px ; font-size : 14 px ; color : #F3F7F5 ; min-height : 44 px } . cockpit-button : hover { background : #244D41 } . cockpit-muted { font-size : 12 px ; color : #B1C6BE ; margin-top : 12 px } . radar-caption { font-size : 15 px ; font-weight : 600 ; display : flex ; justify-content : space-between ; gap : 12 px } . radar-caption small { font-size : 12 px ; color : #B1C6BE } . radar-chart svg { width : 100 % ; height : auto ; max-height : 275 px ; overflow : visible ; display : block } . radar-chart . grid-line { fill : none ; stroke : currentColor ; opacity : .25 ; stroke-width : 1 } . radar-chart . stage-label { font-size : 10 px ; fill : currentColor ; opacity : .75 } . radar-chart . dimension-label { font-size : 12 px ; fill : currentColor ; cursor : pointer } . radar-chart . dimension-label : hover { text-decoration : underline } . radar-chart [ data-series = baseline ] { fill : #B1C6BE 22 ; stroke : #B1C6BE ; stroke-width : 2 } . dimension-list { display : grid ; grid-template-columns : repeat ( 3 , minmax ( 0 , 1 fr ) ) ; gap : 6 px } . dimension-list button { font-size : 12 px ; text-align : left ; padding : 8 px ; border : 1 px solid #52675C ; border-radius : 6 px ; min-height : 44 px } . dimension-list b { font-weight : 500 ; display : block } . dimension-list span { font-size : 11 px ; color : #B1C6BE } . dimension-list button : hover { background : #244D41 } . cockpit-foot { font-size : 12 px ; line-height : 1.8 ; color : #F3F7F5 ; border-top : 1 px solid #52675C ; padding-top : 12 px ; margin-top : 16 px } . cockpit-foot span { color : #B1C6BE } . trace-strip { display : flex ; flex-wrap : wrap ; align-items : center ; gap : 8 px 16 px ; font-size : 12 px ; color : #52675C } . trace-strip . text-action { font-size : 12 px ; min-height : 36 px } . scenario-radar-card { min-width : 0 ; flex : 1 ; background : #F8FAF9 ; border : 1 px solid #DCE4DF ; border-radius : 12 px ; padding : 20 px ; color : #52675C } . scenario-probabilities { display : flex ; justify-content : space-between ; gap : 16 px } . scenario-probabilities > div : last-child { text-align : right } . scenario-probabilities small { display : block ; font-size : 12 px } . scenario-probabilities strong { display : block ; font-size : 30 px ; color : #17634C } . scenario-probabilities # sim-prob-delta { font-size : 12 px ; color : #17634C ; display : block ; white-space : nowrap } . scenario-meter { height : 5 px ; background : #DCE4DF ; border-radius : 4 px ; margin : 12 px 0 ; overflow : hidden } . scenario-meter > div { height : 100 % ; background : #17634C ; transition : width 180 ms } . radar-legend { display : flex ; justify-content : center ; gap : 16 px ; font-size : 12 px } . scenario-radar-card [ data-series = baseline ] { fill : none ; stroke : #64766C ; stroke-dasharray : 5 4 } . scenario-radar-card [ data-series = scenario ] { fill : #17634C 22 ; stroke : #17634C ; stroke-width : 2 } . scenario-radar-card . dimension-list { grid-template-columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) } . scenario-radar-card . dimension-list button { border-color : #DCE4DF } . scenario-radar-card . dimension-list span { color : #52675C } . scenario-radar-card . dimension-list button : hover { background : #EAF3EC } . proto-panel . radar-help { font-size : 12 px ; line-height : 1.65 ; margin : 12 px 0 ; color : #64766C } . method-table { width : 100 % ; font-size : 14 px ; border-collapse : collapse } . method-table caption { font-size : 12 px ; color : #64766C ; text-align : left ; margin-bottom : 12 px } . method-table th , . method-table td { padding : 12 px 8 px ; border-bottom : 1 px solid #DCE4DF ; text-align : left } . method-table [ aria-selected = true ] { background : #EAF3EC ; color : #17634C ; font-weight : 600 ; outline : 1 px solid #17634C } . method-subheading { font-size : 17 px ; font-weight : 600 ; margin : 24 px 0 12 px } . trace-chain { list-style : none ; padding : 0 ; margin : 0 } . trace-chain li { border-left : 2 px solid #B1C6BE ; padding : 0 0 16 px 16 px ; margin-left : 5 px } . trace-chain li b { font-size : 14 px } . trace-chain li p { font-size : 14 px ; overflow-wrap : anywhere } . trace-chip { font-size : 12 px ; color : #52675C ; background : #F8FAF9 ; padding : 8 px ; border : 1 px solid #DCE4DF ; border-radius : 6 px ; overflow-wrap : anywhere } . cockpit-grid * : focus-visible { outline-color : #B1C6BE } body [ role = tab ] [ data-tab ] [ aria-selected = false ] { border-color : transparent !important }
@ media ( max-width : 1250px ) and ( min-width : 1101px ) { . cockpit-grid { grid-template-columns : 1 fr } . probability-ring { width : 170 px ; height : 170 px } }
@ media ( max-width : 768px ) { body # probability-hero { padding : 16 px } . cockpit-grid { grid-template-columns : 1 fr } . radar-chart svg { max-height : none } . probability-ring { width : 180 px ; height : 180 px } . cockpit-heading { font-size : 11 px } . dimension-list { grid-template-columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) } . scenario-radar-card { padding : 12 px } . radar-caption { margin-top : 16 px } . trace-strip { line-height : 1.8 } }
@ media ( max-width : 768px ) { . radar-chart . dimension-label { font-size : 16 px } . radar-chart . stage-label { font-size : 14 px } }
< / style >
< / head >
< body >
@@ -102,20 +115,15 @@
< section class = "bg-card rounded-panel p-32 shadow-card border border-border flex flex-col gap-24" data-sd-id = "19" >
< div class = "flex justify-between items-start" data-sd-id = "20" >
< div class = "flex flex-col gap-8 w-full max-w-3xl" data-sd-id = "21" >
<!-- Added Probability Hero Area -->
< div class = "flex items-center gap-16 mb-4" id = "probability-hero" >
< div class = "flex items-baseline gap-6" >
< span class = "text-[36px] font-bold text-primary leading-none tracking-tight " id = "baseline-probability" > 42 < span class = "text-[20px]" > % < / span > < / span >
< span class = "text-[12px] text-primary bg-normal-bg px-10 py-4 rounded-full border border-normal-text/20 font-medium" > 审批通过概率 · 演示值 < / span >
< / div >
< button class = "text-[14px] text-primary hover:text-primary-hover font-medium flex items-center gap-4 px-12 py-6 rounded-button hover:bg-normal-bg transition-colors outline-none focus-visible:ring-2 focus-visible:ring-primary" id = "btn-show-basis" >
< iconify-icon icon = "lucide:help-circle" > < / iconify-icon > 查看判断依据
< / button >
< / div >
< div class = "probability-cockpit" id = "probability-hero" >
< div class = "cockpit-heading" > < span > DECISION INTELLIGENCE / 预审透视 < / span > < span class = "cockpit-badge" > DEMO · 人工演示 < / span > < / div >
< div class = "cockpit-grid" > < div class = "probability-center" > < div class = "probability-ring" > < svg aria-hidden = "true" viewbox = "0 0 200 200" > < circle class = "ring-ticks" cx = "100" cy = "100" r = "87" > < / circle > < circle class = "ring-track" cx = "100" cy = "100" r = "73" > < / circle > < circle class = "ring-value" cx = "100" cy = "100" pathlength = "100" r = "73" stroke-dasharray = "42 100" > < / circle > < / svg > < div class = "ring-copy" > < strong id = "baseline-probability" > 42% < / strong > < span > 审批通过概率 · 演示值 < / span > < / div > < / div > < button class = "cockpit-button" id = "btn-probability-method" > 42% 如何得到 < span aria-hidden = "true" > ↗ < / span > < / button > < p class = "cockpit-muted" > 依据可追溯 · 正式审批由人工决定 < / p > < / div >
< div class = "radar-main" > < div class = "radar-caption" > 六维证据雷达 < small > 基线 / 阶段 0—4 < / small > < / div > < div class = "radar-chart" > < svg aria-label = "六维证据核验阶段,详细内容见下方维度按钮 " id = "radar- baseline" role = "group" viewbox = "-180 -140 360 280" > < / svg > < / div > < div class = "dimension-list" data-dimension-list = "baseline" > < / div > < / div > < / div >
< div class = "cockpit-foot" > 证据阶段 ≠ 审批概率 · 雷达面积不换算为 42% < br / > < span > 0 未提供 · 1 仅有说明 · 2 资料待核 · 3 交叉核验 · 4 人工复核 < / span > < / div >
< / div > < div class = "trace-strip" > < span > < b > miniOpenClaw < / b > 受控编排 < / span > < span > 数据卡 → Skills → Tools → Rules → 主审 < / span > < button class = "text-action" id = "btn-show-basis" > 查看判断依据 ↗ < / button > < / div >
< div class = "text-[12px] text-warning-text bg-warning-bg px-12 py-8 rounded-button border border-warning-text/20 inline-flex w-fit items-center gap-6 mb-8" >
< iconify-icon class = "text-[14px]" icon = "lucide:info" > < / iconify-icon > 人工设定,仅演示交互;未经历史数据校准。目标定义:以本次材料版本提交后的首次审批通过。
< / div >
<!-- End Probability Hero Area -->
< h2 class = "text-[24px] font-bold text-ink-main mt-4" data-sd-id = "22" id = "real-recommendation" > 主审意见:补充材料后再判断< / h2 >
< p class = "text-[16px] text-ink-sub max-w-2xl leading-relaxed" data-sd-id = "23" >
经营现金流与回款说明存在待核实差异,建议先补齐两项关键证据,再推进评审。
@@ -238,51 +246,19 @@
< div class = "condition-grid" > < div > < strong > 适用条件< / strong > < p > 客户结构稳定,回款与应收记录可逐笔匹配。< / p > < / div > < div > < strong > 例外边界< / strong > < p > 收入集中、关联回款未穿透或材料真实性未核实。< / p > < / div > < / div >
< div class = "notice" > 条件相似不等于结论相同。当前项目仍缺银行流水与权属核验。< / div >
< / section >
<!-- Updated Simulation Tab -->
< section aria-labelledby = "tab-simulation" class = "proto-panel" hidden = "" id = "panel-simulation" role = "tabpanel" >
< div class = "section-eyebrow" > SCENARIO / 条件 推演< / div >
< div class = "section-eyebrow" > SCENARIO / 证据成熟度 推演< / div >
< h2 > 补齐证据之后,审批概率如何变化?< / h2 >
< div class = "notice" > 模拟结果,不改变真实项目。以下 仅假设证据真实且完成 核验;补件也可能发现新风险,真 实概率未必上升,仍需人工复核 。< / div >
< div class = "notice" > 模拟结果,不改变真实项目。仅假设证据真实且核验支持解释 ;补件也可能发现新风险,实际 概率未必上升。< / div >
< div class = "flex flex-col lg:flex-row gap-24 mt-24 mb-24" >
< div class = "flex-1 flex flex-col gap-12" >
< p class = "muted mb-8" > 选择准备补充的材料,观察演示 概率变化:< / p >
< label class = "scenario-choice" > < input id = "assume-bank" type = "checkbox" / > < span > < strong > 补充近六个月银行流水 < / strong > < small > 假设逐笔匹配后 支持账期变化解释< / small > < / span > < / label >
< label class = "scenario-choice" > < input id = "assume-title" type = "checkbox" / > < span > < strong > 补充 设备权属证明< / strong > < small > 假设合同、发票与设备清单一致且经 核验< / small > < / span > < / label >
< p class = "muted mb-8" > 选择假设补充核验的材料,观察证据六边形扩张与 概率变化:< / p >
< label class = "scenario-choice" > < input id = "assume-bank" type = "checkbox" / > < span > < strong > 假设银行流水逐笔匹配 < / strong > < small > 假设核验 支持账期变化解释;只改变回款核验维度 < / small > < / span > < / label >
< label class = "scenario-choice" > < input id = "assume-title" type = "checkbox" / > < span > < strong > 假设 设备权属证明一致 < / strong > < small > 假设合同、发票与设备清单核验一致;只改变权属维度 < / small > < / span > < / label >
< / div >
< div aria-live = "polite" class = "flex-1 bg-panel border border-border rounded-panel p-24 flex flex-col justify-center" >
< div class = "flex justify-between items-end mb-16" >
< div >
< div class = "text-[12px] text-ink-mute mb-8" > 当前基线 (演示值)< / div >
< div class = "text-[24px] font-bold text-ink-main leading-none" > 42%< / div >
< div class = "scenario-radar-card" > < div aria-live = "polite" class = "scenario-probabilities" > < div > < small > 当前基线 · 演示值 < / small > < strong > 42% < / strong > < / div > < div > < small > 所选情景 · 演示值 < / small > < strong id = "sim-prob-val" > 42% < / strong > < span id = "sim-prob-delta" > +0 百分点 < / span > < / div > < / div > < div class = "scenario-meter" > < div id = "sim-prob-bar" style = "width:42%" > < / div > < / div > < div class = "radar-legend" > < span > ┄┄ 基线 < / span > < span > ━━ 所选假设 < / span > < / div > < div class = "radar-chart" > < svg aria-label = "六维证据核验阶段,详细内容见下方维度按钮" id = "radar-scenario" role = "group" viewbox = "-180 -140 360 280" > < / svg > < / div > < div class = "dimension-list" data-dimension-list = "scenario" > < / div > < p class = "radar-help" > 证据阶段 ≠ 审批概率;0 未提供 · 1 仅有说明 · 2 资料待核 · 3 交叉核验 · 4 人工复核 < / p > < p class = "radar-help" > 人工设定,仅演示交互;未经历史数据校准 < / p > < button class = "text-action" id = "btn-scenario-method" > 所选情景概率如何得到 ↗ < / button > < / div >
< / div >
< div class = "text-right" >
< div class = "text-[12px] text-ink-mute mb-8" > 所选情景 (演示值)< / div >
< div class = "flex items-baseline gap-8 justify-end" >
< span class = "text-[36px] font-bold text-primary leading-none tracking-tight" id = "sim-prob-val" > 42%< / span >
< span class = "text-[14px] font-bold text-normal-text bg-normal-bg px-8 py-2 rounded-full opacity-0 transition-opacity duration-200" id = "sim-prob-delta" > +0 百分点< / span >
< / div >
< / div >
< / div >
< div class = "flex flex-col gap-12" >
< div class = "flex items-center gap-12" >
< span class = "text-[12px] text-ink-mute w-[32px] shrink-0 text-right" > 基线< / span >
< div class = "flex-1 h-[8px] bg-border rounded-full overflow-hidden" >
< div class = "h-full bg-ink-mute rounded-full" style = "width: 42%;" > < / div >
< / div >
< / div >
< div class = "flex items-center gap-12" >
< span class = "text-[12px] text-ink-mute w-[32px] shrink-0 text-right" > 模拟< / span >
< div class = "flex-1 h-[8px] bg-border rounded-full overflow-hidden" >
< div class = "h-full bg-primary rounded-full transition-all duration-200 ease-out" id = "sim-prob-bar" style = "width: 42%;" > < / div >
< / div >
< / div >
< / div >
< div class = "text-[12px] text-warning-text mt-16 flex items-center justify-center gap-4" >
< iconify-icon icon = "lucide:info" > < / iconify-icon > 人工设定,仅演示交互;未经历史数据校准
< / div >
< / div >
< / div >
< button class = "primary-button" id = "run-simulation" > 查看概率与判断依据< / button >
< button class = "primary-button" id = "run-simulation" > 查看模拟判断依据 < / button >
< p aria-live = "polite" class = "muted mt-12" id = "simulation-feedback" > 概率、原因与待核实事项随勾选即时更新。< / p >
< div aria-live = "polite" class = "condition-grid mt-16" id = "simulation-comparison" >
< div > < small > 真实预审 · 保持不变< / small > < h3 > 2 项待核实< / h3 > < p > 补充材料后再判断< / p > < / div >
@@ -353,7 +329,6 @@
< section aria-labelledby = "evidence-source-tab" id = "evidence-source" role = "tabpanel" > < p class = "muted" id = "source-location" > 回款说明.pdf · 第3页 · 虚构演示< / p > < blockquote id = "source-quote" > 主要客户账期延长,预计下一季度集中回款。< / blockquote > < div class = "notice" id = "source-gap" > 尚未提供对应银行流水,不能仅凭解释确认回款。< / div > < p class = "muted" > 来源可定位不代表材料真实性已经核验。< / p > < / section >
< section aria-labelledby = "evidence-basis-tab" hidden = "" id = "evidence-basis" role = "tabpanel" > < h3 > 从解释到判断,仍缺一环< / h3 > < p id = "basis-copy" > 现有说明提出了账期变化的解释,但需要银行流水与应收账龄交叉核验。专项判断不能替代主审综合意见。< / p > < h3 > 建议下一步< / h3 > < p id = "basis-next" > 补充近六个月银行流水,逐笔匹配主要客户回款。< / p > < / section >
< / dialog >
<!-- NEW: Basis Drawer -->
< dialog aria-labelledby = "basis-title" class = "evidence-dialog" id = "basis-dialog" >
< header class = "dialog-header" >
< div >
@@ -363,7 +338,7 @@
< button aria-label = "关闭依据抽屉" class = "close-button" data-close = "basis-dialog" > × < / button >
< / header >
< div class = "p-24 overflow-y-auto" style = "height:calc(100vh - 90px)" >
< div class = "notice mb-24" > 当前基线 42% 来自人工设定的原型情景表,非模型计算、非历史统计。以下展示未来的追溯结构,不构成数字的计算来源。< / div > < div class = "notice" id = "demo-probability-source" > 演示情景表:无假设 42%;流水核验支持解释 58%;权属核验一致 51%;两者同时成立 64%。组合结果单独设定,不能把增幅简单相加。 < / div >
< div class = "notice mb-24" > 当前基线 42% 来自人工设定的原型情景表,非模型计算、非历史统计。以下展示未来的追溯结构,不构成数字的计算来源。< / div >
< div class = "flex flex-col gap-24" >
< div >
< h3 class = "text-[16px] font-bold text-ink-main mb-12 flex items-center gap-8" > < iconify-icon icon = "lucide:database" > < / iconify-icon > 1. 状态与数据卡< / h3 >
@@ -376,7 +351,7 @@
< h3 class = "text-[16px] font-bold text-ink-main mb-12 flex items-center gap-8" > < iconify-icon icon = "lucide:cpu" > < / iconify-icon > 2. 技能与规则 (Skill Trace)< / h3 >
< ul class = "checklist" >
< li > < strong > 回款交叉核验< / strong > < span class = "text-ink-mute text-[12px]" > SKILL-04 · v1.0(演示)< / span > < p > 状态:待核实。缺少对应时间段银行流水,不能判定核验通过或不通过。< / p > < / li >
< li > < strong > 权属一致性比对 < / strong > < span class = "text-ink-mute text-[12px]" > SKILL-09 · v1.0(演示)< / span > < p > 发现发票与清单异常。< / p > < / li >
< li > < strong > 权属一致性比 timelines < / strong > < span class = "text-ink-mute text-[12px]" > SKILL-09 · v1.0(演示)< / span > < p > 发现发票与清单异常。< / p > < / li >
< / ul >
< / div >
< div >
@@ -394,8 +369,27 @@
< / div >
< / div >
< / dialog >
< dialog aria-labelledby = "checklist-title" class = "center-dialog" id = "checklist -dialog"> < header class = "dialog-header" > < div > < div class = "section-eyebrow" > NEXT ACTION / 演示清单 < / div > < h2 id = "checklist -title" > 项目补件清单 < / h2 > < / div > < button aria-label = "关闭补件清单 " class = "close-button" data-close = "checklist -dialog" > × < / button > < / header > < ol class = "checklist" > < li > < strong > 近六个月银行流水与应收账龄 < / strong > < p > 标注主要客户逐笔回款,说明与合同账期的对应关系。 < / p > < / li > < li > < strong > 设备权属材料 < / strong > < p > 提供采购合同、发票和设备清单,并解释品名差异。 < / p > < / li > < / ol > < div class = "notice" > DEMO-026 · 虚构演示,未发送至任何业务系统。 < / div > < button class = "primary-button" id = "copy-checklist" > 复制清单 < / button > < p aria-live = "polite" id = "copy-status" > < / p > < / dialog >
< dialog aria-labelledby = "validation -title" class = "center-dialog" id = "validation-dialog" > < header class = "dialog-header" > < div > < div class = "section-eyebrow" > VALIDATION / 验证计划 < / div > < h2 id = "validation-title" > 待开展脱敏盲测 < / h2 > < / div > < button aria-label = "关闭验证计划" class = "close-button" data-close = "validation-dialog" > × < / button > < / header > < p > 先冻结样本和预测,再揭示专家参考意见。当前没有真实验证结果。 < / p > < ol class = "checklist" > < li > 基础预审:不使用历史经验 < / li > < li > 经验增强:主审结合已审核经验 < / li > < li > 专项增强:分别验证本地模型与 Jev(可选) < / li > < / ol > < div class = "notice" > 关注重大问题漏检、无依据结论、有效补件与耗时。阈值在试点前约定。 < / div > < / dialog >
< dialog aria-labelledby = "dimension-title" class = "evidence-dialog" id = "dimension-dialog" > < header class = "dialog-header" > < div > < div class = "section-eyebrow" > TRACE / miniOpenClaw < / div > < h2 id = "dimension-title" > < / h2 > < / div > < button aria-label = "关闭维度依据" class = "close-button" data-close = "dimension-dialog" > × < / button > < / header > < div id = "dimension-trace" > < / div > < / dialog > < dialog aria-labelledby = "method-title" class = "center-dialog" id = "probability-method -dialog"> < header class = "dialog-header" > < div > < div class = "section-eyebrow" > PROBABILITY / 结果出处 < / div > < h2 id = "method -title" > 这次概率如何得到 < / h2 > < / div > < button aria-label = "关闭概率出处 " class = "close-button" data-close = "probability-method -dialog" > × < / button > < / header > < div aria-live = "polite" class = "notice" id = "method-result" > < / div > < p > 当前依据:人工情景表 < strong > DEMO-TABLE-v1 < / strong > 。没有模型计算、真实样本统计或校准结果;六维雷达不能求和、平均或按面积换算成概率。 < / p > < table class = "method-table" > < caption > 选择键:流水假设 / 权属假设;数字为人工演示值 < / caption > < thead > < tr > < th > 键 < / th > < th > 假设组合 < / th > < th > 演示输出 < / th > < / tr > < / thead > < tbody > < tr id = "method-row-00" > < td > 00 < / td > < td > 两项均未选择 < / td > < td > 42% < / td > < / tr > < tr id = "method-row-10" > < td > 10 < / td > < td > 流水核验支持解释 < / td > < td > 58% < / td > < / tr > < tr id = "method-row-01" > < td > 01 < / td > < td > 权属核验一致 < / td > < td > 51% < / td > < / tr > < tr id = "method-row-11" > < td > 11 < / td > < td > 两项假设均成立 < / td > < td > 64% < / td > < / tr > < / tbody > < / table > < h3 class = "method-subheading" > 真实版如何计算 · 后续规划 < / h3 > < ol class = "trace-chain" > < li > < b > 01 数据卡 → Skills / 授权 Tools < / b > < p > 读取冻结事实与核验记录,保留来源和方法版本。 < / p > < / li > < li > < b > 02 特征构建 → 概率估计 → 历史校准 < / b > < p > 在明确审批口径、样本范围和制度版本后训练与验证。模型、样本、校准:当前均未接入。 < / p > < / li > < li > < b > 03 Rules / 有效性检查 → 主审解释 < / b > < p > 缺证标待核实;硬性阻断不能被高概率抵消。未校准的真实概率保持空值。 < / p > < / li > < li > < b > 04 miniOpenClaw 保留轨迹 → 人工审批 < / b > < p > 主审解释综合结论;Jev/local只承担可选专项判断,不能用其置信度替代审批概率。 < / p > < / li > < / ol > < / dialog >
< dialog aria-labelledby = "checklist -title" class = "center-dialog" id = "checklist-dialog" >
< header class = "dialog-header" > < div > < div class = "section-eyebrow" > NEXT ACTION / 演示清单< / div > < h2 id = "checklist-title" > 项目补件清单< / h2 > < / div > < button aria-label = "关闭补件清单" class = "close-button" data-close = "checklist-dialog" > × < / button > < / header >
< ol class = "checklist" >
< li > < strong > 近六个月银行流水与应收账龄< / strong > < p > 标注主要客户逐笔回款,说明与合同账期的对应关系。< / p > < / li >
< li > < strong > 设备权属材料< / strong > < p > 提供采购合同、发票和设备清单,并解释品名差异。< / p > < / li >
< / ol >
< div class = "notice" > DEMO-026 · 虚构演示,未发送至任何业务系统。< / div >
< button class = "primary-button" id = "copy-checklist" > 复制清单< / button >
< p aria-live = "polite" id = "copy-status" > < / p >
< / dialog >
< dialog aria-labelledby = "validation-title" class = "center-dialog" id = "validation-dialog" >
< header class = "dialog-header" > < div > < div class = "section-eyebrow" > VALIDATION / 验证计划< / div > < h2 id = "validation-title" > 待开展脱敏盲测< / h2 > < / div > < button aria-label = "关闭验证计划" class = "close-button" data-close = "validation-dialog" > × < / button > < / header >
< p > 先冻结样本和预测,再揭示专家参考意见。当前没有真实验证结果。< / p >
< ol class = "checklist" >
< li > 基础预审:不使用历史经验< / li >
< li > 经验增强:主审结合已审核经验< / li >
< li > 专项增强:分别验证本地模型与 Jev(可选)< / li >
< / ol >
< div class = "notice" > 关注重大问题漏检、无依据结论、有效补件与耗时。阈值在试点前约定。< / div >
< / dialog >
< script >
( ( ) => {
const $ = s => document . querySelector ( s ) , all = s => [ ... document . querySelectorAll ( s ) ] , sd = n => $ ( '[data-sd-id="' + n + '"]' ) ;
@@ -416,6 +410,38 @@
all ( 'input[name=model]' ) . forEach ( r => r . onchange = ( ) => { const off = r . value === 'off' ; $ ( '#model-status' ) . textContent = off ? '专项核查已关闭。主审仍可基于证据与经验给出有限意见。' : '本地开源模型(演示)。无真实模型请求;主审负责综合预审意见。' ; sd ( 56 ) . textContent = off ? '未执行' : '不足' ; sd ( 55 ) . textContent = off ? '专项核查' : '专项支持' } ) ;
const dimensionNames = [ '回款核验' , '财务勾稽' , '权属核验' , '交易要素' , '经验适配' , '规则覆盖' ] ;
const baseStages = [ 1 , 2 , 1 , 2 , 2 , 1 ] , stageNames = [ '未提供' , '仅有说明' , '资料待核' , '交叉核验' , '人工复核' ] ;
const dimensionTraces = [
{ card : 'DC-CASH v1.2' , skill : 'SKILL-04 v1.0 · 回款交叉核验' , tools : 'read_project_snapshot / read_document / read_method / read_checks' , input : '回款说明.pdf第3页与应收明细;近六个月银行流水缺失。' , output : '账期变化仍只有说明,无法逐笔比对。' , rule : 'RULE-CASH v1.0 · 待核实,不能把解释当成已收回资金。' , experience : 'H-018:客户结构稳定且能逐笔匹配时参考;关联回款未穿透时不适用。' } ,
{ card : 'DC-FIN v1.0' , skill : 'SKILL-FIN v1.0 · 财务口径核对' , tools : 'read_project_snapshot / read_document / read_method / read_checks' , input : '演示报表与财务说明;原始凭证和口径待复核。' , output : '仅说明资料待核,未完成收入、利润、现金流勾稽。' , rule : 'RULE-FIN v1.0 · 期间和口径未确认时不得直接比较或加分。' , experience : '经验只在期间、口径、行业适用条件一致时参考,不能套用阈值。' } ,
{ card : 'DC-TITLE v1.0' , skill : 'SKILL-09 v1.0 · 权属一致性' , tools : 'read_project_snapshot / read_document / read_method / read_checks' , input : '设备清单与发票品名差异;采购合同附件待补。' , output : '只有差异说明,真实权属尚待核验。' , rule : 'RULE-01 v1.0 · 待核实,尚未确认阻断不代表红线核查通过。' , experience : '参考核验步骤而非套用审批结论;权属链不完整时不适用通过意见。' } ,
{ card : 'DC-DEAL v1.0' , skill : 'SKILL-DEAL v1.0 · 交易要素核对' , tools : 'read_project_snapshot / read_method / read_checks' , input : '演示融资3,000万元、36个月、设备直租。' , output : '要素已列示,未核对合同条件和租金安排。' , rule : 'RULE-DEAL v1.0 · 条款和还款安排待复核,列示不等于有效。' , experience : '交易类型与期限匹配只是筛选条件,不是审批依据。' } ,
{ card : 'DC-EXP v1.0' , skill : 'SKILL-EXP v1.0 · 经验适用性核查' , tools : 'read_project_snapshot / read_method / read_experiences' , input : '虚构经验H-018及适用条件与例外。' , output : '已展示候选经验;当前缺少逐笔匹配证据,不能直接套用。' , rule : 'RULE-EXP v1.0 · 真实经验须审核、发布并冻结版本;本条仅演示。' , experience : '客户结构稳定、逐笔回款匹配;收入集中或关联回款未穿透属于例外。' } ,
{ card : 'DC-RULE v1.0' , skill : 'SKILL-RULE v1.0 · 规则结果汇总' , tools : 'read_project_snapshot / read_method / read_checks' , input : '演示规则清单与缺证状态,真实制度尚未接入。' , output : '仍有待核实规则,未形成规则全部通过的判断。' , rule : 'RULE-GATE v1.0 · 未知不能当通过;确认硬阻断时独立提示,不能被高分抵消。' , experience : '历史案例不能豁免当前有效规则;制度版本变化需重新确认适用。' }
] ;
function scenarioKey ( ) { return Number ( $ ( '#assume-bank' ) . checked ) + '' + Number ( $ ( '#assume-title' ) . checked ) }
function points ( stages ) { return stages . map ( ( v , i ) => { const a = i * Math . PI / 3 ; return ( ( v / 4 ) * 90 * Math . sin ( a ) ) . toFixed ( 2 ) + ',' + ( - ( v / 4 ) * 90 * Math . cos ( a ) ) . toFixed ( 2 ) } ) . join ( ' ' ) }
function selectedStages ( ) { const v = [ ... baseStages ] ; if ( $ ( '#assume-bank' ) . checked ) v [ 0 ] = 3 ; if ( $ ( '#assume-title' ) . checked ) v [ 2 ] = 3 ; return v }
function buildRadar ( context ) {
const svg = $ ( '#radar-' + ( context === 'baseline' ? 'baseline' : 'scenario' ) ) ;
let html = '' ;
for ( let n = 1 ; n <= 4 ; n ++ ) html += '<polygon class="grid-line" points="' + points ( Array ( 6 ) . fill ( n ) ) + '"/><text class="stage-label" x="5" y="' + ( - n * 22.5 + 3 ) + '">' + n + '</text>' ;
const labelPositions = [ [ 0 , - 111 , 'middle' ] , [ 96 , - 49 , 'start' ] , [ 96 , 58 , 'start' ] , [ 0 , 117 , 'middle' ] , [ - 96 , 58 , 'end' ] , [ - 96 , - 49 , 'end' ] ] ;
dimensionNames . forEach ( ( name , i ) => { const a = i * Math . PI / 3 ; html += '<line class="grid-line" x1="0" y1="0" x2="' + 90 * Math . sin ( a ) + '" y2="' + ( - 90 * Math . cos ( a ) ) + '"/>' } ) ;
html += '<polygon data-series="baseline" points="' + points ( baseStages ) + '"/>' ;
if ( context === 'scenario' ) html += '<polygon data-series="scenario" points="' + points ( baseStages ) + '"/>' ;
dimensionNames . forEach ( ( name , i ) => { const [ x , y , anchor ] = labelPositions [ i ] ; html += '<text class="dimension-label" data-dimension="' + i + '" data-context="' + context + '" role="button" tabindex="0" aria-label="查看' + name + '依据" x="' + x + '" y="' + y + '" text-anchor="' + anchor + '">' + name + '</text>' } ) ;
svg . innerHTML = html ;
$ ( '[data-dimension-list="' + context + '"]' ) . innerHTML = dimensionNames . map ( ( name , i ) => '<button data-dimension="' + i + '" data-context="' + context + '"><b>' + name + '</b><span data-stage-label="' + i + '">' + baseStages [ i ] + ' · ' + stageNames [ baseStages [ i ] ] + '</span></button>' ) . join ( '' ) ;
}
function updateRadar ( ) { const stages = selectedStages ( ) ; $ ( '#radar-scenario [data-series="scenario"]' ) . setAttribute ( 'points' , points ( stages ) ) ; all ( '[data-dimension-list="scenario"] [data-stage-label]' ) . forEach ( el => { const i = Number ( el . dataset . stageLabel ) , v = stages [ i ] ; el . textContent = v + ' · ' + ( v !== baseStages [ i ] ? '假设已核验' : stageNames [ v ] ) ; } ) ; }
function openDimension ( i , context ) { const d = dimensionTraces [ i ] , assumed = context === 'scenario' && selectedStages ( ) [ i ] !== baseStages [ i ] ; $ ( '#dimension-title' ) . textContent = dimensionNames [ i ] + ' · ' + ( context === 'scenario' ? '情景依据' : '当前依据' ) ; $ ( '#dimension-trace' ) . innerHTML = '<div class="notice">虚构演示链,未执行真实工具调用。' + ( assumed ? '本情景假设该维度交叉核验成立;原项目仍待核实。' : '当前材料仍须核验,不能仅凭阶段推出概率。' ) + '</div><div class="trace-chip">miniOpenClaw · 受控编排示意 / 组件版本为示例</div><ol class="trace-chain"><li><b>01 数据卡 · ' + d . card + '</b><p>' + d . input + '</p></li><li><b>02 Skill · ' + d . skill + '</b><p>组织专业方法;只使用授权的数据域与工具。</p></li><li><b>03 Tools · 允许的只读能力</b><p>' + d . tools + '</p><p>读取上下文、方法或核验记录,不代表读取工具已完成业务认证。</p></li><li><b>04 核查输出 · ' + ( assumed ? '假设状态' : '当前示例' ) + '</b><p>' + ( assumed ? '假设补充材料真实,交叉核验支持解释;实际调用尚未发生。' : d . output ) + '</p></li><li><b>05 Rules · 不可被模型分数覆盖</b><p>' + d . rule + '</p></li><li><b>06 历史经验 · 适用与例外</b><p>' + d . experience + '</p></li></ol><div class="notice">该链解释专业判断的方法与边界,不是42%的数学计算。Jev/local为可选专项判断;概率服务与校准仍待建设。</div>' ; showDialog ( 'dimension-dialog' ) ; }
function openMethod ( context ) { const key = context === 'baseline' ? '00' : scenarioKey ( ) , value = demoScenarios [ key ] . demoProbability ; $ ( '#method-result' ) . textContent = ( context === 'baseline' ? '当前基线' : '所选假设情景' ) + ' → 命中 ' + key + ' 条目 → ' + value + '%(人工演示值)' ; all ( '[id^="method-row-"]' ) . forEach ( row => row . setAttribute ( 'aria-selected' , row . id === 'method-row-' + key ) ) ; showDialog ( 'probability-method-dialog' ) ; }
buildRadar ( 'baseline' ) ; buildRadar ( 'scenario' ) ;
all ( '[data-dimension][data-context]' ) . forEach ( el => { el . onclick = ( ) => openDimension ( Number ( el . dataset . dimension ) , el . dataset . context ) ; if ( el . tagName . toLowerCase ( ) === 'text' ) el . onkeydown = e => { if ( e . key === 'Enter' || e . key === ' ' ) { e . preventDefault ( ) ; el . onclick ( ) } } } ) ;
$ ( '#btn-probability-method' ) . onclick = ( ) => openMethod ( 'baseline' ) ; $ ( '#btn-scenario-method' ) . onclick = ( ) => openMethod ( 'scenario' ) ;
// Artificial prototype lookup only: never writes a production probability.
const demoScenarios = {
'00' : { demoProbability : 42 , remaining : '2 项仍待核实(模拟)' , reason : '未选择假设。回款与设备权属证据仍有缺口,保持演示基线。' } ,
@@ -433,6 +459,7 @@
$ ( '#sim-remaining' ) . textContent = scenario . remaining ;
$ ( '#sim-explanation' ) . textContent = scenario . reason ;
$ ( '#simulation-comparison' ) . hidden = false ;
updateRadar ( ) ;
}
[ 'assume-bank' , 'assume-title' ] . forEach ( id => $ ( '#' + id ) . addEventListener ( 'change' , updateSimulation ) ) ;
$ ( '#run-simulation' ) . onclick = ( ) => showDialog ( 'basis-dialog' ) ;