|
@@ -0,0 +1,1081 @@
|
|
|
|
|
+<!DOCTYPE html>
|
|
|
|
|
+<html lang="zh-CN">
|
|
|
|
|
+<head>
|
|
|
|
|
+ <meta charset="UTF-8" />
|
|
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
|
|
+ <title>助贷征信分析与产品匹配 - UI原型</title>
|
|
|
|
|
+ <style>
|
|
|
|
|
+ :root {
|
|
|
|
|
+ --bg: #f8fafc;
|
|
|
|
|
+ --card: #ffffff;
|
|
|
|
|
+ --text: #0f172a;
|
|
|
|
|
+ --sub: #64748b;
|
|
|
|
|
+ --line: #e2e8f0;
|
|
|
|
|
+ --primary: #2563eb;
|
|
|
|
|
+ --ok: #16a34a;
|
|
|
|
|
+ --warn: #f59e0b;
|
|
|
|
|
+ --danger: #dc2626;
|
|
|
|
|
+ --radius: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+ * { box-sizing: border-box; }
|
|
|
|
|
+ body {
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
|
|
|
|
|
+ background: #eef2ff;
|
|
|
|
|
+ color: var(--text);
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ place-items: center;
|
|
|
|
|
+ min-height: 100vh;
|
|
|
|
|
+ padding: 20px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .phone {
|
|
|
|
|
+ width: 390px;
|
|
|
|
|
+ height: 844px;
|
|
|
|
|
+ background: var(--bg);
|
|
|
|
|
+ border-radius: 32px;
|
|
|
|
|
+ border: 8px solid #0b1220;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ box-shadow: 0 20px 60px rgba(15, 23, 42, 0.35);
|
|
|
|
|
+ }
|
|
|
|
|
+ .status {
|
|
|
|
|
+ height: 34px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ padding: 10px 16px 0;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ background: #f1f5f9;
|
|
|
|
|
+ }
|
|
|
|
|
+ .screen {
|
|
|
|
|
+ display: none;
|
|
|
|
|
+ height: calc(100% - 34px - 68px);
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .screen.active { display: block; }
|
|
|
|
|
+ .screen.no-tab {
|
|
|
|
|
+ height: calc(100% - 34px);
|
|
|
|
|
+ padding-bottom: 28px;
|
|
|
|
|
+ }
|
|
|
|
|
+ h1 {
|
|
|
|
|
+ font-size: 20px;
|
|
|
|
|
+ margin: 0 0 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ h2 {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ margin: 0 0 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .sub {
|
|
|
|
|
+ color: var(--sub);
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ margin-bottom: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card {
|
|
|
|
|
+ background: var(--card);
|
|
|
|
|
+ border: 1px solid var(--line);
|
|
|
|
|
+ border-radius: var(--radius);
|
|
|
|
|
+ padding: 12px;
|
|
|
|
|
+ margin-bottom: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .between {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .stat {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ background: #eff6ff;
|
|
|
|
|
+ border: 1px solid #bfdbfe;
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ }
|
|
|
|
|
+ .stat b { font-size: 18px; display: block; }
|
|
|
|
|
+ .input {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ border: 1px solid var(--line);
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ padding: 11px 12px;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .btn {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ padding: 12px 14px;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ margin-top: 4px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .btn.primary { background: var(--primary); color: #fff; }
|
|
|
|
|
+ .btn.ghost { background: #fff; color: var(--primary); border: 1px solid #bfdbfe; }
|
|
|
|
|
+ .btn.ok { background: var(--ok); color: #fff; }
|
|
|
|
|
+ .tag {
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ padding: 3px 8px;
|
|
|
|
|
+ margin: 0 6px 6px 0;
|
|
|
|
|
+ background: #eff6ff;
|
|
|
|
|
+ color: var(--primary);
|
|
|
|
|
+ }
|
|
|
|
|
+ .tag.warn { background: #fef3c7; color: #92400e; }
|
|
|
|
|
+ .tag.danger { background: #fee2e2; color: #991b1b; }
|
|
|
|
|
+ .small { font-size: 12px; color: var(--sub); }
|
|
|
|
|
+ .progress {
|
|
|
|
|
+ height: 10px;
|
|
|
|
|
+ background: #e2e8f0;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ margin: 10px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ .bar {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ background: linear-gradient(90deg, #2563eb, #06b6d4);
|
|
|
|
|
+ width: 72%;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score {
|
|
|
|
|
+ width: 110px;
|
|
|
|
|
+ height: 110px;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ margin: 2px auto 10px;
|
|
|
|
|
+ border: 10px solid #bfdbfe;
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ place-items: center;
|
|
|
|
|
+ color: var(--primary);
|
|
|
|
|
+ font-weight: 800;
|
|
|
|
|
+ font-size: 26px;
|
|
|
|
|
+ background: #f8fbff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .product {
|
|
|
|
|
+ border: 1px solid #bfdbfe;
|
|
|
|
|
+ background: #f8fbff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .product h3 {
|
|
|
|
|
+ margin: 0 0 8px;
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .bottom-tab {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ height: 68px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-top: 1px solid var(--line);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-around;
|
|
|
|
|
+ padding-top: 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .tab {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ background: transparent;
|
|
|
|
|
+ color: #64748b;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .tab.active { color: var(--primary); font-weight: 700; }
|
|
|
|
|
+ .link {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: var(--primary);
|
|
|
|
|
+ text-decoration: none;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .space { height: 8px; }
|
|
|
|
|
+ .ai-fab {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ right: 14px;
|
|
|
|
|
+ bottom: 86px;
|
|
|
|
|
+ z-index: 8;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ background: linear-gradient(135deg, #2563eb, #0ea5e9);
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ box-shadow: 0 10px 18px rgba(37, 99, 235, 0.3);
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-fab.hide { display: none; }
|
|
|
|
|
+ .ai-panel {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ left: 10px;
|
|
|
|
|
+ right: 10px;
|
|
|
|
|
+ bottom: 10px;
|
|
|
|
|
+ z-index: 9;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border: 1px solid var(--line);
|
|
|
|
|
+ border-radius: 16px;
|
|
|
|
|
+ box-shadow: 0 20px 30px rgba(15, 23, 42, 0.2);
|
|
|
|
|
+ display: none;
|
|
|
|
|
+ max-height: 62%;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-panel.show { display: block; }
|
|
|
|
|
+ .ai-head {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ border-bottom: 1px solid var(--line);
|
|
|
|
|
+ background: #f8fbff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-title {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ color: #1e3a8a;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-close {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ background: transparent;
|
|
|
|
|
+ color: #64748b;
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-body {
|
|
|
|
|
+ padding: 10px 12px 12px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ max-height: calc(62vh - 48px);
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-msg {
|
|
|
|
|
+ background: #eff6ff;
|
|
|
|
|
+ border: 1px solid #bfdbfe;
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+ color: #1e3a8a;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-q {
|
|
|
|
|
+ border: 1px solid #dbeafe;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ color: #1d4ed8;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ padding: 7px 10px;
|
|
|
|
|
+ margin: 0 6px 8px 0;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-input {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ border: 1px solid var(--line);
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ margin-top: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-tip {
|
|
|
|
|
+ margin-top: 8px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: var(--sub);
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-chat {
|
|
|
|
|
+ max-height: 170px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ margin: 4px 0 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-bubble {
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ padding: 8px 10px;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+ max-width: 92%;
|
|
|
|
|
+ line-height: 1.45;
|
|
|
|
|
+ white-space: pre-wrap;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-bubble.user {
|
|
|
|
|
+ margin-left: auto;
|
|
|
|
|
+ background: #2563eb;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-bubble.ai {
|
|
|
|
|
+ background: #f8fafc;
|
|
|
|
|
+ border: 1px solid var(--line);
|
|
|
|
|
+ color: #0f172a;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-input-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-send {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ background: #2563eb;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-loading {
|
|
|
|
|
+ color: #64748b;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-result h4 {
|
|
|
|
|
+ margin: 0 0 6px;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #1e3a8a;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-result p {
|
|
|
|
|
+ margin: 0 0 6px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ai-open-report {
|
|
|
|
|
+ margin-top: 6px;
|
|
|
|
|
+ width: auto;
|
|
|
|
|
+ padding: 8px 10px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .report-page .card {
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .report-badge {
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: #1d4ed8;
|
|
|
|
|
+ background: #eff6ff;
|
|
|
|
|
+ border: 1px solid #bfdbfe;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ padding: 4px 9px;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .report-block-title {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ color: #1e3a8a;
|
|
|
|
|
+ margin: 0 0 6px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .report-content {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ line-height: 1.6;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ white-space: pre-wrap;
|
|
|
|
|
+ }
|
|
|
|
|
+ .quick-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .quick-btn {
|
|
|
|
|
+ margin-top: 8px;
|
|
|
|
|
+ padding: 9px 10px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .pref-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ margin: 6px 0 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .pref-btn {
|
|
|
|
|
+ border: 1px solid #bfdbfe;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ color: #1d4ed8;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ padding: 6px 10px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .pref-btn.active {
|
|
|
|
|
+ background: #2563eb;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ border-color: #2563eb;
|
|
|
|
|
+ }
|
|
|
|
|
+ </style>
|
|
|
|
|
+</head>
|
|
|
|
|
+<body>
|
|
|
|
|
+ <div class="phone">
|
|
|
|
|
+ <div class="status">
|
|
|
|
|
+ <span>9:41</span>
|
|
|
|
|
+ <span>5G 100%</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="login" class="screen no-tab active">
|
|
|
|
|
+ <h1>助贷智能工作台</h1>
|
|
|
|
|
+ <p class="sub">征信分析、自动评估、一键匹配银行产品</p>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>登录</h2>
|
|
|
|
|
+ <input class="input" placeholder="手机号" />
|
|
|
|
|
+ <input class="input" placeholder="验证码" />
|
|
|
|
|
+ <button class="btn primary" data-go="home">进入系统</button>
|
|
|
|
|
+ <button class="btn ghost" data-go="register">去注册</button>
|
|
|
|
|
+ <p class="small">登录即表示同意《用户协议》《隐私政策》</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="register" class="screen no-tab">
|
|
|
|
|
+ <h1>注册账号</h1>
|
|
|
|
|
+ <p class="sub">面向助贷人员注册,完成后可管理多个客户</p>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <input class="input" placeholder="姓名" />
|
|
|
|
|
+ <input class="input" placeholder="手机号" />
|
|
|
|
|
+ <input class="input" placeholder="验证码" />
|
|
|
|
|
+ <input class="input" placeholder="机构名称" />
|
|
|
|
|
+ <input class="input" placeholder="执业城市" />
|
|
|
|
|
+ <button class="btn primary" data-go="home">注册并进入系统</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <a class="link" data-go="login">返回登录</a>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="home" class="screen">
|
|
|
|
|
+ <h1>首页</h1>
|
|
|
|
|
+ <p class="sub">你好,王经理。今天有 6 位客户待跟进。</p>
|
|
|
|
|
+ <div class="row">
|
|
|
|
|
+ <div class="stat"><b>6</b><span class="small">待处理</span></div>
|
|
|
|
|
+ <div class="stat"><b>2</b><span class="small">分析中</span></div>
|
|
|
|
|
+ <div class="stat"><b>3</b><span class="small">可匹配</span></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="space"></div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>快捷操作</h2>
|
|
|
|
|
+ <div class="row">
|
|
|
|
|
+ <button class="btn primary" data-go="add-customer">新增客户</button>
|
|
|
|
|
+ <button class="btn ghost" data-go="upload">征信分析</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <div class="between">
|
|
|
|
|
+ <h2>最近客户</h2>
|
|
|
|
|
+ <a class="link" data-go="customers">查看全部</a>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <p>张三 · 征信已分析 · 等待匹配</p>
|
|
|
|
|
+ <p>李四 · 上传中</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="customers" class="screen">
|
|
|
|
|
+ <h1>客户</h1>
|
|
|
|
|
+ <input class="input" placeholder="搜索客户姓名 / 手机号" />
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <span class="tag">全部</span>
|
|
|
|
|
+ <span class="tag warn">待上传</span>
|
|
|
|
|
+ <span class="tag">已分析</span>
|
|
|
|
|
+ <span class="tag">已匹配</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <div class="between"><b>张三</b><span class="small">138****8888</span></div>
|
|
|
|
|
+ <p class="small">状态:征信分析完成(B+)</p>
|
|
|
|
|
+ <button class="btn primary" data-go="report">查看报告</button>
|
|
|
|
|
+ <button class="btn ghost" data-go="edit-customer">编辑资料</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <div class="between"><b>李四</b><span class="small">139****6666</span></div>
|
|
|
|
|
+ <p class="small">状态:已上传,解析中</p>
|
|
|
|
|
+ <button class="btn ghost" data-go="processing">查看进度</button>
|
|
|
|
|
+ <button class="btn ghost" data-go="edit-customer">编辑资料</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button class="btn primary" data-go="add-customer">+ 新增客户</button>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="edit-customer" class="screen no-tab">
|
|
|
|
|
+ <h1>编辑客户资料</h1>
|
|
|
|
|
+ <p class="sub">可随时修改客户信息,保存后即时生效(UI演示)</p>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <input class="input" value="张三" />
|
|
|
|
|
+ <input class="input" value="13800008888" />
|
|
|
|
|
+ <input class="input" value="身份证后四位:1234" />
|
|
|
|
|
+ <input class="input" value="职业:个体经营" />
|
|
|
|
|
+ <input class="input" value="备注:近期有贷款需求,关注放款速度" />
|
|
|
|
|
+ <button id="saveCustomerBtn" class="btn primary">保存客户资料</button>
|
|
|
|
|
+ <p id="customerSaveTip" class="small" style="display:none;">客户资料已保存(UI演示)。</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <a class="link" data-go="customers">返回客户列表</a>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="add-customer" class="screen no-tab">
|
|
|
|
|
+ <h1>新增客户</h1>
|
|
|
|
|
+ <p class="sub">先建客户档案,再进入征信分析</p>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <input class="input" placeholder="客户姓名" />
|
|
|
|
|
+ <input class="input" placeholder="手机号" />
|
|
|
|
|
+ <input class="input" placeholder="身份证后四位(可选)" />
|
|
|
|
|
+ <input class="input" placeholder="备注(可选)" />
|
|
|
|
|
+ <button class="btn primary" data-go="upload">保存并进入征信分析</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <a class="link" data-go="home">返回首页</a>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="upload" class="screen">
|
|
|
|
|
+ <h1>征信分析</h1>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>选择客户</h2>
|
|
|
|
|
+ <input class="input" value="张三(138****8888)" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>选择文件</h2>
|
|
|
|
|
+ <p class="small">上传入口不限制文件类型,具体校验由程序处理。</p>
|
|
|
|
|
+ <button class="btn ghost">选择文件</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button class="btn primary" data-go="processing">开始解析</button>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="processing" class="screen no-tab">
|
|
|
|
|
+ <h1>征信解析中</h1>
|
|
|
|
|
+ <p class="sub">正在解析征信数据,预计30-90秒</p>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <div class="progress"><div class="bar"></div></div>
|
|
|
|
|
+ <p class="small">当前进度:72%</p>
|
|
|
|
|
+ <p class="small">你可以稍后在“报告”页查看结果</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button class="btn ok" data-go="report">模拟解析完成</button>
|
|
|
|
|
+ <a class="link" data-go="home">返回首页</a>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="report" class="screen">
|
|
|
|
|
+ <h1>征信分析报告</h1>
|
|
|
|
|
+ <p class="sub">客户:张三(最近更新:今天 10:42)</p>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <div class="score">B+</div>
|
|
|
|
|
+ <p style="text-align:center;margin:0 0 8px;">建议可申请额度:20万-35万</p>
|
|
|
|
|
+ <div style="text-align:center;">
|
|
|
|
|
+ <span class="tag">收入稳定</span>
|
|
|
|
|
+ <span class="tag warn">查询偏多</span>
|
|
|
|
|
+ <span class="tag danger">负债率偏高</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>关键指标</h2>
|
|
|
|
|
+ <p class="small">近3个月查询次数:8 次</p>
|
|
|
|
|
+ <p class="small">信用卡使用率:72%</p>
|
|
|
|
|
+ <p class="small">当前逾期:无</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>建议动作</h2>
|
|
|
|
|
+ <p class="small">1. 控制近1个月新增查询</p>
|
|
|
|
|
+ <p class="small">2. 优先匹配看重流水稳定的产品</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button class="btn primary" data-go="match">智能匹配银行产品</button>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="match" class="screen">
|
|
|
|
|
+ <h1>智能匹配结果(Top 3)</h1>
|
|
|
|
|
+ <p class="sub">根据当前征信表现,推荐以下更合适产品</p>
|
|
|
|
|
+ <div class="card product">
|
|
|
|
|
+ <h3>产品A · 稳享贷 <span class="tag">匹配度 92%</span></h3>
|
|
|
|
|
+ <p class="small">额度:20-30万 | 年化:4.2%-6.1% | 放款:T+1</p>
|
|
|
|
|
+ <p class="small">匹配理由:收入稳定、无当前逾期、近半年账户活跃</p>
|
|
|
|
|
+ <button class="btn ghost" data-go="product">查看详情</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card product">
|
|
|
|
|
+ <h3>产品B · 惠民贷 <span class="tag">匹配度 88%</span></h3>
|
|
|
|
|
+ <p class="small">额度:15-25万 | 年化:4.8%-6.8% | 放款:T+1~T+2</p>
|
|
|
|
|
+ <p class="small">匹配理由:查询可接受、负债可覆盖、工作稳定</p>
|
|
|
|
|
+ <button class="btn ghost" data-go="product">查看详情</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card product">
|
|
|
|
|
+ <h3>产品C · 极速贷 <span class="tag">匹配度 84%</span></h3>
|
|
|
|
|
+ <p class="small">额度:10-20万 | 年化:5.2%-7.2% | 放款:最快当天</p>
|
|
|
|
|
+ <p class="small">匹配理由:审批快、对查询容忍较高、材料简化</p>
|
|
|
|
|
+ <button class="btn ghost" data-go="product">查看详情</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button id="rematchBtn" class="btn primary">重新匹配(调整偏好)</button>
|
|
|
|
|
+ <div id="rematchPanel" class="card" style="display:none;">
|
|
|
|
|
+ <h2>匹配偏好</h2>
|
|
|
|
|
+ <div class="pref-row">
|
|
|
|
|
+ <button class="pref-btn active" data-pref="额度优先">额度优先</button>
|
|
|
|
|
+ <button class="pref-btn" data-pref="利率优先">利率优先</button>
|
|
|
|
|
+ <button class="pref-btn" data-pref="放款速度优先">放款速度优先</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button id="confirmRematchBtn" class="btn primary">确认重新匹配</button>
|
|
|
|
|
+ <p id="rematchResult" class="small" style="display:none;">已按“额度优先”重新匹配,结果已更新(UI演示)。</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="product" class="screen no-tab">
|
|
|
|
|
+ <h1>产品A · 稳享贷</h1>
|
|
|
|
|
+ <p class="sub">银行直连产品,适合征信中等偏优客户</p>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>产品参数</h2>
|
|
|
|
|
+ <p class="small">额度区间:20万-30万</p>
|
|
|
|
|
+ <p class="small">年化区间:4.2%-6.1%</p>
|
|
|
|
|
+ <p class="small">期限:12-36期</p>
|
|
|
|
|
+ <p class="small">放款时效:T+1</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>准入条件</h2>
|
|
|
|
|
+ <p class="small">- 年龄22-55周岁</p>
|
|
|
|
|
+ <p class="small">- 近6个月无当前逾期</p>
|
|
|
|
|
+ <p class="small">- 查询次数建议低于10次/3个月</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>风险提示</h2>
|
|
|
|
|
+ <p class="small">若近期新增2次以上硬查询,审批通过率可能明显下降。</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button class="btn primary">标记推荐给客户</button>
|
|
|
|
|
+ <a class="link" data-go="match">返回匹配结果</a>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="reports" class="screen">
|
|
|
|
|
+ <h1>报告</h1>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <div class="between"><b>张三</b><span class="tag">B+</span></div>
|
|
|
|
|
+ <p class="small">已生成征信分析报告 · 10:42</p>
|
|
|
|
|
+ <button class="btn ghost" data-go="report">查看</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <div class="between"><b>王五</b><span class="tag warn">解析中</span></div>
|
|
|
|
|
+ <p class="small">上传时间:09:16</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="ai-report" class="screen no-tab report-page">
|
|
|
|
|
+ <h1>AI专业回答</h1>
|
|
|
|
|
+ <span class="report-badge" id="aiReportScene">场景:报告解读</span>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2 id="aiReportQuestionTitle">用户问题</h2>
|
|
|
|
|
+ <p id="aiReportQuestion" class="report-content">-</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <p class="report-block-title">结论</p>
|
|
|
|
|
+ <p id="aiReportConclusion" class="report-content">-</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <p class="report-block-title">依据</p>
|
|
|
|
|
+ <p id="aiReportBasis" class="report-content">-</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <p class="report-block-title">建议动作</p>
|
|
|
|
|
+ <p id="aiReportAction" class="report-content">-</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <p class="report-block-title">风险提示</p>
|
|
|
|
|
+ <p id="aiReportRisk" class="report-content">-</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button id="aiReportBack" class="btn primary">回提问界面</button>
|
|
|
|
|
+ <div class="quick-row">
|
|
|
|
|
+ <button id="aiReportBackStart" class="btn ghost quick-btn">回开始提问页</button>
|
|
|
|
|
+ <button id="aiReportHome" class="btn ghost quick-btn">一键回首页</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="mine" class="screen">
|
|
|
|
|
+ <h1>我的</h1>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>账号信息</h2>
|
|
|
|
|
+ <p class="small">姓名:王经理</p>
|
|
|
|
|
+ <p class="small">机构:XX助贷服务</p>
|
|
|
|
|
+ <p class="small">城市:上海</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h2>设置</h2>
|
|
|
|
|
+ <p class="small">隐私协议</p>
|
|
|
|
|
+ <p class="small">联系客服</p>
|
|
|
|
|
+ <p class="small">版本信息 v1.0</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button class="btn primary" data-go="edit-mine">编辑我的资料</button>
|
|
|
|
|
+ <button class="btn ghost" data-go="login">退出登录</button>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section id="edit-mine" class="screen no-tab">
|
|
|
|
|
+ <h1>编辑我的资料</h1>
|
|
|
|
|
+ <p class="sub">可修改个人与机构信息,便于统一对外展示</p>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <input class="input" value="王经理" />
|
|
|
|
|
+ <input class="input" value="13800001111" />
|
|
|
|
|
+ <input class="input" value="XX助贷服务" />
|
|
|
|
|
+ <input class="input" value="上海" />
|
|
|
|
|
+ <input class="input" value="擅长:经营贷、消费贷匹配" />
|
|
|
|
|
+ <button id="saveMineBtn" class="btn primary">保存我的资料</button>
|
|
|
|
|
+ <p id="mineSaveTip" class="small" style="display:none;">我的资料已保存(UI演示)。</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <a class="link" data-go="mine">返回我的</a>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <nav class="bottom-tab" id="tabs">
|
|
|
|
|
+ <button class="tab active" data-tab="home">首页</button>
|
|
|
|
|
+ <button class="tab" data-tab="customers">客户</button>
|
|
|
|
|
+ <button class="tab" data-tab="upload">征信分析</button>
|
|
|
|
|
+ <button class="tab" data-tab="reports">报告</button>
|
|
|
|
|
+ <button class="tab" data-tab="mine">我的</button>
|
|
|
|
|
+ </nav>
|
|
|
|
|
+
|
|
|
|
|
+ <button id="aiFab" class="ai-fab">AI助理</button>
|
|
|
|
|
+ <div id="aiPanel" class="ai-panel">
|
|
|
|
|
+ <div class="ai-head">
|
|
|
|
|
+ <span id="aiTitle" class="ai-title">AI助理</span>
|
|
|
|
|
+ <button id="aiClose" class="ai-close" aria-label="关闭">×</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="ai-body">
|
|
|
|
|
+ <div id="aiIntro" class="ai-msg"></div>
|
|
|
|
|
+ <div id="aiQuestions"></div>
|
|
|
|
|
+ <div id="aiChat" class="ai-chat"></div>
|
|
|
|
|
+ <div class="ai-input-row">
|
|
|
|
|
+ <input id="aiInput" class="ai-input" placeholder="输入你的问题(UI演示,不发起真实请求)" />
|
|
|
|
|
+ <button id="aiSend" class="ai-send">发送</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <p id="aiTip" class="ai-tip"></p>
|
|
|
|
|
+ <div class="quick-row">
|
|
|
|
|
+ <button id="aiGoStart" class="btn ghost quick-btn">回开始提问页</button>
|
|
|
|
|
+ <button id="aiGoHome" class="btn ghost quick-btn">一键回首页</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <script>
|
|
|
|
|
+ const screens = document.querySelectorAll(".screen");
|
|
|
|
|
+ const tabs = document.querySelectorAll(".tab");
|
|
|
|
|
+ const tabsWrap = document.getElementById("tabs");
|
|
|
|
|
+ const aiFab = document.getElementById("aiFab");
|
|
|
|
|
+ const aiPanel = document.getElementById("aiPanel");
|
|
|
|
|
+ const aiClose = document.getElementById("aiClose");
|
|
|
|
|
+ const aiTitle = document.getElementById("aiTitle");
|
|
|
|
|
+ const aiIntro = document.getElementById("aiIntro");
|
|
|
|
|
+ const aiQuestions = document.getElementById("aiQuestions");
|
|
|
|
|
+ const aiChat = document.getElementById("aiChat");
|
|
|
|
|
+ const aiInput = document.getElementById("aiInput");
|
|
|
|
|
+ const aiSend = document.getElementById("aiSend");
|
|
|
|
|
+ const aiTip = document.getElementById("aiTip");
|
|
|
|
|
+ const aiReportScene = document.getElementById("aiReportScene");
|
|
|
|
|
+ const aiReportQuestion = document.getElementById("aiReportQuestion");
|
|
|
|
|
+ const aiReportConclusion = document.getElementById("aiReportConclusion");
|
|
|
|
|
+ const aiReportBasis = document.getElementById("aiReportBasis");
|
|
|
|
|
+ const aiReportAction = document.getElementById("aiReportAction");
|
|
|
|
|
+ const aiReportRisk = document.getElementById("aiReportRisk");
|
|
|
|
|
+ const aiReportBack = document.getElementById("aiReportBack");
|
|
|
|
|
+ const aiReportBackStart = document.getElementById("aiReportBackStart");
|
|
|
|
|
+ const aiReportHome = document.getElementById("aiReportHome");
|
|
|
|
|
+ const aiGoStart = document.getElementById("aiGoStart");
|
|
|
|
|
+ const aiGoHome = document.getElementById("aiGoHome");
|
|
|
|
|
+ const rematchBtn = document.getElementById("rematchBtn");
|
|
|
|
|
+ const rematchPanel = document.getElementById("rematchPanel");
|
|
|
|
|
+ const confirmRematchBtn = document.getElementById("confirmRematchBtn");
|
|
|
|
|
+ const rematchResult = document.getElementById("rematchResult");
|
|
|
|
|
+ const saveCustomerBtn = document.getElementById("saveCustomerBtn");
|
|
|
|
|
+ const customerSaveTip = document.getElementById("customerSaveTip");
|
|
|
|
|
+ const saveMineBtn = document.getElementById("saveMineBtn");
|
|
|
|
|
+ const mineSaveTip = document.getElementById("mineSaveTip");
|
|
|
|
|
+ let currentScreenId = "login";
|
|
|
|
|
+ let beforeAiReportScreenId = "home";
|
|
|
|
|
+ let aiSessionStartScreenId = "home";
|
|
|
|
|
+ let lastAiResponse = null;
|
|
|
|
|
+ let lastAiQuestion = "";
|
|
|
|
|
+ let selectedPref = "额度优先";
|
|
|
|
|
+
|
|
|
|
|
+ const aiContext = {
|
|
|
|
|
+ home: {
|
|
|
|
|
+ title: "AI助理 · 今日工作建议",
|
|
|
|
|
+ intro: "我可以基于待处理客户优先级,给你今天最有效的跟进顺序。",
|
|
|
|
|
+ questions: [
|
|
|
|
|
+ "先跟进哪3位客户成功率最高?",
|
|
|
|
|
+ "今天优先做征信分析还是先做产品匹配?",
|
|
|
|
|
+ "给我一份30分钟高效处理清单。"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ customers: {
|
|
|
|
|
+ title: "AI助理 · 客户策略",
|
|
|
|
|
+ intro: "我可以按客户状态给你建议:先补资料、先分析,还是先沟通预期。",
|
|
|
|
|
+ questions: [
|
|
|
|
|
+ "这个客户现在最该做什么?",
|
|
|
|
|
+ "如何向客户解释‘分析中’不等于‘能通过’?",
|
|
|
|
|
+ "给我一段专业但好懂的沟通话术。"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ upload: {
|
|
|
|
|
+ title: "AI助理 · 征信分析前",
|
|
|
|
|
+ intro: "我可以告诉你分析前要核对的信息,避免后续匹配偏差。",
|
|
|
|
|
+ questions: [
|
|
|
|
|
+ "开始分析前我需要确认哪些客户信息?",
|
|
|
|
|
+ "如何减少因资料缺失导致的误判?",
|
|
|
|
|
+ "给我一段让客户配合补充资料的话术。"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ processing: {
|
|
|
|
|
+ title: "AI助理 · 解析等待中",
|
|
|
|
|
+ intro: "等待期间可提前准备沟通策略,分析完成后直接进入匹配。",
|
|
|
|
|
+ questions: [
|
|
|
|
|
+ "结果出来后第一句话怎么跟客户说?",
|
|
|
|
|
+ "如果评级一般,怎么引导客户接受方案?",
|
|
|
|
|
+ "先讲风险还是先讲可做产品?"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ report: {
|
|
|
|
|
+ title: "AI助理 · 报告解读",
|
|
|
|
|
+ intro: "我可以把征信指标翻译成可执行建议:结论、依据、动作、风险提示。",
|
|
|
|
|
+ questions: [
|
|
|
|
|
+ "这份征信最核心的3个风险是什么?",
|
|
|
|
|
+ "为什么是B+,不是A?",
|
|
|
|
|
+ "未来30天怎么优化通过率?"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ match: {
|
|
|
|
|
+ title: "AI助理 · 产品对比",
|
|
|
|
|
+ intro: "我可以解释Top3推荐差异,并按‘额度/利率/速度’给排序建议。",
|
|
|
|
|
+ questions: [
|
|
|
|
|
+ "这3个产品该怎么给客户讲差异?",
|
|
|
|
|
+ "客户要低利率,应该优先推荐哪个?",
|
|
|
|
|
+ "客户要快放款,顺序怎么排?"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ product: {
|
|
|
|
|
+ title: "AI助理 · 进件建议",
|
|
|
|
|
+ intro: "我可以根据该产品准入条件,给你进件前风险提醒和补件建议。",
|
|
|
|
|
+ questions: [
|
|
|
|
|
+ "这个客户做该产品的主要风险点是什么?",
|
|
|
|
|
+ "进件前还建议补哪些材料?",
|
|
|
|
|
+ "如果被拒,备选产品顺序怎么给?"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ reports: {
|
|
|
|
|
+ title: "AI助理 · 报告汇总",
|
|
|
|
|
+ intro: "我可以帮你快速定位需要优先复盘的客户报告。",
|
|
|
|
|
+ questions: [
|
|
|
|
|
+ "哪几份报告最值得今天先处理?",
|
|
|
|
|
+ "解析中客户要提前准备什么?",
|
|
|
|
|
+ "帮我总结常见风险类型。"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ mine: {
|
|
|
|
|
+ title: "AI助理 · 业务复盘",
|
|
|
|
|
+ intro: "我可以帮你做今日复盘,沉淀可复用的话术与流程。",
|
|
|
|
|
+ questions: [
|
|
|
|
|
+ "今天哪些动作最提升成单概率?",
|
|
|
|
|
+ "帮我总结一版标准跟进SOP。",
|
|
|
|
|
+ "如何提高客户配合上传资料率?"
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ function renderAiContext(id) {
|
|
|
|
|
+ const ctx = aiContext[id] || aiContext.home;
|
|
|
|
|
+ aiTitle.textContent = ctx.title;
|
|
|
|
|
+ aiIntro.textContent = ctx.intro;
|
|
|
|
|
+ aiQuestions.innerHTML = "";
|
|
|
|
|
+ aiChat.innerHTML = "";
|
|
|
|
|
+ ctx.questions.forEach(q => {
|
|
|
|
|
+ const btn = document.createElement("button");
|
|
|
|
|
+ btn.className = "ai-q";
|
|
|
|
|
+ btn.textContent = q;
|
|
|
|
|
+ btn.setAttribute("data-ai-q", q);
|
|
|
|
|
+ aiQuestions.appendChild(btn);
|
|
|
|
|
+ });
|
|
|
|
|
+ aiTip.textContent = "提示:当前为UI演示。输入问题后点击“发送”可查看模拟AI返回结构。";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function addUserMessage(text) {
|
|
|
|
|
+ const msg = document.createElement("div");
|
|
|
|
|
+ msg.className = "ai-bubble user";
|
|
|
|
|
+ msg.textContent = text;
|
|
|
|
|
+ aiChat.appendChild(msg);
|
|
|
|
|
+ aiChat.scrollTop = aiChat.scrollHeight;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function buildMockAnswer(screenId) {
|
|
|
|
|
+ const answerMap = {
|
|
|
|
|
+ report: {
|
|
|
|
|
+ conclusion: "该客户当前可做稳健型产品,建议先控查询再推进主推产品。",
|
|
|
|
|
+ basis: "依据:近3个月查询次数偏多、信用卡使用率72%、当前无逾期。",
|
|
|
|
|
+ action: "动作:1) 7-14天内避免新增硬查询 2) 优先申请看重流水稳定产品 3) 先小额试单。",
|
|
|
|
|
+ risk: "风险提示:最终以银行实时审批为准,不承诺100%通过。"
|
|
|
|
|
+ },
|
|
|
|
|
+ match: {
|
|
|
|
|
+ conclusion: "若客户优先低利率,先推产品A;若优先速度,优先产品C。",
|
|
|
|
|
+ basis: "依据:A匹配度92%且利率区间更优,C放款时效最快。",
|
|
|
|
|
+ action: "动作:先确认客户优先级(利率/额度/速度),再给2选1方案。",
|
|
|
|
|
+ risk: "风险提示:若近期新增查询,产品A通过率可能下降。"
|
|
|
|
|
+ },
|
|
|
|
|
+ product: {
|
|
|
|
|
+ conclusion: "该产品适配中等偏优客户,当前客户可尝试但需先做风险沟通。",
|
|
|
|
|
+ basis: "依据:准入条件与客户现状基本匹配,查询次数接近敏感阈值。",
|
|
|
|
|
+ action: "动作:补充收入证明并先做预审沟通,再正式进件。",
|
|
|
|
|
+ risk: "风险提示:若被拒,建议切换容忍查询更高的备选产品。"
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ return answerMap[screenId] || {
|
|
|
|
|
+ conclusion: "当前阶段建议先明确客户目标,再进入下一步操作。",
|
|
|
|
|
+ basis: "依据:页面信息可支持基础判断,但仍需补充客户偏好与近期变化。",
|
|
|
|
|
+ action: "动作:先确认目标(额度/利率/放款速度),再执行对应流程。",
|
|
|
|
|
+ risk: "风险提示:建议始终向客户说明“最终以银行审批为准”。"
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function getSceneName(screenId) {
|
|
|
|
|
+ const map = {
|
|
|
|
|
+ home: "首页工作建议",
|
|
|
|
|
+ customers: "客户策略",
|
|
|
|
|
+ upload: "征信分析前",
|
|
|
|
|
+ processing: "解析等待中",
|
|
|
|
|
+ report: "征信报告解读",
|
|
|
|
|
+ match: "产品匹配对比",
|
|
|
|
|
+ product: "产品进件建议",
|
|
|
|
|
+ reports: "报告汇总",
|
|
|
|
|
+ mine: "业务复盘"
|
|
|
|
|
+ };
|
|
|
|
|
+ return map[screenId] || "综合建议";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function fillAiReport(screenId, question, data) {
|
|
|
|
|
+ aiReportScene.textContent = `场景:${getSceneName(screenId)}`;
|
|
|
|
|
+ aiReportQuestion.textContent = question || "未记录问题";
|
|
|
|
|
+ aiReportConclusion.textContent = data.conclusion || "-";
|
|
|
|
|
+ aiReportBasis.textContent = data.basis || "-";
|
|
|
|
|
+ aiReportAction.textContent = data.action || "-";
|
|
|
|
|
+ aiReportRisk.textContent = data.risk || "-";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function addAiMessage(screenId, question) {
|
|
|
|
|
+ const data = buildMockAnswer(screenId);
|
|
|
|
|
+ lastAiResponse = data;
|
|
|
|
|
+ lastAiQuestion = question;
|
|
|
|
|
+ const wrap = document.createElement("div");
|
|
|
|
|
+ wrap.className = "ai-bubble ai ai-result";
|
|
|
|
|
+ wrap.innerHTML = `
|
|
|
|
|
+ <h4>结论</h4><p>${data.conclusion}</p>
|
|
|
|
|
+ <h4>依据</h4><p>${data.basis}</p>
|
|
|
|
|
+ <h4>建议动作</h4><p>${data.action}</p>
|
|
|
|
|
+ <h4>风险提示</h4><p>${data.risk}</p>
|
|
|
|
|
+ <button class="btn ghost ai-open-report" data-ai-open-report="1">查看完整回答</button>
|
|
|
|
|
+ `;
|
|
|
|
|
+ aiChat.appendChild(wrap);
|
|
|
|
|
+ aiChat.scrollTop = aiChat.scrollHeight;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function submitAiQuestion() {
|
|
|
|
|
+ const q = aiInput.value.trim();
|
|
|
|
|
+ if (!q) return;
|
|
|
|
|
+ addUserMessage(q);
|
|
|
|
|
+ aiInput.value = "";
|
|
|
|
|
+ const loading = document.createElement("div");
|
|
|
|
|
+ loading.className = "ai-bubble ai ai-loading";
|
|
|
|
|
+ loading.textContent = "AI正在生成专业建议...";
|
|
|
|
|
+ aiChat.appendChild(loading);
|
|
|
|
|
+ aiChat.scrollTop = aiChat.scrollHeight;
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ loading.remove();
|
|
|
|
|
+ addAiMessage(currentScreenId, q);
|
|
|
|
|
+ }, 550);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function updateAiEntry(id) {
|
|
|
|
|
+ currentScreenId = id;
|
|
|
|
|
+ renderAiContext(id);
|
|
|
|
|
+ const hideAi = id === "login" || id === "register";
|
|
|
|
|
+ aiFab.classList.toggle("hide", hideAi);
|
|
|
|
|
+ if (hideAi) aiPanel.classList.remove("show");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function show(id) {
|
|
|
|
|
+ screens.forEach(s => s.classList.remove("active"));
|
|
|
|
|
+ const target = document.getElementById(id);
|
|
|
|
|
+ if (!target) return;
|
|
|
|
|
+ target.classList.add("active");
|
|
|
|
|
+
|
|
|
|
|
+ const noTab = target.classList.contains("no-tab") || id === "login";
|
|
|
|
|
+ tabsWrap.style.display = noTab ? "none" : "flex";
|
|
|
|
|
+
|
|
|
|
|
+ tabs.forEach(t => t.classList.remove("active"));
|
|
|
|
|
+ const hit = document.querySelector(`.tab[data-tab="${id}"]`);
|
|
|
|
|
+ if (hit) hit.classList.add("active");
|
|
|
|
|
+ updateAiEntry(id);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tabs.forEach(btn => {
|
|
|
|
|
+ btn.addEventListener("click", () => show(btn.dataset.tab));
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ document.body.addEventListener("click", e => {
|
|
|
|
|
+ const btn = e.target.closest("[data-go]");
|
|
|
|
|
+ if (!btn) return;
|
|
|
|
|
+ show(btn.dataset.go);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiFab.addEventListener("click", () => {
|
|
|
|
|
+ aiSessionStartScreenId = currentScreenId;
|
|
|
|
|
+ renderAiContext(currentScreenId);
|
|
|
|
|
+ aiPanel.classList.add("show");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiClose.addEventListener("click", () => {
|
|
|
|
|
+ aiPanel.classList.remove("show");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiQuestions.addEventListener("click", e => {
|
|
|
|
|
+ const btn = e.target.closest("[data-ai-q]");
|
|
|
|
|
+ if (!btn) return;
|
|
|
|
|
+ aiInput.value = btn.getAttribute("data-ai-q");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiChat.addEventListener("click", e => {
|
|
|
|
|
+ const btn = e.target.closest("[data-ai-open-report]");
|
|
|
|
|
+ if (!btn || !lastAiResponse) return;
|
|
|
|
|
+ beforeAiReportScreenId = currentScreenId;
|
|
|
|
|
+ fillAiReport(currentScreenId, lastAiQuestion, lastAiResponse);
|
|
|
|
|
+ aiPanel.classList.remove("show");
|
|
|
|
|
+ show("ai-report");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiSend.addEventListener("click", submitAiQuestion);
|
|
|
|
|
+
|
|
|
|
|
+ aiInput.addEventListener("keydown", e => {
|
|
|
|
|
+ if (e.key === "Enter") submitAiQuestion();
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiReportBack.addEventListener("click", () => {
|
|
|
|
|
+ show(beforeAiReportScreenId);
|
|
|
|
|
+ aiPanel.classList.add("show");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiReportBackStart.addEventListener("click", () => {
|
|
|
|
|
+ show(aiSessionStartScreenId || "home");
|
|
|
|
|
+ aiPanel.classList.add("show");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiReportHome.addEventListener("click", () => {
|
|
|
|
|
+ aiPanel.classList.remove("show");
|
|
|
|
|
+ show("home");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiGoStart.addEventListener("click", () => {
|
|
|
|
|
+ aiPanel.classList.remove("show");
|
|
|
|
|
+ show(aiSessionStartScreenId || "home");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ aiGoHome.addEventListener("click", () => {
|
|
|
|
|
+ aiPanel.classList.remove("show");
|
|
|
|
|
+ show("home");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ rematchBtn.addEventListener("click", () => {
|
|
|
|
|
+ const opened = rematchPanel.style.display === "block";
|
|
|
|
|
+ rematchPanel.style.display = opened ? "none" : "block";
|
|
|
|
|
+ if (!opened) rematchResult.style.display = "none";
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ rematchPanel.addEventListener("click", e => {
|
|
|
|
|
+ const btn = e.target.closest("[data-pref]");
|
|
|
|
|
+ if (!btn) return;
|
|
|
|
|
+ selectedPref = btn.getAttribute("data-pref");
|
|
|
|
|
+ rematchPanel.querySelectorAll(".pref-btn").forEach(el => el.classList.remove("active"));
|
|
|
|
|
+ btn.classList.add("active");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ confirmRematchBtn.addEventListener("click", () => {
|
|
|
|
|
+ rematchResult.textContent = `已按“${selectedPref}”重新匹配,结果已更新(UI演示)。`;
|
|
|
|
|
+ rematchResult.style.display = "block";
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ saveCustomerBtn.addEventListener("click", () => {
|
|
|
|
|
+ customerSaveTip.style.display = "block";
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ saveMineBtn.addEventListener("click", () => {
|
|
|
|
|
+ mineSaveTip.style.display = "block";
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ updateAiEntry("login");
|
|
|
|
|
+ </script>
|
|
|
|
|
+</body>
|
|
|
|
|
+</html>
|