index.html 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>助贷征信分析与产品匹配 - UI原型</title>
  7. <style>
  8. :root {
  9. --bg: #f8fafc;
  10. --card: #ffffff;
  11. --text: #0f172a;
  12. --sub: #64748b;
  13. --line: #e2e8f0;
  14. --primary: #2563eb;
  15. --ok: #16a34a;
  16. --warn: #f59e0b;
  17. --danger: #dc2626;
  18. --radius: 12px;
  19. }
  20. * { box-sizing: border-box; }
  21. body {
  22. margin: 0;
  23. font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
  24. background: #eef2ff;
  25. color: var(--text);
  26. display: grid;
  27. place-items: center;
  28. min-height: 100vh;
  29. padding: 20px;
  30. }
  31. .phone {
  32. width: 390px;
  33. height: 844px;
  34. background: var(--bg);
  35. border-radius: 32px;
  36. border: 8px solid #0b1220;
  37. position: relative;
  38. overflow: hidden;
  39. box-shadow: 0 20px 60px rgba(15, 23, 42, 0.35);
  40. }
  41. .status {
  42. height: 34px;
  43. font-size: 12px;
  44. color: #334155;
  45. padding: 10px 16px 0;
  46. display: flex;
  47. justify-content: space-between;
  48. background: #f1f5f9;
  49. }
  50. .screen {
  51. display: none;
  52. height: calc(100% - 34px - 68px);
  53. overflow-y: auto;
  54. padding: 16px;
  55. }
  56. .screen.active { display: block; }
  57. .screen.no-tab {
  58. height: calc(100% - 34px);
  59. padding-bottom: 28px;
  60. }
  61. h1 {
  62. font-size: 20px;
  63. margin: 0 0 8px;
  64. }
  65. h2 {
  66. font-size: 16px;
  67. margin: 0 0 8px;
  68. }
  69. .sub {
  70. color: var(--sub);
  71. font-size: 13px;
  72. margin-bottom: 14px;
  73. }
  74. .card {
  75. background: var(--card);
  76. border: 1px solid var(--line);
  77. border-radius: var(--radius);
  78. padding: 12px;
  79. margin-bottom: 12px;
  80. }
  81. .row {
  82. display: flex;
  83. gap: 8px;
  84. }
  85. .between {
  86. display: flex;
  87. justify-content: space-between;
  88. align-items: center;
  89. gap: 8px;
  90. }
  91. .stat {
  92. flex: 1;
  93. background: #eff6ff;
  94. border: 1px solid #bfdbfe;
  95. border-radius: 10px;
  96. padding: 10px;
  97. text-align: center;
  98. }
  99. .stat b { font-size: 18px; display: block; }
  100. .input {
  101. width: 100%;
  102. border: 1px solid var(--line);
  103. border-radius: 10px;
  104. padding: 11px 12px;
  105. margin-bottom: 10px;
  106. background: #fff;
  107. font-size: 14px;
  108. }
  109. .btn {
  110. width: 100%;
  111. border: none;
  112. border-radius: 10px;
  113. padding: 12px 14px;
  114. font-size: 14px;
  115. font-weight: 700;
  116. cursor: pointer;
  117. margin-top: 4px;
  118. }
  119. .btn.primary { background: var(--primary); color: #fff; }
  120. .btn.ghost { background: #fff; color: var(--primary); border: 1px solid #bfdbfe; }
  121. .btn.ok { background: var(--ok); color: #fff; }
  122. .tag {
  123. display: inline-block;
  124. font-size: 12px;
  125. border-radius: 999px;
  126. padding: 3px 8px;
  127. margin: 0 6px 6px 0;
  128. background: #eff6ff;
  129. color: var(--primary);
  130. }
  131. .tag.warn { background: #fef3c7; color: #92400e; }
  132. .tag.danger { background: #fee2e2; color: #991b1b; }
  133. .small { font-size: 12px; color: var(--sub); }
  134. .progress {
  135. height: 10px;
  136. background: #e2e8f0;
  137. border-radius: 999px;
  138. overflow: hidden;
  139. margin: 10px 0;
  140. }
  141. .bar {
  142. height: 100%;
  143. background: linear-gradient(90deg, #2563eb, #06b6d4);
  144. width: 72%;
  145. }
  146. .score {
  147. width: 110px;
  148. height: 110px;
  149. border-radius: 50%;
  150. margin: 2px auto 10px;
  151. border: 10px solid #bfdbfe;
  152. display: grid;
  153. place-items: center;
  154. color: var(--primary);
  155. font-weight: 800;
  156. font-size: 26px;
  157. background: #f8fbff;
  158. }
  159. .product {
  160. border: 1px solid #bfdbfe;
  161. background: #f8fbff;
  162. }
  163. .product h3 {
  164. margin: 0 0 8px;
  165. font-size: 15px;
  166. }
  167. .bottom-tab {
  168. position: absolute;
  169. bottom: 0;
  170. left: 0;
  171. right: 0;
  172. height: 68px;
  173. background: #fff;
  174. border-top: 1px solid var(--line);
  175. display: flex;
  176. justify-content: space-around;
  177. padding-top: 8px;
  178. }
  179. .tab {
  180. border: none;
  181. background: transparent;
  182. color: #64748b;
  183. font-size: 12px;
  184. cursor: pointer;
  185. }
  186. .tab.active { color: var(--primary); font-weight: 700; }
  187. .link {
  188. font-size: 13px;
  189. color: var(--primary);
  190. text-decoration: none;
  191. cursor: pointer;
  192. }
  193. .space { height: 8px; }
  194. .ai-fab {
  195. position: absolute;
  196. right: 14px;
  197. bottom: 86px;
  198. z-index: 8;
  199. border: none;
  200. border-radius: 999px;
  201. background: linear-gradient(135deg, #2563eb, #0ea5e9);
  202. color: #fff;
  203. font-weight: 700;
  204. font-size: 12px;
  205. padding: 10px 12px;
  206. box-shadow: 0 10px 18px rgba(37, 99, 235, 0.3);
  207. cursor: pointer;
  208. }
  209. .ai-fab.hide { display: none; }
  210. .ai-panel {
  211. position: absolute;
  212. left: 10px;
  213. right: 10px;
  214. bottom: 10px;
  215. z-index: 9;
  216. background: #fff;
  217. border: 1px solid var(--line);
  218. border-radius: 16px;
  219. box-shadow: 0 20px 30px rgba(15, 23, 42, 0.2);
  220. display: none;
  221. max-height: 62%;
  222. overflow: hidden;
  223. }
  224. .ai-panel.show { display: block; }
  225. .ai-head {
  226. display: flex;
  227. justify-content: space-between;
  228. align-items: center;
  229. padding: 10px 12px;
  230. border-bottom: 1px solid var(--line);
  231. background: #f8fbff;
  232. }
  233. .ai-title {
  234. font-size: 14px;
  235. font-weight: 700;
  236. color: #1e3a8a;
  237. }
  238. .ai-close {
  239. border: none;
  240. background: transparent;
  241. color: #64748b;
  242. font-size: 18px;
  243. cursor: pointer;
  244. }
  245. .ai-body {
  246. padding: 10px 12px 12px;
  247. overflow-y: auto;
  248. max-height: calc(62vh - 48px);
  249. }
  250. .ai-msg {
  251. background: #eff6ff;
  252. border: 1px solid #bfdbfe;
  253. border-radius: 10px;
  254. padding: 10px;
  255. font-size: 13px;
  256. margin-bottom: 10px;
  257. color: #1e3a8a;
  258. }
  259. .ai-q {
  260. border: 1px solid #dbeafe;
  261. background: #fff;
  262. color: #1d4ed8;
  263. border-radius: 999px;
  264. padding: 7px 10px;
  265. margin: 0 6px 8px 0;
  266. font-size: 12px;
  267. cursor: pointer;
  268. }
  269. .ai-input {
  270. flex: 1;
  271. border: 1px solid var(--line);
  272. border-radius: 10px;
  273. padding: 10px;
  274. font-size: 13px;
  275. margin-top: 0;
  276. }
  277. .ai-tip {
  278. margin-top: 8px;
  279. font-size: 12px;
  280. color: var(--sub);
  281. }
  282. .ai-chat {
  283. max-height: 170px;
  284. overflow-y: auto;
  285. margin: 4px 0 10px;
  286. }
  287. .ai-bubble {
  288. border-radius: 10px;
  289. padding: 8px 10px;
  290. font-size: 13px;
  291. margin-bottom: 8px;
  292. max-width: 92%;
  293. line-height: 1.45;
  294. white-space: pre-wrap;
  295. }
  296. .ai-bubble.user {
  297. margin-left: auto;
  298. background: #2563eb;
  299. color: #fff;
  300. }
  301. .ai-bubble.ai {
  302. background: #f8fafc;
  303. border: 1px solid var(--line);
  304. color: #0f172a;
  305. }
  306. .ai-input-row {
  307. display: flex;
  308. gap: 8px;
  309. align-items: center;
  310. }
  311. .ai-send {
  312. border: none;
  313. border-radius: 10px;
  314. background: #2563eb;
  315. color: #fff;
  316. font-size: 12px;
  317. font-weight: 700;
  318. padding: 10px 12px;
  319. cursor: pointer;
  320. white-space: nowrap;
  321. }
  322. .ai-loading {
  323. color: #64748b;
  324. font-size: 12px;
  325. }
  326. .ai-result h4 {
  327. margin: 0 0 6px;
  328. font-size: 13px;
  329. color: #1e3a8a;
  330. }
  331. .ai-result p {
  332. margin: 0 0 6px;
  333. font-size: 12px;
  334. color: #334155;
  335. }
  336. .ai-open-report {
  337. margin-top: 6px;
  338. width: auto;
  339. padding: 8px 10px;
  340. font-size: 12px;
  341. border-radius: 8px;
  342. }
  343. .report-page .card {
  344. margin-bottom: 10px;
  345. }
  346. .report-badge {
  347. display: inline-block;
  348. font-size: 12px;
  349. color: #1d4ed8;
  350. background: #eff6ff;
  351. border: 1px solid #bfdbfe;
  352. border-radius: 999px;
  353. padding: 4px 9px;
  354. margin-bottom: 8px;
  355. }
  356. .report-block-title {
  357. font-size: 13px;
  358. font-weight: 700;
  359. color: #1e3a8a;
  360. margin: 0 0 6px;
  361. }
  362. .report-content {
  363. font-size: 13px;
  364. line-height: 1.6;
  365. color: #334155;
  366. margin: 0;
  367. white-space: pre-wrap;
  368. }
  369. .quick-row {
  370. display: flex;
  371. gap: 8px;
  372. }
  373. .quick-btn {
  374. margin-top: 8px;
  375. padding: 9px 10px;
  376. font-size: 12px;
  377. }
  378. .pref-row {
  379. display: flex;
  380. gap: 8px;
  381. margin: 6px 0 8px;
  382. }
  383. .pref-btn {
  384. border: 1px solid #bfdbfe;
  385. background: #fff;
  386. color: #1d4ed8;
  387. border-radius: 999px;
  388. padding: 6px 10px;
  389. font-size: 12px;
  390. cursor: pointer;
  391. }
  392. .pref-btn.active {
  393. background: #2563eb;
  394. color: #fff;
  395. border-color: #2563eb;
  396. }
  397. </style>
  398. </head>
  399. <body>
  400. <div class="phone">
  401. <div class="status">
  402. <span>9:41</span>
  403. <span>5G 100%</span>
  404. </div>
  405. <section id="login" class="screen no-tab active">
  406. <h1>助贷智能工作台</h1>
  407. <p class="sub">征信分析、自动评估、一键匹配银行产品</p>
  408. <div class="card">
  409. <h2>登录</h2>
  410. <input class="input" placeholder="手机号" />
  411. <input class="input" placeholder="验证码" />
  412. <button class="btn primary" data-go="home">进入系统</button>
  413. <button class="btn ghost" data-go="register">去注册</button>
  414. <p class="small">登录即表示同意《用户协议》《隐私政策》</p>
  415. </div>
  416. </section>
  417. <section id="register" class="screen no-tab">
  418. <h1>注册账号</h1>
  419. <p class="sub">面向助贷人员注册,完成后可管理多个客户</p>
  420. <div class="card">
  421. <input class="input" placeholder="姓名" />
  422. <input class="input" placeholder="手机号" />
  423. <input class="input" placeholder="验证码" />
  424. <input class="input" placeholder="机构名称" />
  425. <input class="input" placeholder="执业城市" />
  426. <button class="btn primary" data-go="home">注册并进入系统</button>
  427. </div>
  428. <a class="link" data-go="login">返回登录</a>
  429. </section>
  430. <section id="home" class="screen">
  431. <h1>首页</h1>
  432. <p class="sub">你好,王经理。今天有 6 位客户待跟进。</p>
  433. <div class="row">
  434. <div class="stat"><b>6</b><span class="small">待处理</span></div>
  435. <div class="stat"><b>2</b><span class="small">分析中</span></div>
  436. <div class="stat"><b>3</b><span class="small">可匹配</span></div>
  437. </div>
  438. <div class="space"></div>
  439. <div class="card">
  440. <h2>快捷操作</h2>
  441. <div class="row">
  442. <button class="btn primary" data-go="add-customer">新增客户</button>
  443. <button class="btn ghost" data-go="upload">征信分析</button>
  444. </div>
  445. </div>
  446. <div class="card">
  447. <div class="between">
  448. <h2>最近客户</h2>
  449. <a class="link" data-go="customers">查看全部</a>
  450. </div>
  451. <p>张三 · 征信已分析 · 等待匹配</p>
  452. <p>李四 · 上传中</p>
  453. </div>
  454. </section>
  455. <section id="customers" class="screen">
  456. <h1>客户</h1>
  457. <input class="input" placeholder="搜索客户姓名 / 手机号" />
  458. <div>
  459. <span class="tag">全部</span>
  460. <span class="tag warn">待上传</span>
  461. <span class="tag">已分析</span>
  462. <span class="tag">已匹配</span>
  463. </div>
  464. <div class="card">
  465. <div class="between"><b>张三</b><span class="small">138****8888</span></div>
  466. <p class="small">状态:征信分析完成(B+)</p>
  467. <button class="btn primary" data-go="report">查看报告</button>
  468. <button class="btn ghost" data-go="edit-customer">编辑资料</button>
  469. </div>
  470. <div class="card">
  471. <div class="between"><b>李四</b><span class="small">139****6666</span></div>
  472. <p class="small">状态:已上传,解析中</p>
  473. <button class="btn ghost" data-go="processing">查看进度</button>
  474. <button class="btn ghost" data-go="edit-customer">编辑资料</button>
  475. </div>
  476. <button class="btn primary" data-go="add-customer">+ 新增客户</button>
  477. </section>
  478. <section id="edit-customer" class="screen no-tab">
  479. <h1>编辑客户资料</h1>
  480. <p class="sub">可随时修改客户信息,保存后即时生效(UI演示)</p>
  481. <div class="card">
  482. <input class="input" value="张三" />
  483. <input class="input" value="13800008888" />
  484. <input class="input" value="身份证后四位:1234" />
  485. <input class="input" value="职业:个体经营" />
  486. <input class="input" value="备注:近期有贷款需求,关注放款速度" />
  487. <button id="saveCustomerBtn" class="btn primary">保存客户资料</button>
  488. <p id="customerSaveTip" class="small" style="display:none;">客户资料已保存(UI演示)。</p>
  489. </div>
  490. <a class="link" data-go="customers">返回客户列表</a>
  491. </section>
  492. <section id="add-customer" class="screen no-tab">
  493. <h1>新增客户</h1>
  494. <p class="sub">先建客户档案,再进入征信分析</p>
  495. <div class="card">
  496. <input class="input" placeholder="客户姓名" />
  497. <input class="input" placeholder="手机号" />
  498. <input class="input" placeholder="身份证后四位(可选)" />
  499. <input class="input" placeholder="备注(可选)" />
  500. <button class="btn primary" data-go="upload">保存并进入征信分析</button>
  501. </div>
  502. <a class="link" data-go="home">返回首页</a>
  503. </section>
  504. <section id="upload" class="screen">
  505. <h1>征信分析</h1>
  506. <div class="card">
  507. <h2>选择客户</h2>
  508. <input class="input" value="张三(138****8888)" />
  509. </div>
  510. <div class="card">
  511. <h2>选择文件</h2>
  512. <p class="small">上传入口不限制文件类型,具体校验由程序处理。</p>
  513. <button class="btn ghost">选择文件</button>
  514. </div>
  515. <button class="btn primary" data-go="processing">开始解析</button>
  516. </section>
  517. <section id="processing" class="screen no-tab">
  518. <h1>征信解析中</h1>
  519. <p class="sub">正在解析征信数据,预计30-90秒</p>
  520. <div class="card">
  521. <div class="progress"><div class="bar"></div></div>
  522. <p class="small">当前进度:72%</p>
  523. <p class="small">你可以稍后在“报告”页查看结果</p>
  524. </div>
  525. <button class="btn ok" data-go="report">模拟解析完成</button>
  526. <a class="link" data-go="home">返回首页</a>
  527. </section>
  528. <section id="report" class="screen">
  529. <h1>征信分析报告</h1>
  530. <p class="sub">客户:张三(最近更新:今天 10:42)</p>
  531. <div class="card">
  532. <div class="score">B+</div>
  533. <p style="text-align:center;margin:0 0 8px;">建议可申请额度:20万-35万</p>
  534. <div style="text-align:center;">
  535. <span class="tag">收入稳定</span>
  536. <span class="tag warn">查询偏多</span>
  537. <span class="tag danger">负债率偏高</span>
  538. </div>
  539. </div>
  540. <div class="card">
  541. <h2>关键指标</h2>
  542. <p class="small">近3个月查询次数:8 次</p>
  543. <p class="small">信用卡使用率:72%</p>
  544. <p class="small">当前逾期:无</p>
  545. </div>
  546. <div class="card">
  547. <h2>建议动作</h2>
  548. <p class="small">1. 控制近1个月新增查询</p>
  549. <p class="small">2. 优先匹配看重流水稳定的产品</p>
  550. </div>
  551. <button class="btn primary" data-go="match">智能匹配银行产品</button>
  552. </section>
  553. <section id="match" class="screen">
  554. <h1>智能匹配结果(Top 3)</h1>
  555. <p class="sub">根据当前征信表现,推荐以下更合适产品</p>
  556. <div class="card product">
  557. <h3>产品A · 稳享贷 <span class="tag">匹配度 92%</span></h3>
  558. <p class="small">额度:20-30万 | 年化:4.2%-6.1% | 放款:T+1</p>
  559. <p class="small">匹配理由:收入稳定、无当前逾期、近半年账户活跃</p>
  560. <button class="btn ghost" data-go="product">查看详情</button>
  561. </div>
  562. <div class="card product">
  563. <h3>产品B · 惠民贷 <span class="tag">匹配度 88%</span></h3>
  564. <p class="small">额度:15-25万 | 年化:4.8%-6.8% | 放款:T+1~T+2</p>
  565. <p class="small">匹配理由:查询可接受、负债可覆盖、工作稳定</p>
  566. <button class="btn ghost" data-go="product">查看详情</button>
  567. </div>
  568. <div class="card product">
  569. <h3>产品C · 极速贷 <span class="tag">匹配度 84%</span></h3>
  570. <p class="small">额度:10-20万 | 年化:5.2%-7.2% | 放款:最快当天</p>
  571. <p class="small">匹配理由:审批快、对查询容忍较高、材料简化</p>
  572. <button class="btn ghost" data-go="product">查看详情</button>
  573. </div>
  574. <button id="rematchBtn" class="btn primary">重新匹配(调整偏好)</button>
  575. <div id="rematchPanel" class="card" style="display:none;">
  576. <h2>匹配偏好</h2>
  577. <div class="pref-row">
  578. <button class="pref-btn active" data-pref="额度优先">额度优先</button>
  579. <button class="pref-btn" data-pref="利率优先">利率优先</button>
  580. <button class="pref-btn" data-pref="放款速度优先">放款速度优先</button>
  581. </div>
  582. <button id="confirmRematchBtn" class="btn primary">确认重新匹配</button>
  583. <p id="rematchResult" class="small" style="display:none;">已按“额度优先”重新匹配,结果已更新(UI演示)。</p>
  584. </div>
  585. </section>
  586. <section id="product" class="screen no-tab">
  587. <h1>产品A · 稳享贷</h1>
  588. <p class="sub">银行直连产品,适合征信中等偏优客户</p>
  589. <div class="card">
  590. <h2>产品参数</h2>
  591. <p class="small">额度区间:20万-30万</p>
  592. <p class="small">年化区间:4.2%-6.1%</p>
  593. <p class="small">期限:12-36期</p>
  594. <p class="small">放款时效:T+1</p>
  595. </div>
  596. <div class="card">
  597. <h2>准入条件</h2>
  598. <p class="small">- 年龄22-55周岁</p>
  599. <p class="small">- 近6个月无当前逾期</p>
  600. <p class="small">- 查询次数建议低于10次/3个月</p>
  601. </div>
  602. <div class="card">
  603. <h2>风险提示</h2>
  604. <p class="small">若近期新增2次以上硬查询,审批通过率可能明显下降。</p>
  605. </div>
  606. <button class="btn primary">标记推荐给客户</button>
  607. <a class="link" data-go="match">返回匹配结果</a>
  608. </section>
  609. <section id="reports" class="screen">
  610. <h1>报告</h1>
  611. <div class="card">
  612. <div class="between"><b>张三</b><span class="tag">B+</span></div>
  613. <p class="small">已生成征信分析报告 · 10:42</p>
  614. <button class="btn ghost" data-go="report">查看</button>
  615. </div>
  616. <div class="card">
  617. <div class="between"><b>王五</b><span class="tag warn">解析中</span></div>
  618. <p class="small">上传时间:09:16</p>
  619. </div>
  620. </section>
  621. <section id="ai-report" class="screen no-tab report-page">
  622. <h1>AI专业回答</h1>
  623. <span class="report-badge" id="aiReportScene">场景:报告解读</span>
  624. <div class="card">
  625. <h2 id="aiReportQuestionTitle">用户问题</h2>
  626. <p id="aiReportQuestion" class="report-content">-</p>
  627. </div>
  628. <div class="card">
  629. <p class="report-block-title">结论</p>
  630. <p id="aiReportConclusion" class="report-content">-</p>
  631. </div>
  632. <div class="card">
  633. <p class="report-block-title">依据</p>
  634. <p id="aiReportBasis" class="report-content">-</p>
  635. </div>
  636. <div class="card">
  637. <p class="report-block-title">建议动作</p>
  638. <p id="aiReportAction" class="report-content">-</p>
  639. </div>
  640. <div class="card">
  641. <p class="report-block-title">风险提示</p>
  642. <p id="aiReportRisk" class="report-content">-</p>
  643. </div>
  644. <button id="aiReportBack" class="btn primary">回提问界面</button>
  645. <div class="quick-row">
  646. <button id="aiReportBackStart" class="btn ghost quick-btn">回开始提问页</button>
  647. <button id="aiReportHome" class="btn ghost quick-btn">一键回首页</button>
  648. </div>
  649. </section>
  650. <section id="mine" class="screen">
  651. <h1>我的</h1>
  652. <div class="card">
  653. <h2>账号信息</h2>
  654. <p class="small">姓名:王经理</p>
  655. <p class="small">机构:XX助贷服务</p>
  656. <p class="small">城市:上海</p>
  657. </div>
  658. <div class="card">
  659. <h2>设置</h2>
  660. <p class="small">隐私协议</p>
  661. <p class="small">联系客服</p>
  662. <p class="small">版本信息 v1.0</p>
  663. </div>
  664. <button class="btn primary" data-go="edit-mine">编辑我的资料</button>
  665. <button class="btn ghost" data-go="login">退出登录</button>
  666. </section>
  667. <section id="edit-mine" class="screen no-tab">
  668. <h1>编辑我的资料</h1>
  669. <p class="sub">可修改个人与机构信息,便于统一对外展示</p>
  670. <div class="card">
  671. <input class="input" value="王经理" />
  672. <input class="input" value="13800001111" />
  673. <input class="input" value="XX助贷服务" />
  674. <input class="input" value="上海" />
  675. <input class="input" value="擅长:经营贷、消费贷匹配" />
  676. <button id="saveMineBtn" class="btn primary">保存我的资料</button>
  677. <p id="mineSaveTip" class="small" style="display:none;">我的资料已保存(UI演示)。</p>
  678. </div>
  679. <a class="link" data-go="mine">返回我的</a>
  680. </section>
  681. <nav class="bottom-tab" id="tabs">
  682. <button class="tab active" data-tab="home">首页</button>
  683. <button class="tab" data-tab="customers">客户</button>
  684. <button class="tab" data-tab="upload">征信分析</button>
  685. <button class="tab" data-tab="reports">报告</button>
  686. <button class="tab" data-tab="mine">我的</button>
  687. </nav>
  688. <button id="aiFab" class="ai-fab">AI助理</button>
  689. <div id="aiPanel" class="ai-panel">
  690. <div class="ai-head">
  691. <span id="aiTitle" class="ai-title">AI助理</span>
  692. <button id="aiClose" class="ai-close" aria-label="关闭">×</button>
  693. </div>
  694. <div class="ai-body">
  695. <div id="aiIntro" class="ai-msg"></div>
  696. <div id="aiQuestions"></div>
  697. <div id="aiChat" class="ai-chat"></div>
  698. <div class="ai-input-row">
  699. <input id="aiInput" class="ai-input" placeholder="输入你的问题(UI演示,不发起真实请求)" />
  700. <button id="aiSend" class="ai-send">发送</button>
  701. </div>
  702. <p id="aiTip" class="ai-tip"></p>
  703. <div class="quick-row">
  704. <button id="aiGoStart" class="btn ghost quick-btn">回开始提问页</button>
  705. <button id="aiGoHome" class="btn ghost quick-btn">一键回首页</button>
  706. </div>
  707. </div>
  708. </div>
  709. </div>
  710. <script>
  711. const screens = document.querySelectorAll(".screen");
  712. const tabs = document.querySelectorAll(".tab");
  713. const tabsWrap = document.getElementById("tabs");
  714. const aiFab = document.getElementById("aiFab");
  715. const aiPanel = document.getElementById("aiPanel");
  716. const aiClose = document.getElementById("aiClose");
  717. const aiTitle = document.getElementById("aiTitle");
  718. const aiIntro = document.getElementById("aiIntro");
  719. const aiQuestions = document.getElementById("aiQuestions");
  720. const aiChat = document.getElementById("aiChat");
  721. const aiInput = document.getElementById("aiInput");
  722. const aiSend = document.getElementById("aiSend");
  723. const aiTip = document.getElementById("aiTip");
  724. const aiReportScene = document.getElementById("aiReportScene");
  725. const aiReportQuestion = document.getElementById("aiReportQuestion");
  726. const aiReportConclusion = document.getElementById("aiReportConclusion");
  727. const aiReportBasis = document.getElementById("aiReportBasis");
  728. const aiReportAction = document.getElementById("aiReportAction");
  729. const aiReportRisk = document.getElementById("aiReportRisk");
  730. const aiReportBack = document.getElementById("aiReportBack");
  731. const aiReportBackStart = document.getElementById("aiReportBackStart");
  732. const aiReportHome = document.getElementById("aiReportHome");
  733. const aiGoStart = document.getElementById("aiGoStart");
  734. const aiGoHome = document.getElementById("aiGoHome");
  735. const rematchBtn = document.getElementById("rematchBtn");
  736. const rematchPanel = document.getElementById("rematchPanel");
  737. const confirmRematchBtn = document.getElementById("confirmRematchBtn");
  738. const rematchResult = document.getElementById("rematchResult");
  739. const saveCustomerBtn = document.getElementById("saveCustomerBtn");
  740. const customerSaveTip = document.getElementById("customerSaveTip");
  741. const saveMineBtn = document.getElementById("saveMineBtn");
  742. const mineSaveTip = document.getElementById("mineSaveTip");
  743. let currentScreenId = "login";
  744. let beforeAiReportScreenId = "home";
  745. let aiSessionStartScreenId = "home";
  746. let lastAiResponse = null;
  747. let lastAiQuestion = "";
  748. let selectedPref = "额度优先";
  749. const aiContext = {
  750. home: {
  751. title: "AI助理 · 今日工作建议",
  752. intro: "我可以基于待处理客户优先级,给你今天最有效的跟进顺序。",
  753. questions: [
  754. "先跟进哪3位客户成功率最高?",
  755. "今天优先做征信分析还是先做产品匹配?",
  756. "给我一份30分钟高效处理清单。"
  757. ]
  758. },
  759. customers: {
  760. title: "AI助理 · 客户策略",
  761. intro: "我可以按客户状态给你建议:先补资料、先分析,还是先沟通预期。",
  762. questions: [
  763. "这个客户现在最该做什么?",
  764. "如何向客户解释‘分析中’不等于‘能通过’?",
  765. "给我一段专业但好懂的沟通话术。"
  766. ]
  767. },
  768. upload: {
  769. title: "AI助理 · 征信分析前",
  770. intro: "我可以告诉你分析前要核对的信息,避免后续匹配偏差。",
  771. questions: [
  772. "开始分析前我需要确认哪些客户信息?",
  773. "如何减少因资料缺失导致的误判?",
  774. "给我一段让客户配合补充资料的话术。"
  775. ]
  776. },
  777. processing: {
  778. title: "AI助理 · 解析等待中",
  779. intro: "等待期间可提前准备沟通策略,分析完成后直接进入匹配。",
  780. questions: [
  781. "结果出来后第一句话怎么跟客户说?",
  782. "如果评级一般,怎么引导客户接受方案?",
  783. "先讲风险还是先讲可做产品?"
  784. ]
  785. },
  786. report: {
  787. title: "AI助理 · 报告解读",
  788. intro: "我可以把征信指标翻译成可执行建议:结论、依据、动作、风险提示。",
  789. questions: [
  790. "这份征信最核心的3个风险是什么?",
  791. "为什么是B+,不是A?",
  792. "未来30天怎么优化通过率?"
  793. ]
  794. },
  795. match: {
  796. title: "AI助理 · 产品对比",
  797. intro: "我可以解释Top3推荐差异,并按‘额度/利率/速度’给排序建议。",
  798. questions: [
  799. "这3个产品该怎么给客户讲差异?",
  800. "客户要低利率,应该优先推荐哪个?",
  801. "客户要快放款,顺序怎么排?"
  802. ]
  803. },
  804. product: {
  805. title: "AI助理 · 进件建议",
  806. intro: "我可以根据该产品准入条件,给你进件前风险提醒和补件建议。",
  807. questions: [
  808. "这个客户做该产品的主要风险点是什么?",
  809. "进件前还建议补哪些材料?",
  810. "如果被拒,备选产品顺序怎么给?"
  811. ]
  812. },
  813. reports: {
  814. title: "AI助理 · 报告汇总",
  815. intro: "我可以帮你快速定位需要优先复盘的客户报告。",
  816. questions: [
  817. "哪几份报告最值得今天先处理?",
  818. "解析中客户要提前准备什么?",
  819. "帮我总结常见风险类型。"
  820. ]
  821. },
  822. mine: {
  823. title: "AI助理 · 业务复盘",
  824. intro: "我可以帮你做今日复盘,沉淀可复用的话术与流程。",
  825. questions: [
  826. "今天哪些动作最提升成单概率?",
  827. "帮我总结一版标准跟进SOP。",
  828. "如何提高客户配合上传资料率?"
  829. ]
  830. }
  831. };
  832. function renderAiContext(id) {
  833. const ctx = aiContext[id] || aiContext.home;
  834. aiTitle.textContent = ctx.title;
  835. aiIntro.textContent = ctx.intro;
  836. aiQuestions.innerHTML = "";
  837. aiChat.innerHTML = "";
  838. ctx.questions.forEach(q => {
  839. const btn = document.createElement("button");
  840. btn.className = "ai-q";
  841. btn.textContent = q;
  842. btn.setAttribute("data-ai-q", q);
  843. aiQuestions.appendChild(btn);
  844. });
  845. aiTip.textContent = "提示:当前为UI演示。输入问题后点击“发送”可查看模拟AI返回结构。";
  846. }
  847. function addUserMessage(text) {
  848. const msg = document.createElement("div");
  849. msg.className = "ai-bubble user";
  850. msg.textContent = text;
  851. aiChat.appendChild(msg);
  852. aiChat.scrollTop = aiChat.scrollHeight;
  853. }
  854. function buildMockAnswer(screenId) {
  855. const answerMap = {
  856. report: {
  857. conclusion: "该客户当前可做稳健型产品,建议先控查询再推进主推产品。",
  858. basis: "依据:近3个月查询次数偏多、信用卡使用率72%、当前无逾期。",
  859. action: "动作:1) 7-14天内避免新增硬查询 2) 优先申请看重流水稳定产品 3) 先小额试单。",
  860. risk: "风险提示:最终以银行实时审批为准,不承诺100%通过。"
  861. },
  862. match: {
  863. conclusion: "若客户优先低利率,先推产品A;若优先速度,优先产品C。",
  864. basis: "依据:A匹配度92%且利率区间更优,C放款时效最快。",
  865. action: "动作:先确认客户优先级(利率/额度/速度),再给2选1方案。",
  866. risk: "风险提示:若近期新增查询,产品A通过率可能下降。"
  867. },
  868. product: {
  869. conclusion: "该产品适配中等偏优客户,当前客户可尝试但需先做风险沟通。",
  870. basis: "依据:准入条件与客户现状基本匹配,查询次数接近敏感阈值。",
  871. action: "动作:补充收入证明并先做预审沟通,再正式进件。",
  872. risk: "风险提示:若被拒,建议切换容忍查询更高的备选产品。"
  873. }
  874. };
  875. return answerMap[screenId] || {
  876. conclusion: "当前阶段建议先明确客户目标,再进入下一步操作。",
  877. basis: "依据:页面信息可支持基础判断,但仍需补充客户偏好与近期变化。",
  878. action: "动作:先确认目标(额度/利率/放款速度),再执行对应流程。",
  879. risk: "风险提示:建议始终向客户说明“最终以银行审批为准”。"
  880. };
  881. }
  882. function getSceneName(screenId) {
  883. const map = {
  884. home: "首页工作建议",
  885. customers: "客户策略",
  886. upload: "征信分析前",
  887. processing: "解析等待中",
  888. report: "征信报告解读",
  889. match: "产品匹配对比",
  890. product: "产品进件建议",
  891. reports: "报告汇总",
  892. mine: "业务复盘"
  893. };
  894. return map[screenId] || "综合建议";
  895. }
  896. function fillAiReport(screenId, question, data) {
  897. aiReportScene.textContent = `场景:${getSceneName(screenId)}`;
  898. aiReportQuestion.textContent = question || "未记录问题";
  899. aiReportConclusion.textContent = data.conclusion || "-";
  900. aiReportBasis.textContent = data.basis || "-";
  901. aiReportAction.textContent = data.action || "-";
  902. aiReportRisk.textContent = data.risk || "-";
  903. }
  904. function addAiMessage(screenId, question) {
  905. const data = buildMockAnswer(screenId);
  906. lastAiResponse = data;
  907. lastAiQuestion = question;
  908. const wrap = document.createElement("div");
  909. wrap.className = "ai-bubble ai ai-result";
  910. wrap.innerHTML = `
  911. <h4>结论</h4><p>${data.conclusion}</p>
  912. <h4>依据</h4><p>${data.basis}</p>
  913. <h4>建议动作</h4><p>${data.action}</p>
  914. <h4>风险提示</h4><p>${data.risk}</p>
  915. <button class="btn ghost ai-open-report" data-ai-open-report="1">查看完整回答</button>
  916. `;
  917. aiChat.appendChild(wrap);
  918. aiChat.scrollTop = aiChat.scrollHeight;
  919. }
  920. function submitAiQuestion() {
  921. const q = aiInput.value.trim();
  922. if (!q) return;
  923. addUserMessage(q);
  924. aiInput.value = "";
  925. const loading = document.createElement("div");
  926. loading.className = "ai-bubble ai ai-loading";
  927. loading.textContent = "AI正在生成专业建议...";
  928. aiChat.appendChild(loading);
  929. aiChat.scrollTop = aiChat.scrollHeight;
  930. setTimeout(() => {
  931. loading.remove();
  932. addAiMessage(currentScreenId, q);
  933. }, 550);
  934. }
  935. function updateAiEntry(id) {
  936. currentScreenId = id;
  937. renderAiContext(id);
  938. const hideAi = id === "login" || id === "register";
  939. aiFab.classList.toggle("hide", hideAi);
  940. if (hideAi) aiPanel.classList.remove("show");
  941. }
  942. function show(id) {
  943. screens.forEach(s => s.classList.remove("active"));
  944. const target = document.getElementById(id);
  945. if (!target) return;
  946. target.classList.add("active");
  947. const noTab = target.classList.contains("no-tab") || id === "login";
  948. tabsWrap.style.display = noTab ? "none" : "flex";
  949. tabs.forEach(t => t.classList.remove("active"));
  950. const hit = document.querySelector(`.tab[data-tab="${id}"]`);
  951. if (hit) hit.classList.add("active");
  952. updateAiEntry(id);
  953. }
  954. tabs.forEach(btn => {
  955. btn.addEventListener("click", () => show(btn.dataset.tab));
  956. });
  957. document.body.addEventListener("click", e => {
  958. const btn = e.target.closest("[data-go]");
  959. if (!btn) return;
  960. show(btn.dataset.go);
  961. });
  962. aiFab.addEventListener("click", () => {
  963. aiSessionStartScreenId = currentScreenId;
  964. renderAiContext(currentScreenId);
  965. aiPanel.classList.add("show");
  966. });
  967. aiClose.addEventListener("click", () => {
  968. aiPanel.classList.remove("show");
  969. });
  970. aiQuestions.addEventListener("click", e => {
  971. const btn = e.target.closest("[data-ai-q]");
  972. if (!btn) return;
  973. aiInput.value = btn.getAttribute("data-ai-q");
  974. });
  975. aiChat.addEventListener("click", e => {
  976. const btn = e.target.closest("[data-ai-open-report]");
  977. if (!btn || !lastAiResponse) return;
  978. beforeAiReportScreenId = currentScreenId;
  979. fillAiReport(currentScreenId, lastAiQuestion, lastAiResponse);
  980. aiPanel.classList.remove("show");
  981. show("ai-report");
  982. });
  983. aiSend.addEventListener("click", submitAiQuestion);
  984. aiInput.addEventListener("keydown", e => {
  985. if (e.key === "Enter") submitAiQuestion();
  986. });
  987. aiReportBack.addEventListener("click", () => {
  988. show(beforeAiReportScreenId);
  989. aiPanel.classList.add("show");
  990. });
  991. aiReportBackStart.addEventListener("click", () => {
  992. show(aiSessionStartScreenId || "home");
  993. aiPanel.classList.add("show");
  994. });
  995. aiReportHome.addEventListener("click", () => {
  996. aiPanel.classList.remove("show");
  997. show("home");
  998. });
  999. aiGoStart.addEventListener("click", () => {
  1000. aiPanel.classList.remove("show");
  1001. show(aiSessionStartScreenId || "home");
  1002. });
  1003. aiGoHome.addEventListener("click", () => {
  1004. aiPanel.classList.remove("show");
  1005. show("home");
  1006. });
  1007. rematchBtn.addEventListener("click", () => {
  1008. const opened = rematchPanel.style.display === "block";
  1009. rematchPanel.style.display = opened ? "none" : "block";
  1010. if (!opened) rematchResult.style.display = "none";
  1011. });
  1012. rematchPanel.addEventListener("click", e => {
  1013. const btn = e.target.closest("[data-pref]");
  1014. if (!btn) return;
  1015. selectedPref = btn.getAttribute("data-pref");
  1016. rematchPanel.querySelectorAll(".pref-btn").forEach(el => el.classList.remove("active"));
  1017. btn.classList.add("active");
  1018. });
  1019. confirmRematchBtn.addEventListener("click", () => {
  1020. rematchResult.textContent = `已按“${selectedPref}”重新匹配,结果已更新(UI演示)。`;
  1021. rematchResult.style.display = "block";
  1022. });
  1023. saveCustomerBtn.addEventListener("click", () => {
  1024. customerSaveTip.style.display = "block";
  1025. });
  1026. saveMineBtn.addEventListener("click", () => {
  1027. mineSaveTip.style.display = "block";
  1028. });
  1029. updateAiEntry("login");
  1030. </script>
  1031. </body>
  1032. </html>