feat: 初步测试自动过盾,添加适配器模型管理

This commit is contained in:
foxhui
2025-12-29 03:51:14 +08:00
parent 6f4860dbca
commit c82e7d6f06
22 changed files with 526 additions and 238 deletions
@@ -1 +1 @@
import{c as i,I as u}from"./index-BaE9FvKY.js";var l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 140H96c-17.7 0-32 14.3-32 32v496c0 17.7 14.3 32 32 32h380v112H304c-8.8 0-16 7.2-16 16v48c0 4.4 3.6 8 8 8h432c4.4 0 8-3.6 8-8v-48c0-8.8-7.2-16-16-16H548V700h380c17.7 0 32-14.3 32-32V172c0-17.7-14.3-32-32-32zm-40 488H136V212h752v416z"}}]},name:"desktop",theme:"outlined"};function c(r){for(var t=1;t<arguments.length;t++){var e=arguments[t]!=null?Object(arguments[t]):{},n=Object.keys(e);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(e).filter(function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.forEach(function(a){s(r,a,e[a])})}return r}function s(r,t,e){return t in r?Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[t]=e,r}var o=function(t,e){var n=c({},t,e.attrs);return i(u,c({},n,{icon:l}),null)};o.displayName="DesktopOutlined";o.inheritAttrs=!1;export{o as D};
import{c as i,I as u}from"./index-CeQVA4cs.js";var l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 140H96c-17.7 0-32 14.3-32 32v496c0 17.7 14.3 32 32 32h380v112H304c-8.8 0-16 7.2-16 16v48c0 4.4 3.6 8 8 8h432c4.4 0 8-3.6 8-8v-48c0-8.8-7.2-16-16-16H548V700h380c17.7 0 32-14.3 32-32V172c0-17.7-14.3-32-32-32zm-40 488H136V212h752v416z"}}]},name:"desktop",theme:"outlined"};function c(r){for(var t=1;t<arguments.length;t++){var e=arguments[t]!=null?Object(arguments[t]):{},n=Object.keys(e);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(e).filter(function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.forEach(function(a){s(r,a,e[a])})}return r}function s(r,t,e){return t in r?Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[t]=e,r}var o=function(t,e){var n=c({},t,e.attrs);return i(u,c({},n,{icon:l}),null)};o.displayName="DesktopOutlined";o.inheritAttrs=!1;export{o as D};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
import{c as l,I as P,_ as q,j as J,r as p,l as Q,o as X,a as Y,b as N,d as b,w as o,g as v,f,h as m,u as C,R as k,y as Z,D as K,i as L,e as S,t as _,m as ee,F as te,s as R,M as ae,z as le,A as ne,B as oe}from"./index-BaE9FvKY.js";var se={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M304 280h56c4.4 0 8-3.6 8-8 0-28.3 5.9-53.2 17.1-73.5 10.6-19.4 26-34.8 45.4-45.4C450.9 142 475.7 136 504 136h16c28.3 0 53.2 5.9 73.5 17.1 19.4 10.6 34.8 26 45.4 45.4C650 218.9 656 243.7 656 272c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8 0-40-8.8-76.7-25.9-108.1a184.31 184.31 0 00-74-74C596.7 72.8 560 64 520 64h-16c-40 0-76.7 8.8-108.1 25.9a184.31 184.31 0 00-74 74C304.8 195.3 296 232 296 272c0 4.4 3.6 8 8 8z"}},{tag:"path",attrs:{d:"M940 512H792V412c76.8 0 139-62.2 139-139 0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8a63 63 0 01-63 63H232a63 63 0 01-63-63c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 76.8 62.2 139 139 139v100H84c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h148v96c0 6.5.2 13 .7 19.3C164.1 728.6 116 796.7 116 876c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8 0-44.2 23.9-82.9 59.6-103.7a273 273 0 0022.7 49c24.3 41.5 59 76.2 100.5 100.5S460.5 960 512 960s99.8-13.9 141.3-38.2a281.38 281.38 0 00123.2-149.5A120 120 0 01836 876c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8 0-79.3-48.1-147.4-116.7-176.7.4-6.4.7-12.8.7-19.3v-96h148c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM716 680c0 36.8-9.7 72-27.8 102.9-17.7 30.3-43 55.6-73.3 73.3C584 874.3 548.8 884 512 884s-72-9.7-102.9-27.8c-30.3-17.7-55.6-43-73.3-73.3A202.75 202.75 0 01308 680V412h408v268z"}}]},name:"bug",theme:"outlined"};function D(n){for(var t=1;t<arguments.length;t++){var a=arguments[t]!=null?Object(arguments[t]):{},s=Object.keys(a);typeof Object.getOwnPropertySymbols=="function"&&(s=s.concat(Object.getOwnPropertySymbols(a).filter(function(c){return Object.getOwnPropertyDescriptor(a,c).enumerable}))),s.forEach(function(c){re(n,c,a[c])})}return n}function re(n,t,a){return t in n?Object.defineProperty(n,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):n[t]=a,n}var j=function(t,a){var s=D({},t,a.attrs);return l(P,D({},s,{icon:se}),null)};j.displayName="BugOutlined";j.inheritAttrs=!1;var ce={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M464 720a48 48 0 1096 0 48 48 0 10-96 0zm16-304v184c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V416c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8zm475.7 440l-416-720c-6.2-10.7-16.9-16-27.7-16s-21.6 5.3-27.7 16l-416 720C56 877.4 71.4 904 96 904h832c24.6 0 40-26.6 27.7-48zm-783.5-27.9L512 239.9l339.8 588.2H172.2z"}}]},name:"warning",theme:"outlined"};function E(n){for(var t=1;t<arguments.length;t++){var a=arguments[t]!=null?Object(arguments[t]):{},s=Object.keys(a);typeof Object.getOwnPropertySymbols=="function"&&(s=s.concat(Object.getOwnPropertySymbols(a).filter(function(c){return Object.getOwnPropertyDescriptor(a,c).enumerable}))),s.forEach(function(c){ie(n,c,a[c])})}return n}function ie(n,t,a){return t in n?Object.defineProperty(n,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):n[t]=a,n}var I=function(t,a){var s=E({},t,a.attrs);return l(P,E({},s,{icon:ce}),null)};I.displayName="WarningOutlined";I.inheritAttrs=!1;const ue={class:"toolbar"},de={class:"toolbar-row"},fe={class:"toolbar-row"},ve={style:{"margin-bottom":"12px",color:"#8c8c8c","font-size":"12px"}},me={key:0,style:{color:"#1890ff","margin-left":"8px"}},pe={class:"log-container"},ge={class:"log-time"},_e={class:"log-module"},he={class:"log-message"},Oe={__name:"logs",setup(n){const t=J(),a=p([]),s=p(!1),c=p(0),h=p(!1),g=p(null),y=p(""),w=p("all"),U={INFO:{color:"#1890ff",icon:oe},WARN:{color:"#faad14",icon:I},ERRO:{color:"#ff4d4f",icon:ne},DBUG:{color:"#722ed1",icon:j}},z=async()=>{s.value=!0;try{const r=await fetch("/admin/logs?lines=500",{headers:t.getHeaders()});if(r.ok){const e=await r.json();a.value=A(e.logs||[]),c.value=e.total||0}}catch{R.error("获取日志失败")}finally{s.value=!1}},A=r=>r.map((e,i)=>{const d=e.match(/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) \[(\w+)\] \[([^\]]+)\] (.*)$/);return d?{id:i,time:d[1],level:d[2],module:d[3],message:d[4],raw:e}:{id:i,raw:e,level:"INFO",time:"",module:"",message:e}}),x=Q(()=>a.value.filter(e=>{if(w.value!=="all"&&e.level!==w.value)return!1;if(y.value){const i=y.value.toLowerCase();return e.raw.toLowerCase().includes(i)}return!0}).reverse()),F=()=>{ae.confirm({title:"确认清除日志",content:"此操作将删除所有系统日志文件,是否继续?",okText:"确认清除",okType:"danger",cancelText:"取消",async onOk(){try{(await fetch("/admin/logs",{method:"DELETE",headers:t.getHeaders()})).ok?(R.success("日志已清除"),a.value=[],c.value=0):R.error("清除失败")}catch{R.error("请求失败")}}})},M=()=>{const r=a.value.map(O=>O.raw).join(`
import{c as l,I as P,_ as q,j as J,r as p,l as Q,o as X,a as Y,b as N,d as b,w as o,g as v,f,h as m,u as C,R as k,y as Z,D as K,i as L,e as S,t as _,m as ee,F as te,s as R,M as ae,z as le,A as ne,B as oe}from"./index-CeQVA4cs.js";var se={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M304 280h56c4.4 0 8-3.6 8-8 0-28.3 5.9-53.2 17.1-73.5 10.6-19.4 26-34.8 45.4-45.4C450.9 142 475.7 136 504 136h16c28.3 0 53.2 5.9 73.5 17.1 19.4 10.6 34.8 26 45.4 45.4C650 218.9 656 243.7 656 272c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8 0-40-8.8-76.7-25.9-108.1a184.31 184.31 0 00-74-74C596.7 72.8 560 64 520 64h-16c-40 0-76.7 8.8-108.1 25.9a184.31 184.31 0 00-74 74C304.8 195.3 296 232 296 272c0 4.4 3.6 8 8 8z"}},{tag:"path",attrs:{d:"M940 512H792V412c76.8 0 139-62.2 139-139 0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8a63 63 0 01-63 63H232a63 63 0 01-63-63c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 76.8 62.2 139 139 139v100H84c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h148v96c0 6.5.2 13 .7 19.3C164.1 728.6 116 796.7 116 876c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8 0-44.2 23.9-82.9 59.6-103.7a273 273 0 0022.7 49c24.3 41.5 59 76.2 100.5 100.5S460.5 960 512 960s99.8-13.9 141.3-38.2a281.38 281.38 0 00123.2-149.5A120 120 0 01836 876c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8 0-79.3-48.1-147.4-116.7-176.7.4-6.4.7-12.8.7-19.3v-96h148c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM716 680c0 36.8-9.7 72-27.8 102.9-17.7 30.3-43 55.6-73.3 73.3C584 874.3 548.8 884 512 884s-72-9.7-102.9-27.8c-30.3-17.7-55.6-43-73.3-73.3A202.75 202.75 0 01308 680V412h408v268z"}}]},name:"bug",theme:"outlined"};function D(n){for(var t=1;t<arguments.length;t++){var a=arguments[t]!=null?Object(arguments[t]):{},s=Object.keys(a);typeof Object.getOwnPropertySymbols=="function"&&(s=s.concat(Object.getOwnPropertySymbols(a).filter(function(c){return Object.getOwnPropertyDescriptor(a,c).enumerable}))),s.forEach(function(c){re(n,c,a[c])})}return n}function re(n,t,a){return t in n?Object.defineProperty(n,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):n[t]=a,n}var j=function(t,a){var s=D({},t,a.attrs);return l(P,D({},s,{icon:se}),null)};j.displayName="BugOutlined";j.inheritAttrs=!1;var ce={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M464 720a48 48 0 1096 0 48 48 0 10-96 0zm16-304v184c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V416c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8zm475.7 440l-416-720c-6.2-10.7-16.9-16-27.7-16s-21.6 5.3-27.7 16l-416 720C56 877.4 71.4 904 96 904h832c24.6 0 40-26.6 27.7-48zm-783.5-27.9L512 239.9l339.8 588.2H172.2z"}}]},name:"warning",theme:"outlined"};function E(n){for(var t=1;t<arguments.length;t++){var a=arguments[t]!=null?Object(arguments[t]):{},s=Object.keys(a);typeof Object.getOwnPropertySymbols=="function"&&(s=s.concat(Object.getOwnPropertySymbols(a).filter(function(c){return Object.getOwnPropertyDescriptor(a,c).enumerable}))),s.forEach(function(c){ie(n,c,a[c])})}return n}function ie(n,t,a){return t in n?Object.defineProperty(n,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):n[t]=a,n}var I=function(t,a){var s=E({},t,a.attrs);return l(P,E({},s,{icon:ce}),null)};I.displayName="WarningOutlined";I.inheritAttrs=!1;const ue={class:"toolbar"},de={class:"toolbar-row"},fe={class:"toolbar-row"},ve={style:{"margin-bottom":"12px",color:"#8c8c8c","font-size":"12px"}},me={key:0,style:{color:"#1890ff","margin-left":"8px"}},pe={class:"log-container"},ge={class:"log-time"},_e={class:"log-module"},he={class:"log-message"},Oe={__name:"logs",setup(n){const t=J(),a=p([]),s=p(!1),c=p(0),h=p(!1),g=p(null),y=p(""),w=p("all"),U={INFO:{color:"#1890ff",icon:oe},WARN:{color:"#faad14",icon:I},ERRO:{color:"#ff4d4f",icon:ne},DBUG:{color:"#722ed1",icon:j}},z=async()=>{s.value=!0;try{const r=await fetch("/admin/logs?lines=500",{headers:t.getHeaders()});if(r.ok){const e=await r.json();a.value=A(e.logs||[]),c.value=e.total||0}}catch{R.error("获取日志失败")}finally{s.value=!1}},A=r=>r.map((e,i)=>{const d=e.match(/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) \[(\w+)\] \[([^\]]+)\] (.*)$/);return d?{id:i,time:d[1],level:d[2],module:d[3],message:d[4],raw:e}:{id:i,raw:e,level:"INFO",time:"",module:"",message:e}}),x=Q(()=>a.value.filter(e=>{if(w.value!=="all"&&e.level!==w.value)return!1;if(y.value){const i=y.value.toLowerCase();return e.raw.toLowerCase().includes(i)}return!0}).reverse()),F=()=>{ae.confirm({title:"确认清除日志",content:"此操作将删除所有系统日志文件,是否继续?",okText:"确认清除",okType:"danger",cancelText:"取消",async onOk(){try{(await fetch("/admin/logs",{method:"DELETE",headers:t.getHeaders()})).ok?(R.success("日志已清除"),a.value=[],c.value=0):R.error("清除失败")}catch{R.error("请求失败")}}})},M=()=>{const r=a.value.map(O=>O.raw).join(`
`),e=new Blob([r],{type:"text/plain"}),i=URL.createObjectURL(e),d=document.createElement("a");d.href=i,d.download=`system-${new Date().toISOString().split("T")[0]}.log`,d.click(),URL.revokeObjectURL(i)},T=r=>{h.value=r,r?(z(),g.value=setInterval(z,5e3)):g.value&&(clearInterval(g.value),g.value=null)};return X(()=>{z()}),Y(()=>{g.value&&clearInterval(g.value)}),(r,e)=>{const i=f("a-select-option"),d=f("a-select"),O=f("a-button"),B=f("a-tooltip"),V=f("a-space"),W=f("a-input-search"),$=f("a-tag"),H=f("a-empty"),G=f("a-card");return b(),N(G,{title:"系统日志",bordered:!1},{default:o(()=>[v("div",ue,[v("div",de,[l(d,{value:w.value,"onUpdate:value":e[0]||(e[0]=u=>w.value=u),style:{width:"90px"},size:"small"},{default:o(()=>[l(i,{value:"all"},{default:o(()=>[...e[3]||(e[3]=[m("全部",-1)])]),_:1}),l(i,{value:"INFO"},{default:o(()=>[...e[4]||(e[4]=[m("INFO",-1)])]),_:1}),l(i,{value:"WARN"},{default:o(()=>[...e[5]||(e[5]=[m("WARN",-1)])]),_:1}),l(i,{value:"ERRO"},{default:o(()=>[...e[6]||(e[6]=[m("ERROR",-1)])]),_:1}),l(i,{value:"DBUG"},{default:o(()=>[...e[7]||(e[7]=[m("DEBUG",-1)])]),_:1})]),_:1},8,["value"]),l(V,{size:4},{default:o(()=>[l(B,{title:h.value?"关闭自动刷新":"开启自动刷新"},{default:o(()=>[l(O,{size:"small",type:h.value?"primary":"default",onClick:e[1]||(e[1]=u=>T(!h.value))},{icon:o(()=>[l(C(k))]),_:1},8,["type"])]),_:1},8,["title"]),l(B,{title:"导出日志"},{default:o(()=>[l(O,{size:"small",onClick:M},{icon:o(()=>[l(C(Z))]),_:1})]),_:1}),l(B,{title:"清除日志"},{default:o(()=>[l(O,{size:"small",danger:"",onClick:F},{icon:o(()=>[l(C(K))]),_:1})]),_:1})]),_:1})]),v("div",fe,[l(W,{value:y.value,"onUpdate:value":e[2]||(e[2]=u=>y.value=u),placeholder:"搜索日志",size:"small","enter-button":"","allow-clear":"",style:{width:"100%"}},null,8,["value"])])]),v("div",ve,[m(" 共 "+_(c.value)+" 条日志,当前显示 "+_(x.value.length)+" 条 ",1),h.value?(b(),L("span",me,[l(C(k),{spin:!0}),e[8]||(e[8]=m(" 自动刷新中 ",-1))])):S("",!0)]),v("div",pe,[(b(!0),L(te,null,ee(x.value,u=>(b(),L("div",{key:u.id,class:le(["log-line","level-"+u.level.toLowerCase()])},[v("span",ge,_(u.time),1),l($,{color:U[u.level]?.color||"#8c8c8c",size:"small",style:{margin:"0 8px"}},{default:o(()=>[m(_(u.level),1)]),_:2},1032,["color"]),v("span",_e,"["+_(u.module)+"]",1),v("span",he,_(u.message),1)],2))),128)),x.value.length===0?(b(),N(H,{key:0,description:"暂无日志"})):S("",!0)])]),_:1})}}},ye=q(Oe,[["__scopeId","data-v-6c3b8e99"]]);export{ye as default};
@@ -1 +1 @@
import{_ as b,j as w,k,o as c,b as C,d as S,w as n,c as o,g as e,f as a,h as i}from"./index-BaE9FvKY.js";const B={style:{"margin-bottom":"8px"}},T={style:{"margin-bottom":"8px"}},z={style:{"margin-bottom":"8px"}},U={style:{display:"flex","justify-content":"flex-end","margin-top":"24px"}},j={style:{"margin-bottom":"8px"}},M={style:{"margin-bottom":"8px"}},q={style:{display:"flex","justify-content":"flex-end","margin-top":"24px"}},L={__name:"server",setup(N){const d=w(),s=k({port:5173,authToken:"",keepaliveMode:"comment",queueBuffer:2,imageLimit:5});c(async()=>{await d.fetchServerConfig(),Object.assign(s,d.serverConfig)});const m=async()=>{await d.saveServerConfig(s)};return(V,t)=>{const p=a("a-input-number"),r=a("a-col"),y=a("a-input-password"),u=a("a-select-option"),g=a("a-select"),f=a("a-row"),v=a("a-button"),x=a("a-card"),_=a("a-layout");return S(),C(_,{style:{background:"transparent"}},{default:n(()=>[o(x,{title:"服务器设置",bordered:!1,style:{width:"100%"}},{default:n(()=>[o(f,{gutter:[16,16]},{default:n(()=>[o(r,{xs:24,md:12},{default:n(()=>[e("div",B,[t[5]||(t[5]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"监听端口",-1)),t[6]||(t[6]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}}," 设置服务器监听的端口号,默认为 5173 ",-1)),o(p,{value:s.port,"onUpdate:value":t[0]||(t[0]=l=>s.port=l),min:1,max:65535,placeholder:"请输入端口号",style:{width:"100%"}},null,8,["value"])])]),_:1}),o(r,{xs:24,md:12},{default:n(()=>[e("div",T,[t[7]||(t[7]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"鉴权 Token",-1)),t[8]||(t[8]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}}," 用于 API 请求鉴权的密钥,留空则不启用鉴权 ",-1)),o(y,{value:s.authToken,"onUpdate:value":t[1]||(t[1]=l=>s.authToken=l),placeholder:"请输入 Token",type:"password"},null,8,["value"])])]),_:1}),o(r,{xs:24,md:12},{default:n(()=>[e("div",z,[t[11]||(t[11]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"心跳包类型",-1)),t[12]||(t[12]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}}," 选择 SSE 流式响应的心跳包格式 ",-1)),o(g,{value:s.keepaliveMode,"onUpdate:value":t[2]||(t[2]=l=>s.keepaliveMode=l),style:{width:"100%"},placeholder:"请选择心跳包类型"},{default:n(()=>[o(u,{value:"comment"},{default:n(()=>[...t[9]||(t[9]=[i("Comment - 注释格式",-1)])]),_:1}),o(u,{value:"content"},{default:n(()=>[...t[10]||(t[10]=[i("Content - 内容格式",-1)])]),_:1})]),_:1},8,["value"])])]),_:1})]),_:1}),e("div",U,[o(v,{type:"primary",onClick:m},{default:n(()=>[...t[13]||(t[13]=[i(" 保存设置 ",-1)])]),_:1})])]),_:1}),o(x,{title:"队列设置",bordered:!1,style:{width:"100%","margin-top":"10px"}},{default:n(()=>[o(f,{gutter:[16,16]},{default:n(()=>[o(r,{xs:24,md:12},{default:n(()=>[e("div",j,[t[14]||(t[14]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"队列缓冲区大小",-1)),t[15]||(t[15]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}},[i(" 非流式请求的额外排队数(设为 0 则不限制非流式请求数量)"),e("br"),i(" 实际队列上限 = Workers数量 + 缓冲区大小 ")],-1)),o(p,{value:s.queueBuffer,"onUpdate:value":t[3]||(t[3]=l=>s.queueBuffer=l),min:0,max:100,placeholder:"默认为 2",style:{width:"100%"}},null,8,["value"])])]),_:1}),o(r,{xs:24,md:12},{default:n(()=>[e("div",M,[t[16]||(t[16]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"图片数量上限",-1)),t[17]||(t[17]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}},[i(" 单次请求最多支持的图片附件数量"),e("br"),i(" 网页最多支持10个附件,超出会被丢弃 ")],-1)),o(p,{value:s.imageLimit,"onUpdate:value":t[4]||(t[4]=l=>s.imageLimit=l),min:1,max:10,placeholder:"默认为 5",style:{width:"100%"}},null,8,["value"])])]),_:1})]),_:1}),e("div",q,[o(v,{type:"primary",onClick:m},{default:n(()=>[...t[18]||(t[18]=[i(" 保存设置 ",-1)])]),_:1})])]),_:1})]),_:1})}}},A=b(L,[["__scopeId","data-v-bd32923f"]]);export{A as default};
import{_ as b,j as w,k,o as c,b as C,d as S,w as n,c as o,g as e,f as a,h as i}from"./index-CeQVA4cs.js";const B={style:{"margin-bottom":"8px"}},T={style:{"margin-bottom":"8px"}},z={style:{"margin-bottom":"8px"}},U={style:{display:"flex","justify-content":"flex-end","margin-top":"24px"}},j={style:{"margin-bottom":"8px"}},M={style:{"margin-bottom":"8px"}},q={style:{display:"flex","justify-content":"flex-end","margin-top":"24px"}},L={__name:"server",setup(N){const d=w(),s=k({port:5173,authToken:"",keepaliveMode:"comment",queueBuffer:2,imageLimit:5});c(async()=>{await d.fetchServerConfig(),Object.assign(s,d.serverConfig)});const m=async()=>{await d.saveServerConfig(s)};return(V,t)=>{const p=a("a-input-number"),r=a("a-col"),y=a("a-input-password"),u=a("a-select-option"),g=a("a-select"),f=a("a-row"),v=a("a-button"),x=a("a-card"),_=a("a-layout");return S(),C(_,{style:{background:"transparent"}},{default:n(()=>[o(x,{title:"服务器设置",bordered:!1,style:{width:"100%"}},{default:n(()=>[o(f,{gutter:[16,16]},{default:n(()=>[o(r,{xs:24,md:12},{default:n(()=>[e("div",B,[t[5]||(t[5]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"监听端口",-1)),t[6]||(t[6]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}}," 设置服务器监听的端口号,默认为 5173 ",-1)),o(p,{value:s.port,"onUpdate:value":t[0]||(t[0]=l=>s.port=l),min:1,max:65535,placeholder:"请输入端口号",style:{width:"100%"}},null,8,["value"])])]),_:1}),o(r,{xs:24,md:12},{default:n(()=>[e("div",T,[t[7]||(t[7]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"鉴权 Token",-1)),t[8]||(t[8]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}}," 用于 API 请求鉴权的密钥,留空则不启用鉴权 ",-1)),o(y,{value:s.authToken,"onUpdate:value":t[1]||(t[1]=l=>s.authToken=l),placeholder:"请输入 Token",type:"password"},null,8,["value"])])]),_:1}),o(r,{xs:24,md:12},{default:n(()=>[e("div",z,[t[11]||(t[11]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"心跳包类型",-1)),t[12]||(t[12]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}}," 选择 SSE 流式响应的心跳包格式 ",-1)),o(g,{value:s.keepaliveMode,"onUpdate:value":t[2]||(t[2]=l=>s.keepaliveMode=l),style:{width:"100%"},placeholder:"请选择心跳包类型"},{default:n(()=>[o(u,{value:"comment"},{default:n(()=>[...t[9]||(t[9]=[i("Comment - 注释格式",-1)])]),_:1}),o(u,{value:"content"},{default:n(()=>[...t[10]||(t[10]=[i("Content - 内容格式",-1)])]),_:1})]),_:1},8,["value"])])]),_:1})]),_:1}),e("div",U,[o(v,{type:"primary",onClick:m},{default:n(()=>[...t[13]||(t[13]=[i(" 保存设置 ",-1)])]),_:1})])]),_:1}),o(x,{title:"队列设置",bordered:!1,style:{width:"100%","margin-top":"10px"}},{default:n(()=>[o(f,{gutter:[16,16]},{default:n(()=>[o(r,{xs:24,md:12},{default:n(()=>[e("div",j,[t[14]||(t[14]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"队列缓冲区大小",-1)),t[15]||(t[15]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}},[i(" 非流式请求的额外排队数(设为 0 则不限制非流式请求数量)"),e("br"),i(" 实际队列上限 = Workers数量 + 缓冲区大小 ")],-1)),o(p,{value:s.queueBuffer,"onUpdate:value":t[3]||(t[3]=l=>s.queueBuffer=l),min:0,max:100,placeholder:"默认为 2",style:{width:"100%"}},null,8,["value"])])]),_:1}),o(r,{xs:24,md:12},{default:n(()=>[e("div",M,[t[16]||(t[16]=e("div",{style:{"font-weight":"600","margin-bottom":"4px"}},"图片数量上限",-1)),t[17]||(t[17]=e("div",{style:{"font-size":"12px",color:"#8c8c8c","margin-bottom":"8px"}},[i(" 单次请求最多支持的图片附件数量"),e("br"),i(" 网页最多支持10个附件,超出会被丢弃 ")],-1)),o(p,{value:s.imageLimit,"onUpdate:value":t[4]||(t[4]=l=>s.imageLimit=l),min:1,max:10,placeholder:"默认为 5",style:{width:"100%"}},null,8,["value"])])]),_:1})]),_:1}),e("div",q,[o(v,{type:"primary",onClick:m},{default:n(()=>[...t[18]||(t[18]=[i(" 保存设置 ",-1)])]),_:1})])]),_:1})]),_:1})}}},A=b(L,[["__scopeId","data-v-bd32923f"]]);export{A as default};
@@ -1 +1 @@
import{x as i,j as a,s as r}from"./index-BaE9FvKY.js";const u=i("system",{state:()=>({status:"",version:"1.0.0",systemVersion:"",uptime:0,cpuUsage:0,memoryUsage:{total:0,used:0,free:0},safeMode:{enabled:!1,reason:null},stats:{totalRequests:0,successRate:0,activeWorkers:0,totalWorkers:0,avgResponseTime:0}}),actions:{async fetchStatus(){const t=a();try{const e=await fetch("/admin/status",{headers:t.getHeaders()});if(e.ok){const s=await e.json();this.$patch(s)}}catch(e){console.error("Failed to fetch system status:",e)}},async fetchStats(){const t=a();try{const e=await fetch("/admin/stats",{headers:t.getHeaders()});if(e.ok){const s=await e.json();this.stats=s}}catch(e){console.error("Failed to fetch stats:",e)}},async restartService(t={}){const e=a(),{loginMode:s,workerName:n}=t;try{const o=await(await fetch("/admin/restart",{method:"POST",headers:{...e.getHeaders(),"Content-Type":"application/json"},body:JSON.stringify({loginMode:s,workerName:n})})).json();return o.success?(r.success(o.message||"服务重启中..."),!0):(r.error("重启失败"),!1)}catch{return r.error("重启请求失败"),!1}},async stopService(){const t=a();try{const s=await(await fetch("/admin/stop",{method:"POST",headers:t.getHeaders()})).json();return s.success?(r.success(s.message||"服务停止中..."),!0):(r.error("停止失败"),!1)}catch{return r.error("停止请求失败"),!1}}}});export{u};
import{x as i,j as a,s as r}from"./index-CeQVA4cs.js";const u=i("system",{state:()=>({status:"",version:"1.0.0",systemVersion:"",uptime:0,cpuUsage:0,memoryUsage:{total:0,used:0,free:0},safeMode:{enabled:!1,reason:null},stats:{totalRequests:0,successRate:0,activeWorkers:0,totalWorkers:0,avgResponseTime:0}}),actions:{async fetchStatus(){const t=a();try{const e=await fetch("/admin/status",{headers:t.getHeaders()});if(e.ok){const s=await e.json();this.$patch(s)}}catch(e){console.error("Failed to fetch system status:",e)}},async fetchStats(){const t=a();try{const e=await fetch("/admin/stats",{headers:t.getHeaders()});if(e.ok){const s=await e.json();this.stats=s}}catch(e){console.error("Failed to fetch stats:",e)}},async restartService(t={}){const e=a(),{loginMode:s,workerName:n}=t;try{const o=await(await fetch("/admin/restart",{method:"POST",headers:{...e.getHeaders(),"Content-Type":"application/json"},body:JSON.stringify({loginMode:s,workerName:n})})).json();return o.success?(r.success(o.message||"服务重启中..."),!0):(r.error("重启失败"),!1)}catch{return r.error("重启请求失败"),!1}},async stopService(){const t=a();try{const s=await(await fetch("/admin/stop",{method:"POST",headers:t.getHeaders()})).json();return s.success?(r.success(s.message||"服务停止中..."),!0):(r.error("停止失败"),!1)}catch{return r.error("停止请求失败"),!1}}}});export{u};
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -6,7 +6,7 @@
<link rel="icon" type="image/png" href="/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WebAI2API</title>
<script type="module" crossorigin src="/assets/index-BaE9FvKY.js"></script>
<script type="module" crossorigin src="/assets/index-CeQVA4cs.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BVr8U7Bl.css">
</head>
+93 -4
View File
@@ -10,6 +10,12 @@ const drawerVisible = ref(false);
const currentAdapter = ref(null);
const currentConfig = reactive({});
// 模型过滤配置
const modelFilter = reactive({
mode: 'blacklist',
list: []
});
// 挂载时获取数据
onMounted(async () => {
await Promise.all([
@@ -21,6 +27,45 @@ onMounted(async () => {
// 适配器列表
const adapters = computed(() => settingsStore.adaptersMeta);
// 检查模型是否启用
const isModelEnabled = (modelId) => {
const inList = modelFilter.list.includes(modelId);
if (modelFilter.mode === 'whitelist') {
return inList;
} else {
return !inList;
}
};
// 切换模型启用/禁用
const toggleModel = (modelId, enabled) => {
const idx = modelFilter.list.indexOf(modelId);
if (modelFilter.mode === 'whitelist') {
// 白名单模式:启用=加入列表,禁用=移出列表
if (enabled && idx === -1) {
modelFilter.list.push(modelId);
} else if (!enabled && idx !== -1) {
modelFilter.list.splice(idx, 1);
}
} else {
// 黑名单模式:禁用=加入列表,启用=移出列表
if (!enabled && idx === -1) {
modelFilter.list.push(modelId);
} else if (enabled && idx !== -1) {
modelFilter.list.splice(idx, 1);
}
}
};
// 切换模式时重置列表
const onModeChange = (newMode) => {
if (newMode !== modelFilter.mode) {
modelFilter.mode = newMode;
modelFilter.list = [];
}
};
// 打开抽屉进行编辑
const handleEdit = (adapter) => {
currentAdapter.value = adapter;
@@ -41,6 +86,11 @@ const handleEdit = (adapter) => {
});
}
// 初始化模型过滤配置
const filter = adapter.modelFilter || { mode: 'blacklist', list: [] };
modelFilter.mode = filter.mode || 'blacklist';
modelFilter.list = [...(filter.list || [])];
drawerVisible.value = true;
};
@@ -49,11 +99,22 @@ const handleSave = async () => {
if (!currentAdapter.value) return;
const configToSave = {
[currentAdapter.value.id]: { ...currentConfig }
[currentAdapter.value.id]: {
...currentConfig,
modelFilter: {
mode: modelFilter.mode,
list: [...modelFilter.list]
}
}
};
const success = await settingsStore.saveAdapterConfig(configToSave);
if (success) {
// 更新本地缓存
const adapter = settingsStore.adaptersMeta.find(a => a.id === currentAdapter.value.id);
if (adapter) {
adapter.modelFilter = { mode: modelFilter.mode, list: [...modelFilter.list] };
}
drawerVisible.value = false;
}
};
@@ -76,7 +137,7 @@ const handleSave = async () => {
style="font-size: 18px; color: #1890ff; margin-right: 8px; flex-shrink: 0;" />
<span
style="font-weight: 600; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{
item.id }}</span>
item.id }}</span>
</div>
<SettingOutlined style="font-size: 16px; color: #8c8c8c; flex-shrink: 0;" />
</div>
@@ -95,11 +156,39 @@ const handleSave = async () => {
{{ currentAdapter.description }}
</div>
<!-- 模型管理折叠面板 -->
<a-collapse v-if="currentAdapter.models && currentAdapter.models.length > 0" style="margin-bottom: 16px;">
<a-collapse-panel key="models" header="模型管理">
<!-- 模式选择 -->
<div style="margin-bottom: 12px;">
<span style="margin-right: 12px; color: #666;">过滤模式:</span>
<a-radio-group :value="modelFilter.mode" @change="e => onModeChange(e.target.value)">
<a-radio value="blacklist">黑名单</a-radio>
<a-radio value="whitelist">白名单</a-radio>
</a-radio-group>
</div>
<div style="font-size: 12px; color: #999; margin-bottom: 12px;">
{{ modelFilter.mode === 'blacklist' ? '关闭的模型将被禁用,其他模型可用' : '仅开启的模型可用,其他模型禁用' }}
</div>
<!-- 模型列表 -->
<div style="max-height: 300px; overflow-y: auto;">
<div v-for="modelId in currentAdapter.models" :key="modelId"
style="display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f0f0f0;">
<span style="font-size: 13px; color: #333;">{{ modelId }}</span>
<a-switch :checked="isModelEnabled(modelId)"
@change="checked => toggleModel(modelId, checked)" size="small" />
</div>
</div>
</a-collapse-panel>
</a-collapse>
<!-- 其他配置项 -->
<div v-if="!currentAdapter.configSchema || currentAdapter.configSchema.length === 0">
<a-empty description="该适配器没有可配置项" />
<a-empty v-if="!currentAdapter.models || currentAdapter.models.length === 0" description="该适配器没有可配置项" />
</div>
<a-form layout="vertical" v-else>
<a-form layout="vertical" v-if="currentAdapter.configSchema && currentAdapter.configSchema.length > 0">
<template v-for="field in currentAdapter.configSchema" :key="field.key">
<a-form-item :label="field.label" :required="field.required">
<!-- 字符串输入 -->