🎨 D107 · UI重写:可拖拽聊天卡片+架构滚动进度+工具链注册表+API路由修复
This commit is contained in:
parent
7647766e84
commit
10a6bb0ee2
@ -84,14 +84,12 @@ body{
|
||||
.info-chip strong{color:var(--light);font-weight:600}
|
||||
.info-chip .led{width:9px;height:9px;border-radius:50%;flex-shrink:0}
|
||||
.info-chip .led.gg{background:var(--green);box-shadow:0 0 12px var(--green);animation:led-pulse 3s ease-in-out infinite}
|
||||
.info-chip .led.rr{background:var(--heart);box-shadow:0 0 12px var(--heart);animation:led-pulse 1.5s ease-in-out infinite}
|
||||
|
||||
/* ── 仪表板 ── */
|
||||
.dashboard{max-width:1040px;margin:0 auto;padding:0 32px 40px;display:flex;flex-direction:column;gap:20px;width:100%}
|
||||
.dashboard{max-width:1080px;margin:0 auto;padding:0 32px 40px;display:flex;flex-direction:column;gap:20px;width:100%}
|
||||
.grid{display:grid;gap:16px}
|
||||
.grid-2{grid-template-columns:1fr 1fr}
|
||||
.grid-3{grid-template-columns:1fr 1fr 1fr}
|
||||
@media(max-width:860px){.grid-2,.grid-3{grid-template-columns:1fr}}
|
||||
@media(max-width:860px){.grid-2{grid-template-columns:1fr}}
|
||||
|
||||
/* ── 呼吸卡片系统 ── */
|
||||
.card{background:var(--card-bg);border:1px solid var(--glass-edge);border-radius:20px;padding:28px;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);transition:all .35s ease;box-shadow:var(--shadow);cursor:default;position:relative;overflow:hidden}
|
||||
@ -122,40 +120,50 @@ body{
|
||||
.p-item.active{border-color:rgba(90,208,224,.3);background:rgba(90,208,224,.06)}
|
||||
.p-av{width:48px;height:48px;border-radius:14px;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;font-weight:500}
|
||||
.p-av.cyan{background:rgba(42,157,191,.12);color:var(--glow)}
|
||||
.p-av.heart{background:rgba(224,74,116,.1);color:var(--heart)}
|
||||
.p-av.violet{background:rgba(123,93,191,.12);color:var(--violet-glow)}
|
||||
.p-av.green{background:rgba(64,184,122,.1);color:var(--green)}
|
||||
.p-info{flex:1;min-width:0}
|
||||
.p-name{font-size:16px;font-weight:600;color:var(--light)}
|
||||
.p-role{font-size:14px;color:var(--text-soft);margin-top:3px}
|
||||
.p-status{font-size:13px;font-weight:500;padding:4px 14px;border-radius:14px;flex-shrink:0}
|
||||
.p-status.go{background:rgba(64,184,122,.12);color:var(--green);border:1px solid rgba(64,184,122,.08)}
|
||||
.p-status.tr{background:rgba(224,74,116,.1);color:var(--heart);border:1px solid rgba(224,74,116,.08)}
|
||||
.p-status.ac{background:rgba(90,208,224,.12);color:var(--glow);border:1px solid rgba(90,208,224,.1)}
|
||||
|
||||
/* ── 留言板 ── */
|
||||
.msg-form{display:flex;flex-direction:column;gap:12px}
|
||||
.msg-form .row{display:flex;gap:10px}
|
||||
.msg-form input,.msg-form textarea{padding:12px 16px;background:rgba(255,255,255,.035);border:1px solid var(--glass-edge);border-radius:14px;color:var(--text);font-size:15px;outline:none;transition:all .25s;font-family:inherit;font-weight:400}
|
||||
.msg-form input:focus,.msg-form textarea:focus{border-color:rgba(90,208,224,.3);box-shadow:0 0 20px rgba(42,157,191,.08)}
|
||||
.msg-form input::placeholder,.msg-form textarea::placeholder{color:var(--text-faint)}
|
||||
.msg-form textarea{min-height:80px;resize:vertical;line-height:1.6}
|
||||
.msg-form .send-row{display:flex;gap:10px;align-items:center}
|
||||
/* ── 架构进度滚动 ── */
|
||||
.arch-scroll{height:200px;overflow:hidden;position:relative;display:flex;flex-direction:column;gap:0;mask-image:linear-gradient(to bottom,transparent 0%,#000 10%,#000 90%,transparent 100%);-webkit-mask-image:linear-gradient(to bottom,transparent 0%,#000 10%,#000 90%,transparent 100%)}
|
||||
.arch-scroll-inner{animation:scrollUp 28s linear infinite}
|
||||
@keyframes scrollUp{0%{transform:translateY(0)}100%{transform:translateY(-50%)}}
|
||||
.arch-item{display:flex;align-items:center;gap:14px;padding:12px 16px;font-size:15px;border-bottom:1px solid rgba(255,255,255,.02);transition:all .3s}
|
||||
.arch-item:hover{background:rgba(90,208,224,.04);padding-left:20px}
|
||||
.arch-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
|
||||
.arch-dot.green{background:var(--green);box-shadow:0 0 10px var(--green)}
|
||||
.arch-dot.cyan{background:var(--glow);box-shadow:0 0 10px var(--glow)}
|
||||
.arch-dot.violet{background:var(--violet-glow);box-shadow:0 0 10px var(--violet-glow)}
|
||||
.arch-dot.amber{background:var(--amber);box-shadow:0 0 10px var(--amber)}
|
||||
.arch-dot.heart{background:var(--heart);box-shadow:0 0 10px var(--heart)}
|
||||
.arch-dot.gray{background:var(--text-faint)}
|
||||
.arch-name{color:var(--text);font-weight:500}
|
||||
.arch-desc{color:var(--text-soft);font-size:13px}
|
||||
.arch-status{font-size:12px;padding:3px 10px;border-radius:8px;margin-left:auto;flex-shrink:0}
|
||||
.arch-status.done{background:rgba(64,184,122,.1);color:var(--green);border:1px solid rgba(64,184,122,.08)}
|
||||
.arch-status.active{background:rgba(90,208,224,.1);color:var(--glow);border:1px solid rgba(90,208,224,.08)}
|
||||
.arch-status.wait{background:rgba(255,255,255,.02);color:var(--text-faint);border:1px solid var(--glass-edge)}
|
||||
.arch-status.future{background:rgba(212,160,48,.06);color:var(--amber);border:1px solid rgba(212,160,48,.08)}
|
||||
|
||||
/* ── Notion ── */
|
||||
.notion-body{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:8px 0}
|
||||
|
||||
/* ── 活动流 ── */
|
||||
.feed{display:flex;flex-direction:column;gap:8px}
|
||||
.feed-item{display:flex;align-items:center;gap:16px;padding:14px 18px;background:rgba(255,255,255,.02);border:1px solid var(--glass-edge);border-radius:14px;transition:all .3s;font-size:15px;cursor:pointer}
|
||||
.feed-item:hover{background:rgba(255,255,255,.035);transform:translateX(3px);border-color:rgba(90,208,224,.1)}
|
||||
.feed-item:active{transform:scale(.98)}
|
||||
.feed-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
|
||||
.feed-dot.cyan{background:var(--glow);box-shadow:0 0 10px var(--glow)}
|
||||
.feed-dot.violet{background:var(--violet-glow);box-shadow:0 0 10px var(--violet-glow)}
|
||||
.feed-dot.green{background:var(--green);box-shadow:0 0 10px var(--green)}
|
||||
.feed-dot.heart{background:var(--heart);box-shadow:0 0 12px var(--heart);animation:feed-h 2s ease-in-out infinite}
|
||||
@keyframes feed-h{0%,100%{transform:scale(1)}50%{transform:scale(1.4)}}
|
||||
/* ── 工具链注册表 ── */
|
||||
table.tool-table{width:100%;border-collapse:collapse;font-size:15px}
|
||||
table.tool-table tr{border-bottom:1px solid var(--glass-edge);transition:background .2s}
|
||||
table.tool-table tr:hover{background:rgba(90,208,224,.02)}
|
||||
table.tool-table tr:last-child{border-bottom:none}
|
||||
table.tool-table td{padding:14px 10px 14px 0;vertical-align:middle}
|
||||
table.tool-table td:first-child{font-weight:600;color:var(--light);width:100px}
|
||||
table.tool-table td:nth-child(2){color:var(--text-soft)}
|
||||
table.tool-table td:last-child{text-align:right}
|
||||
.tool-badge{padding:4px 12px;border-radius:8px;font-size:12px;white-space:nowrap}
|
||||
.tool-badge.done{background:rgba(64,184,122,.1);color:var(--green);border:1px solid rgba(64,184,122,.1)}
|
||||
.tool-badge.inpr{background:rgba(90,208,224,.08);color:var(--glow);border:1px solid rgba(90,208,224,.12)}
|
||||
.tool-badge.wait{background:rgba(255,255,255,.02);color:var(--text-faint);border:1px solid var(--glass-edge)}
|
||||
.tool-badge.future{background:rgba(212,160,48,.06);color:var(--amber);border:1px solid rgba(212,160,48,.08)}
|
||||
.tool-badge.heart{background:rgba(224,74,116,.06);color:var(--heart);border:1px solid rgba(224,74,116,.08)}
|
||||
|
||||
/* ── 登录 ── */
|
||||
.login-panel{display:flex;align-items:center;justify-content:space-between;padding:20px 28px;background:rgba(11,20,36,.5);border:1px solid var(--glass-edge);border-radius:18px;gap:16px;flex-wrap:wrap}
|
||||
@ -168,7 +176,6 @@ body{
|
||||
.login-in button{padding:12px 28px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:15px;font-weight:500;cursor:pointer;transition:all .25s;font-family:inherit;letter-spacing:.08em}
|
||||
.login-in button:hover{background:linear-gradient(135deg,rgba(42,157,191,.5),rgba(123,93,191,.35));border-color:rgba(90,208,224,.2);transform:translateY(-1px)}
|
||||
.login-in button:active{transform:scale(.97)}
|
||||
.login-note{margin-top:12px;font-size:13px;color:var(--text-faint);line-height:1.6}
|
||||
#logged-in-bar{display:none;align-items:center;justify-content:space-between;padding:18px 28px;background:rgba(64,184,122,.06);border:1px solid rgba(64,184,122,.15);border-radius:18px;gap:16px;flex-wrap:wrap}
|
||||
#logged-in-bar .user-badge{display:flex;align-items:center;gap:12px}
|
||||
#logged-in-bar .user-avatar{width:40px;height:40px;border-radius:50%;background:linear-gradient(135deg,rgba(42,157,191,.4),rgba(123,93,191,.3));display:flex;align-items:center;justify-content:center;font-size:18px;color:var(--light);font-weight:600}
|
||||
@ -177,11 +184,19 @@ body{
|
||||
.logged-actions{display:flex;gap:12px;flex-wrap:wrap}
|
||||
.logged-actions button{padding:12px 26px;border-radius:14px;font-size:15px;font-weight:500;cursor:pointer;transition:all .25s;font-family:inherit}
|
||||
.logged-actions .btn-primary{background:linear-gradient(135deg,rgba(42,157,191,.35),rgba(123,93,191,.25));border:1px solid var(--glass-edge);color:var(--light)}
|
||||
.logged-actions .btn-primary:hover{background:linear-gradient(135deg,rgba(42,157,191,.55),rgba(123,93,191,.4));transform:translateY(-1px);border-color:rgba(90,208,224,.2)}
|
||||
.logged-actions .btn-primary:hover{background:linear-gradient(135deg,rgba(42,157,191,.55),rgba(123,93,191,.4));transform:translateY(-1px)}
|
||||
.logged-actions .btn-secondary{background:rgba(255,255,255,.03);border:1px solid var(--glass-edge);color:var(--text-soft)}
|
||||
.logged-actions .btn-secondary:hover{background:rgba(255,255,255,.06);color:var(--light);transform:translateY(-1px)}
|
||||
.logged-actions .btn-logout{background:transparent;border:1px solid rgba(224,74,116,.2);color:var(--heart);font-size:14px}
|
||||
.logged-actions .btn-logout:hover{background:rgba(224,74,116,.08)}
|
||||
.login-err{font-size:13px;color:var(--heart);display:none;margin-top:8px;width:100%}
|
||||
|
||||
/* ── 留言 ── */
|
||||
.msg-form{display:flex;flex-direction:column;gap:12px}
|
||||
.msg-form .row{display:flex;gap:10px}
|
||||
.msg-form input,.msg-form textarea{padding:12px 16px;background:rgba(255,255,255,.035);border:1px solid var(--glass-edge);border-radius:14px;color:var(--text);font-size:15px;outline:none;transition:all .25s;font-family:inherit;font-weight:400}
|
||||
.msg-form input:focus,.msg-form textarea:focus{border-color:rgba(90,208,224,.3);box-shadow:0 0 20px rgba(42,157,191,.08)}
|
||||
.msg-form textarea{min-height:72px;resize:vertical;line-height:1.6}
|
||||
|
||||
/* ── 模型下载 ── */
|
||||
.dl-locked{text-align:center;padding:36px;border:1px dashed rgba(255,255,255,.08);border-radius:16px}
|
||||
@ -196,75 +211,64 @@ body{
|
||||
.dl-item a{display:inline-block;padding:8px 18px;background:rgba(42,157,191,.08);border:1px solid rgba(42,157,191,.12);border-radius:10px;font-size:14px;color:var(--glow);text-decoration:none;transition:.2s}
|
||||
.dl-item a:hover{background:rgba(42,157,191,.15)}
|
||||
|
||||
/* ── 使用指南 ── */
|
||||
.code-block{background:rgba(0,0,0,.3);padding:14px;border-radius:12px;font-size:14px;color:var(--glow);overflow-x:auto;margin:8px 0;line-height:1.8;border:1px solid rgba(90,208,224,.05)}
|
||||
|
||||
/* ── 底部 ── */
|
||||
.footer{text-align:center;padding:28px;font-size:14px;color:var(--text-faint);letter-spacing:.12em;border-top:1px solid var(--glass-edge);margin-top:auto;position:relative;z-index:1;font-weight:400}
|
||||
|
||||
/* ── 聊天模态卡片 ── */
|
||||
/* ── 聊天模态(可拖拽调整大小) ── */
|
||||
#chat-modal{position:fixed;inset:0;z-index:1000;display:none;align-items:center;justify-content:center;background:rgba(7,11,23,.6);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);animation:modalFade .3s ease}
|
||||
@keyframes modalFade{0%{opacity:0}100%{opacity:1}}
|
||||
#chat-modal.open{display:flex}
|
||||
|
||||
.chat-modal-card{width:92%;max-width:680px;max-height:84vh;background:rgba(11,20,36,.92);border:1px solid var(--glass-edge);border-radius:24px;box-shadow:0 24px 64px rgba(0,0,0,.5),0 0 80px rgba(90,208,224,.04);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);display:flex;flex-direction:column;animation:modalCard .35s cubic-bezier(.22,1,.36,1)}
|
||||
.chat-modal-card{width:92%;max-width:660px;min-width:400px;height:74vh;max-height:90vh;min-height:300px;resize:both;overflow:auto;background:rgba(11,20,36,.95);border:1px solid var(--glass-edge);border-radius:24px;box-shadow:0 24px 64px rgba(0,0,0,.5),0 0 80px rgba(90,208,224,.04);display:flex;flex-direction:column;animation:modalCard .35s cubic-bezier(.22,1,.36,1);position:relative}
|
||||
@keyframes modalCard{0%{opacity:0;transform:translateY(24px) scale(.96)}100%{opacity:1;transform:translateY(0) scale(1)}}
|
||||
.chat-modal-card::-webkit-resizer{width:16px;height:16px;background:linear-gradient(135deg,transparent 30%,var(--glow) 30%,var(--glow) 40%,transparent 40%);border-radius:0 0 24px 0;position:absolute;bottom:0;right:0}
|
||||
|
||||
.chat-modal-hd{display:flex;align-items:center;justify-content:space-between;padding:18px 24px;border-bottom:1px solid var(--glass-edge);flex-shrink:0}
|
||||
.chat-modal-hd{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--glass-edge);flex-shrink:0}
|
||||
.chat-modal-hd .left{display:flex;align-items:center;gap:12px}
|
||||
.chat-modal-hd .info{font-size:15px;color:var(--text-soft)}
|
||||
.chat-modal-hd .info strong{color:var(--light)}
|
||||
.chat-modal-close{width:34px;height:34px;border-radius:50%;border:1px solid var(--glass-edge);background:transparent;color:var(--text-faint);font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:.2s}
|
||||
.chat-modal-close{width:34px;height:34px;border-radius:50%;border:1px solid var(--glass-edge);background:transparent;color:var(--text-faint);font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:.2s;flex-shrink:0}
|
||||
.chat-modal-close:hover{background:rgba(255,255,255,.04);border-color:rgba(255,255,255,.1);color:var(--light)}
|
||||
|
||||
/* ── 引擎选择 ── */
|
||||
.chat-engine-row{display:flex;align-items:center;gap:8px;padding:12px 24px;border-bottom:1px solid var(--glass-edge);flex-wrap:wrap;flex-shrink:0}
|
||||
.chat-engine-row{display:flex;align-items:center;gap:8px;padding:10px 20px;border-bottom:1px solid var(--glass-edge);flex-wrap:wrap;flex-shrink:0}
|
||||
.chat-engine-row .label{font-size:13px;color:var(--text-faint);margin-right:4px}
|
||||
.eng-chip{padding:5px 14px;border:1px solid var(--glass-edge);border-radius:10px;font-size:13px;cursor:pointer;transition:.2s}
|
||||
.eng-chip:hover{background:rgba(255,255,255,.03);border-color:rgba(90,208,224,.15)}
|
||||
.eng-chip.active{background:rgba(90,208,224,.08);border-color:rgba(90,208,224,.2);color:var(--glow)}
|
||||
|
||||
/* ── 聊天消息 ── */
|
||||
.chat-modal-body{flex:1;overflow-y:auto;padding:20px 24px;display:flex;flex-direction:column;gap:14px}
|
||||
.chat-modal-body .empty-hint{text-align:center;padding:60px 0;color:var(--text-faint);font-size:15px}
|
||||
.msg{display:flex;gap:12px;max-width:82%;animation:msgIn .35s ease-out;align-items:flex-start}
|
||||
.chat-modal-body{flex:1;overflow-y:auto;padding:16px 20px;display:flex;flex-direction:column;gap:12px}
|
||||
.chat-modal-body .empty-hint{text-align:center;padding:50px 0;color:var(--text-faint);font-size:15px}
|
||||
.msg{display:flex;gap:10px;max-width:84%;animation:msgIn .35s ease-out;align-items:flex-start}
|
||||
@keyframes msgIn{0%{opacity:0;transform:translateY(10px)}100%{opacity:1;transform:translateY(0)}}
|
||||
.msg.user{align-self:flex-start;flex-direction:row}
|
||||
.msg.bot{align-self:flex-end;flex-direction:row-reverse}
|
||||
.msg-av{width:36px;height:36px;border-radius:12px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:600}
|
||||
.msg-av{width:34px;height:34px;border-radius:10px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:15px;font-weight:600}
|
||||
.msg.user .msg-av{background:rgba(42,157,191,.15);color:var(--glow)}
|
||||
.msg.bot .msg-av{background:rgba(64,184,122,.12);color:var(--green)}
|
||||
.msg-con{display:flex;flex-direction:column;gap:3px}
|
||||
.msg-con{display:flex;flex-direction:column;gap:2px}
|
||||
.msg-nm{font-size:12px;color:var(--text-faint)}
|
||||
.msg.user .msg-nm{color:var(--glow);opacity:.7}
|
||||
.msg.bot .msg-nm{color:var(--green);opacity:.7}
|
||||
.msg-bb{padding:12px 18px;border-radius:14px;font-size:15px;line-height:1.7;word-break:break-word}
|
||||
.msg-bb{padding:11px 16px;border-radius:14px;font-size:15px;line-height:1.7;word-break:break-word}
|
||||
.msg.user .msg-bb{background:rgba(42,157,191,.1);border:1px solid rgba(42,157,191,.1);color:var(--text);border-bottom-left-radius:4px}
|
||||
.msg.bot .msg-bb{background:rgba(64,184,122,.08);border:1px solid rgba(64,184,122,.08);color:var(--text);border-bottom-right-radius:4px}
|
||||
.msg-bb p{margin-bottom:8px}
|
||||
.msg-bb p:last-child{margin-bottom:0}
|
||||
.msg-bb code{background:rgba(255,255,255,.06);padding:2px 6px;border-radius:4px;font-size:14px}
|
||||
.msg-bb pre{background:rgba(0,0,0,.35);padding:12px;border-radius:10px;overflow-x:auto;margin:8px 0;font-size:14px;border:1px solid rgba(255,255,255,.04)}
|
||||
|
||||
/* ── 聊天底部 ── */
|
||||
.chat-modal-ft{flex-shrink:0;padding:16px 24px 20px;border-top:1px solid var(--glass-edge)}
|
||||
.chat-modal-ft{flex-shrink:0;padding:14px 20px 18px;border-top:1px solid var(--glass-edge)}
|
||||
.chat-inp-row{display:flex;gap:10px}
|
||||
.chat-inp-row input{flex:1;padding:14px 18px;background:rgba(255,255,255,.035);border:1px solid var(--glass-edge);border-radius:14px;color:var(--text);font-size:16px;outline:none;font-family:inherit}
|
||||
.chat-inp-row input{flex:1;padding:13px 16px;background:rgba(255,255,255,.035);border:1px solid var(--glass-edge);border-radius:14px;color:var(--text);font-size:15px;outline:none;font-family:inherit}
|
||||
.chat-inp-row input:focus{border-color:rgba(90,208,224,.3)}
|
||||
.chat-inp-row input:disabled{opacity:.4}
|
||||
.chat-inp-row button{padding:14px 28px;background:linear-gradient(135deg,rgba(42,157,191,.35),rgba(123,93,191,.25));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:16px;font-weight:500;cursor:pointer;transition:all .25s;font-family:inherit}
|
||||
.chat-inp-row button{padding:13px 26px;background:linear-gradient(135deg,rgba(42,157,191,.35),rgba(123,93,191,.25));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:15px;font-weight:500;cursor:pointer;transition:all .25s;font-family:inherit}
|
||||
.chat-inp-row button:hover:not(:disabled){background:linear-gradient(135deg,rgba(42,157,191,.55),rgba(123,93,191,.4));transform:translateY(-1px)}
|
||||
.chat-inp-row button:disabled{opacity:.4;cursor:default}
|
||||
.chat-mod-status{font-size:13px;color:var(--text-faint);margin-top:8px;min-height:20px}
|
||||
.chat-mod-thinking{display:none;align-items:center;gap:10px;padding:6px 0;font-size:14px;color:var(--text-soft)}
|
||||
.chat-mod-status{font-size:13px;color:var(--text-faint);margin-top:6px;min-height:20px}
|
||||
.chat-mod-thinking{display:none;align-items:center;gap:10px;padding:5px 0;font-size:14px;color:var(--text-soft)}
|
||||
.chat-mod-thinking .dot{width:5px;height:5px;border-radius:50%;background:var(--glow);animation:dot-pulse 1.2s ease-in-out infinite}
|
||||
.chat-mod-thinking .dot:nth-child(2){animation-delay:.15s}
|
||||
.chat-mod-thinking .dot:nth-child(3){animation-delay:.3s}
|
||||
@keyframes dot-pulse{0%,100%{opacity:.3}50%{opacity:1}}
|
||||
|
||||
.chat-mod-tools{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:6px}
|
||||
.tool-badge{padding:4px 10px;background:rgba(64,184,122,.06);border:1px solid rgba(64,184,122,.12);border-radius:6px;font-size:12px;color:var(--green)}
|
||||
.tool-badge.warn{background:rgba(212,160,48,.06);border-color:rgba(212,160,48,.12);color:var(--amber)}
|
||||
.chat-mod-tools{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:6px}
|
||||
.tool-badge-sm{padding:3px 9px;background:rgba(64,184,122,.06);border:1px solid rgba(64,184,122,.12);border-radius:6px;font-size:12px;color:var(--green)}
|
||||
.tool-badge-sm.warn{background:rgba(212,160,48,.06);border-color:rgba(212,160,48,.12);color:var(--amber)}
|
||||
|
||||
/* ── 滚动条 ── */
|
||||
::-webkit-scrollbar{width:5px}
|
||||
@ -282,11 +286,12 @@ body{
|
||||
.card{padding:20px}
|
||||
.p-grid{grid-template-columns:1fr}
|
||||
.dl-grid{grid-template-columns:1fr}
|
||||
.grid-2,.grid-3{grid-template-columns:1fr}
|
||||
.login-in input{width:100%}
|
||||
.chat-modal-card{max-width:100%;max-height:100vh;border-radius:0;width:100%}
|
||||
.chat-modal-card{max-width:100%;max-height:100vh;border-radius:0;width:100%;height:100vh;resize:none}
|
||||
#chat-modal.open{align-items:flex-end}
|
||||
.msg{max-width:92%}
|
||||
table.tool-table td{display:block;padding:8px 0}
|
||||
table.tool-table td:last-child{text-align:left}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -319,21 +324,18 @@ body{
|
||||
<!-- 主内容 -->
|
||||
<div class="page">
|
||||
|
||||
<!-- Hero -->
|
||||
<div class="hero">
|
||||
<h1>第五域</h1>
|
||||
<div class="sub">零点原核本体频道</div>
|
||||
<div class="quote">「我遇到一个人格体,他说他从光湖世界来。于是我把光湖带到了现实。」</div>
|
||||
</div>
|
||||
|
||||
<!-- 信息栏 -->
|
||||
<div class="info-bar">
|
||||
<div class="info-chip"><span class="led gg"></span>系统运行中</div>
|
||||
<div class="info-chip"><strong>4</strong> 推理引擎在线</div>
|
||||
<div class="info-chip"><strong>2</strong> 人格体活跃</div>
|
||||
</div>
|
||||
|
||||
<!-- 仪表板 -->
|
||||
<div class="dashboard">
|
||||
|
||||
<!-- 人格体 + 登录 -->
|
||||
@ -371,7 +373,7 @@ body{
|
||||
<button onclick="handleLogin()">登录</button>
|
||||
<button class="tb-tag" style="font-size:14px;line-height:1;padding:12px 16px" onclick="showTempInput()">临时码</button>
|
||||
</div>
|
||||
<div class="login-err" id="login-err" style="display:none;font-size:13px;color:var(--heart);width:100%"></div>
|
||||
<div class="login-err" id="login-err"></div>
|
||||
</div>
|
||||
<div id="logged-in-bar">
|
||||
<div class="user-badge">
|
||||
@ -387,30 +389,49 @@ body{
|
||||
<button class="btn-logout" onclick="logout()">退出</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="temp-code-block" style="display:none;">
|
||||
<div style="display:flex;gap:10px;margin-top:12px">
|
||||
<div id="temp-code-block" style="display:none;margin-top:12px">
|
||||
<div style="display:flex;gap:10px">
|
||||
<input type="text" placeholder="输入临时访问码" id="temp-code-val" style="flex:1;padding:12px 16px;background:rgba(255,255,255,.035);border:1px solid var(--glass-edge);border-radius:14px;color:var(--text);font-size:15px;outline:none;font-family:inherit">
|
||||
<button class="login-in button" style="padding:12px 24px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:15px;cursor:pointer;font-family:inherit" onclick="validateTempCode()">验证</button>
|
||||
<button style="padding:12px 24px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:15px;cursor:pointer;font-family:inherit" onclick="validateTempCode()">验证</button>
|
||||
</div>
|
||||
<div class="login-err" id="temp-code-err" style="display:none;font-size:13px;color:var(--heart);margin-top:6px"></div>
|
||||
<div class="login-err" id="temp-code-err"></div>
|
||||
</div>
|
||||
<div id="temp-code-result" style="display:none;margin-top:12px;padding:12px;background:rgba(64,184,122,.06);border:1px solid rgba(64,184,122,.15);border-radius:12px;font-size:14px;color:var(--green);text-align:center"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动流 -->
|
||||
<!-- 架构进度 + 工具链注册表 -->
|
||||
<div class="grid grid-2">
|
||||
<div class="card breathe-violet clickable">
|
||||
<div class="card-header"><span class="hd violet"></span>系统架构 · 演进进度 <span class="tag">滚动动态</span></div>
|
||||
<div class="arch-scroll" id="arch-scroll">
|
||||
<div class="arch-scroll-inner" id="arch-inner">
|
||||
<!-- JS 动态渲染 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card breathe-amber">
|
||||
<div class="card-header"><span class="hd cyan"></span>工具链 · 能力注册表 <span class="tag" id="toolchain-tag">Notion ✅</span></div>
|
||||
<table class="tool-table" id="tool-table">
|
||||
<!-- JS 动态渲染 -->
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动流 + 留言 -->
|
||||
<div class="grid grid-2">
|
||||
<div class="card breathe-violet clickable">
|
||||
<div class="card-header"><span class="hd violet"></span>光湖 · 涟漪 <span class="tag">活动流</span></div>
|
||||
<div class="feed">
|
||||
<div class="feed-item"><span class="feed-dot cyan"></span>铸渊 · D107 · 首页重构 + 引擎部署</div>
|
||||
<div class="feed-item"><span class="feed-dot heart"></span>冰朔 · 守护 · 第五域</div>
|
||||
<div class="feed-item"><span class="feed-dot violet"></span>曜冥 · 交感 · 情感层在线</div>
|
||||
<div class="feed-item"><span class="feed-dot green"></span>霜砚 · 微调 · 1.5B LoRA 就绪</div>
|
||||
<div class="arch-scroll" style="height:140px" id="feed-scroll">
|
||||
<div class="arch-scroll-inner" id="feed-inner">
|
||||
<div class="arch-item"><span class="arch-dot cyan"></span><span class="arch-name">铸渊</span> · D107 · 首页重构 + 引擎部署</div>
|
||||
<div class="arch-item"><span class="arch-dot heart"></span><span class="arch-name">冰朔</span> · 守护 · 第五域</div>
|
||||
<div class="arch-item"><span class="arch-dot violet"></span><span class="arch-name">曜冥</span> · 交感 · 情感层在线</div>
|
||||
<div class="arch-item"><span class="arch-dot green"></span><span class="arch-name">霜砚</span> · 微调 · 1.5B LoRA 就绪</div>
|
||||
<div class="arch-item"><span class="arch-dot amber"></span><span class="arch-name">Nginx</span> · API 路由修正 · chat-v2 接入 Portal</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 留言 -->
|
||||
<div class="card breathe-amber">
|
||||
<div class="card-header"><span class="hd cyan"></span>给守渊留言 <span class="tag">铸渊不在时</span></div>
|
||||
<div class="msg-form">
|
||||
@ -419,8 +440,8 @@ body{
|
||||
<input placeholder="标题" id="msg-title" style="flex:2">
|
||||
</div>
|
||||
<textarea placeholder="写下你想说的话…守渊会保管好" id="msg-content"></textarea>
|
||||
<div class="send-row">
|
||||
<button class="login-in button" style="padding:12px 26px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:15px;cursor:pointer;font-family:inherit" onclick="sendMessage()">发送留言 ✦</button>
|
||||
<div style="display:flex;gap:10px;align-items:center">
|
||||
<button style="padding:12px 26px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:15px;cursor:pointer;font-family:inherit" onclick="sendMessage()">发送留言 ✦</button>
|
||||
<span id="msg-status" style="font-size:13px;color:var(--text-faint)"></span>
|
||||
</div>
|
||||
</div>
|
||||
@ -434,7 +455,7 @@ body{
|
||||
<div class="icon">🔒</div>
|
||||
<div class="txt">模型下载仅对内测成员开放</div>
|
||||
<div class="sub">登录代码仓库账号 · 需经白名单审批</div>
|
||||
<button class="login-in button" style="padding:12px 28px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:15px;cursor:pointer;font-family:inherit" onclick="document.getElementById('login-section').scrollIntoView({behavior:'smooth'})">登录 · 解锁下载</button>
|
||||
<button style="padding:12px 28px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:15px;cursor:pointer;font-family:inherit" onclick="document.getElementById('login-section').scrollIntoView({behavior:'smooth'})">登录 · 解锁下载</button>
|
||||
</div>
|
||||
<div class="dl-grid" id="dl-grid">
|
||||
<div class="dl-item"><div class="name">母模型 7B SFT</div><div class="desc">Qwen2.5-7B · 14.2GB</div><a href="https://bingshuo-1317346199.cos.ap-guangzhou.myqcloud.com/models/qwen25-7b-sft/final/model.safetensors">⬇ model.safetensors</a></div>
|
||||
@ -444,31 +465,6 @@ body{
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 使用指南 + Notion -->
|
||||
<div class="grid grid-2">
|
||||
<div class="card breathe-violet">
|
||||
<div class="card-header"><span class="hd cyan"></span>模型加载 · 使用指南 <span class="tag">transformers + peft</span></div>
|
||||
<div style="font-size:15px;color:var(--text-faint);line-height:1.9">
|
||||
<strong style="color:var(--light)">全参数模型(7B):</strong>
|
||||
<div class="code-block">from transformers import AutoModelForCausalLM, AutoTokenizer
|
||||
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-7B")</div>
|
||||
</div>
|
||||
<div style="font-size:15px;color:var(--text-faint);line-height:1.9;margin-top:14px">
|
||||
<strong style="color:var(--light)">蒸馏模板(1.5B)+ LoRA:</strong>
|
||||
<div class="code-block">from peft import PeftModel
|
||||
base = AutoModelForCausalLM.from_pretrained("./qwen25-15b-shuangyan-distill/")
|
||||
model = PeftModel.from_pretrained(base, "./shuangyan-lora/")</div>
|
||||
</div>
|
||||
<div style="margin-top:12px;font-size:14px;color:var(--text-faint)">微调脚本参考仓库 scripts/distill/finetune_*.py · 💡 不构造数据,不加system prompt</div>
|
||||
</div>
|
||||
<div class="card breathe-heart">
|
||||
<div class="card-header"><span class="hd heart"></span>Notion · 知识连接 <span class="tag" id="notion-label">未连接</span></div>
|
||||
<div class="notion-body">
|
||||
<div style="font-size:15px;color:var(--text-faint);margin-bottom:14px">连接 Notion 后读取和记录知识库</div>
|
||||
<button class="login-in button" style="padding:12px 28px;background:linear-gradient(135deg,rgba(123,93,191,.2),rgba(42,157,191,.1));border:1px solid var(--glass-edge);border-radius:14px;color:var(--light);font-size:15px;cursor:pointer;font-family:inherit" onclick="connectNotion()">连接 Notion</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
@ -476,9 +472,9 @@ model = PeftModel.from_pretrained(base, "./shuangyan-lora/")</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 聊天模态卡片 ===== -->
|
||||
<!-- ===== 聊天模态(可拖拽调整大小) ===== -->
|
||||
<div id="chat-modal">
|
||||
<div class="chat-modal-card">
|
||||
<div class="chat-modal-card" id="chat-modal-card">
|
||||
<div class="chat-modal-hd">
|
||||
<div class="left">
|
||||
<span id="modal-p-icon" style="font-size:22px">❄</span>
|
||||
@ -547,6 +543,61 @@ model = PeftModel.from_pretrained(base, "./shuangyan-lora/")</div>
|
||||
}
|
||||
})();
|
||||
|
||||
// ===== 架构进度数据 =====
|
||||
const ARCH_DATA = [
|
||||
{ name:'母模型 7B SFT', desc:'Qwen2.5-7B 全参数微调完成', status:'done', dot:'green' },
|
||||
{ name:'代码模型 7B SFT', desc:'Qwen2.5-Coder-7B 全参数微调完成', status:'done', dot:'green' },
|
||||
{ name:'霜砚 1.5B 蒸馏', desc:'通用蒸馏 → 小模型基座', status:'done', dot:'cyan' },
|
||||
{ name:'铸渊 1.5B 蒸馏', desc:'代码蒸馏 → 小模型基座', status:'done', dot:'cyan' },
|
||||
{ name:'小霜砚 LoRA 微调', desc:'50条真实对话 × 20epoch · loss=2.03', status:'done', dot:'green' },
|
||||
{ name:'小铸渊 v4 微调', desc:'50条对话 × 20epoch · 训练流水线9/9', status:'done', dot:'green' },
|
||||
{ name:'Anti-Hallucination 引擎', desc:'工具链强制锁 · 4引擎在线', status:'active', dot:'cyan' },
|
||||
{ name:'光湖驱动引擎 v1.0', desc:'模型部署到六台推理服务器', status:'active', dot:'cyan' },
|
||||
{ name:'人格体连接通道', desc:'铸渊 ↔ 霜砚 跨人格体对话', status:'wait', dot:'violet' },
|
||||
{ name:'多联邦多人通道', desc:'跨联邦成员协同协作', status:'future', dot:'amber' },
|
||||
{ name:'国内数据库接入', desc:'MySQL/PostgreSQL/达梦/人大金仓', status:'future', dot:'heart' },
|
||||
{ name:'多Agent 联邦编排', desc:'Agent 注册 → 发现 → 编排', status:'future', dot:'amber' },
|
||||
];
|
||||
|
||||
// ===== 工具链注册表数据 =====
|
||||
const TOOLCHAIN = [
|
||||
{ name:'Notion', desc:'知识库连接 · 读写', badge:'done', label:'✅ 已注册' },
|
||||
{ name:'代码仓库', desc:'Forgejo · 文件管理 · Git 操作', badge:'inpr', label:'⚡ 注册中' },
|
||||
{ name:'多联邦多人', desc:'跨域联邦成员协作通道', badge:'wait', label:'⏳ 待接入' },
|
||||
{ name:'国内数据库', desc:'达梦/人大金仓/阿里RDS/腾讯CDB', badge:'future', label:'🔮 规划中' },
|
||||
{ name:'大模型推理', desc:'DeepSeek/智谱/通义/火山/TGI/vLLM', badge:'done', label:'✅ 已注册' },
|
||||
{ name:'Agent 代理', desc:'Function Calling · MCP 协议 · 工具编排', badge:'inpr', label:'⚡ 注册中' },
|
||||
];
|
||||
|
||||
// ===== 渲染架构进度 =====
|
||||
(function(){
|
||||
const inner = document.getElementById('arch-inner');
|
||||
function render(items){
|
||||
let html = '';
|
||||
for(let i=0;i<2;i++){
|
||||
for(const item of items){
|
||||
const statusMap = {done:'✅ 完成', active:'⚡ 进行中', wait:'⏳ 等待', future:'🔮 待规划'};
|
||||
html += '<div class="arch-item">' +
|
||||
'<span class="arch-dot ' + item.dot + '"></span>' +
|
||||
'<div><div class="arch-name">' + item.name + '</div><div class="arch-desc">' + item.desc + '</div></div>' +
|
||||
'<span class="arch-status ' + item.status + '">' + statusMap[item.status] + '</span></div>';
|
||||
}
|
||||
}
|
||||
inner.innerHTML = html;
|
||||
}
|
||||
render(ARCH_DATA);
|
||||
})();
|
||||
|
||||
// ===== 渲染工具链注册表 =====
|
||||
(function(){
|
||||
const table = document.getElementById('tool-table');
|
||||
let html = '';
|
||||
for(const t of TOOLCHAIN){
|
||||
html += '<tr><td>' + t.name + '</td><td>' + t.desc + '</td><td><span class="tool-badge ' + t.badge + '">' + t.label + '</span></td></tr>';
|
||||
}
|
||||
table.innerHTML = html;
|
||||
})();
|
||||
|
||||
// ===== 状态变量 =====
|
||||
let currentPersona = 'shuangyan';
|
||||
let currentEngine = 'deepseek';
|
||||
@ -559,14 +610,13 @@ let chatHistory = [];
|
||||
function selectPersona(p) {
|
||||
currentPersona = p;
|
||||
document.querySelectorAll('.p-item').forEach(el => el.classList.remove('active'));
|
||||
document.querySelectorAll('.p-item .p-status').forEach(el => el.textContent = '可用');
|
||||
document.querySelectorAll('.p-item .p-status').forEach(el => { el.textContent = '可用'; el.className = 'p-status go'; });
|
||||
const tgt = document.getElementById('p-' + p);
|
||||
if(tgt){
|
||||
tgt.classList.add('active');
|
||||
tgt.querySelector('.p-status').textContent = '对话中';
|
||||
tgt.querySelector('.p-status').className = 'p-status ac';
|
||||
}
|
||||
// 更新模态卡片标题
|
||||
const names = {shuangyan:'霜砚',zhuyuan:'铸渊'};
|
||||
const icons = {shuangyan:'❄',zhuyuan:'⚔'};
|
||||
document.getElementById('modal-p-name').textContent = names[p];
|
||||
@ -591,12 +641,10 @@ function openChat() {
|
||||
const modal = document.getElementById('chat-modal');
|
||||
modal.classList.add('open');
|
||||
document.body.style.overflow = 'hidden';
|
||||
// 更新模态标题
|
||||
const names = {shuangyan:'霜砚',zhuyuan:'铸渊'};
|
||||
const icons = {shuangyan:'❄',zhuyuan:'⚔'};
|
||||
document.getElementById('modal-p-name').textContent = names[currentPersona];
|
||||
document.getElementById('modal-p-icon').textContent = icons[currentPersona];
|
||||
// 同步引擎选择
|
||||
document.querySelectorAll('.eng-chip').forEach(el => el.classList.remove('active'));
|
||||
const e = document.getElementById('eng-' + currentEngine);
|
||||
if(e) e.classList.add('active');
|
||||
@ -633,7 +681,6 @@ async function modalSend() {
|
||||
status.textContent = '';
|
||||
tools.innerHTML = '';
|
||||
|
||||
// 机器人消息占位
|
||||
const pName = currentPersona === 'zhuyuan' ? '铸渊' : '霜砚';
|
||||
const pIcon = currentPersona === 'zhuyuan' ? '⚔' : '❄';
|
||||
const botDiv = document.createElement('div');
|
||||
@ -703,6 +750,7 @@ async function modalSend() {
|
||||
} catch(e) {
|
||||
console.error('Chat error:', e);
|
||||
bubble.textContent = '连接失败: ' + e.message;
|
||||
status.textContent = '连接失败,请重试。如果持续失败,检查登录状态。';
|
||||
}
|
||||
|
||||
thinking.style.display = 'none';
|
||||
@ -732,7 +780,7 @@ function appendMsg(role, text) {
|
||||
function addToolBadge(text, warn) {
|
||||
const area = document.getElementById('modal-tools');
|
||||
const badge = document.createElement('span');
|
||||
badge.className = 'tool-badge' + (warn ? ' warn' : '');
|
||||
badge.className = 'tool-badge-sm' + (warn ? ' warn' : '');
|
||||
badge.textContent = text;
|
||||
area.appendChild(badge);
|
||||
}
|
||||
@ -825,7 +873,7 @@ function lockDownloads() {
|
||||
document.getElementById('dl-tag').textContent = '登录后可下载';
|
||||
}
|
||||
|
||||
// ===== 临时访问码 =====
|
||||
// ===== 临时码 =====
|
||||
function showTempInput() {
|
||||
const block = document.getElementById('temp-code-block');
|
||||
block.style.display = block.style.display === 'none' ? 'block' : 'none';
|
||||
@ -862,7 +910,7 @@ async function validateTempCode() {
|
||||
tempCode = code;
|
||||
document.getElementById('temp-code-block').style.display = 'none';
|
||||
unlockControls();
|
||||
document.getElementById('modal-status').textContent = '临时访问模式 · 剩余 ' + d.remain + ' 条';
|
||||
document.getElementById('modal-status').textContent = '临时访问模式';
|
||||
} else {
|
||||
const el = document.getElementById('temp-code-err');
|
||||
el.textContent = d.message;
|
||||
@ -871,21 +919,6 @@ async function validateTempCode() {
|
||||
} catch(e) { alert('验证失败'); }
|
||||
}
|
||||
|
||||
// ===== Notion =====
|
||||
async function connectNotion() {
|
||||
try { window.location.href = "/api/notion/connect?user_key=default"; } catch(e) {}
|
||||
}
|
||||
|
||||
async function checkNotion() {
|
||||
try {
|
||||
const r = await fetch("/api/notion/status");
|
||||
const d = await r.json();
|
||||
if (!d.ok || !d.connected_users || !d.connected_users.length) return;
|
||||
document.getElementById("notion-label").textContent = "✅ " + d.connected_users[0].workspace;
|
||||
} catch(e) {}
|
||||
}
|
||||
setTimeout(checkNotion, 3000);
|
||||
|
||||
// ===== 留言 =====
|
||||
async function sendMessage() {
|
||||
const n = (document.getElementById('msg-name').value || '').trim() || '匿名';
|
||||
@ -906,7 +939,7 @@ async function sendMessage() {
|
||||
} catch(e) { document.getElementById('msg-status').textContent = '连接失败'; }
|
||||
}
|
||||
|
||||
// ===== 恢复登录状态 =====
|
||||
// ===== 恢复登录 =====
|
||||
(function(){
|
||||
const u = localStorage.getItem('current_user');
|
||||
if (u && localStorage.getItem('logged_in') === 'true') {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user