PageSourceSearch

https://nickz.ai/assets/js/index-BIcskmq5.js

js nickz.ai collected 2026-10-05 14:20:24 UTC 64,966 bytes, 1 lines download raw bytes

1import{j as e,r as s}from"./vendor-react-DejgYtBM.js";import{C as t}from"./CardPro-DfDWu9ok.js";import{f as a,i as l,z as i,u as r,j as n,B as o,M as d,E as c,J as m,K as p,l as h,F as u,y as x,o as g,m as y,p as f,a1 as j,T as v,a as b,R as w,C as _,r as S,W as C,A as N,G as k,U as z,_ as M,v as T,Q as I,$ as O,s as V,t as A,H as E,aE as P,Y as $,D as J}from"./vendor-semi-D8d7bTtM.js";import{C as L}from"./CardTable-Cq0lqlnD.js";import{ax as K,b1 as R,Y as F,A as U,w as q,s as D,u as B,a0 as G,v as H,aF as W,b2 as Z,b3 as Y,b4 as Q,a6 as X,a7 as ee,a8 as se,Z as te,ag as ae}from"./index-BeIIFw6E.js";import{r as le,a as ie}from"./RenderUtils-CDnwzZ19.js";import{M as re}from"./channel.constants-BcDm5HEb.js";import{u as ne}from"./useIsMobile-D_kfVI0u.js";import{X as oe,ae as de,T as ce,x as me,p as pe,bB as he,ba as ue,bO as xe,am as ge,y as ye,bm as fe,aa as je,Z as ve}from"./vendor-icons-EJvJ5X-w.js";import"./vendor-motion-Chfy_MiU.js";const{Text:be}=a;function we(s){return e.jsx(e.Fragment,{children:F(s)})}const _e=s=>s&&0!==s.length?ie({items:s,renderItem:(s,t)=>e.jsx(l,{size:"small",shape:"circle",color:K(s),children:s},t)}):"-",Se=s=>{if(!s)return"-";const t=s.split(",").filter(Boolean);return ie({items:t,renderItem:(s,t)=>e.jsx(l,{size:"small",shape:"circle",color:K(s),children:s},t)})},Ce=s=>{try{const t="string"==typeof s?JSON.parse(s):s;if(t&&"object"==typeof t&&!Array.isArray(t)){const s=Object.keys(t||{});return 0===s.length?"-":ie({items:s,renderItem:(s,t)=>e.jsx(l,{size:"small",shape:"circle",color:K(s),children:s},t),maxDisplay:3})}return Array.isArray(t)?0===t.length?"-":ie({items:t,renderItem:(s,t)=>e.jsx(l,{color:"white",size:"small",shape:"circle",children:s},t),maxDisplay:3}):s||"-"}catch(t){return s||"-"}},Ne=s=>s&&0!==s.length?ie({items:s,renderItem:(s,t)=>e.jsxs(l,{color:"white",size:"small",shape:"circle",children:[s.name,"(",s.type,")"]},t)}):"-",ke=({value:t,record:a,refresh:l,t:i})=>{const[n,o]=s.useState(!1),[d,c]=s.useState(!1),[m,p]=s.useState(t||0),[h,u]=s.useState(t||0),x=async()=>{const e=Math.floor(Math.max(0,Number(m)||0));if(e!==h){c(!0);try{const s=await U.put("/api/models/",{id:a.id,sort_order:e,model_name:a.model_name,name_rule:a.name_rule,status:a.status,sync_official:a.sync_official,show_in_square:a.show_in_square??1,tags:a.tags||"",model_type:a.model_type||"",description:a.description||"",icon:a.icon||"",vendor_id:a.vendor_id,endpoints:a.endpoints||""});s.data.success?(q(i("排序值更新成功")),p(e),u(e),l&&l()):(D(s.data.message||i("更新失败")),p(h))}catch(s){D(s.response?.data?.message||i("更新失败")),p(h)}c(!1),o(!1)}else o(!1)};return n?e.jsx(r,{value:m,onChange:e=>p(e),onBlur:x,onKeyDown:e=>{"Enter"===e.key?(e.preventDefault(),x()):"Escape"===e.key&&(p(h),o(!1))},min:0,step:1,precision:0,disabled:d,size:"small",style:{width:80},autoFocus:!0}):e.jsx("div",{onClick:()=>{o(!0),u(m)},style:{cursor:"pointer",padding:"4px 8px",borderRadius:"4px",border:"1px solid transparent"},onMouseEnter:e=>{e.currentTarget.style.border="1px solid #ddd",e.currentTarget.style.backgroundColor="#f9f9f9"},onMouseLeave:e=>{e.currentTarget.style.border="1px solid transparent",e.currentTarget.style.backgroundColor="transparent"},children:m})},ze=({value:t,record:a,refresh:i,t:r})=>{const[n,o]=s.useState(!1),[d,c]=s.useState(t??1);return e.jsx(l,{size:"small",shape:"circle",color:1===d?"green":"red",style:{cursor:n?"not-allowed":"pointer",opacity:n?.6:1},onClick:async e=>{e.stopPropagation();const s=1===d?0:1;o(!0);try{const e=await U.put("/api/models/",{id:a.id,sort_order:a.sort_order||0,model_name:a.model_name,name_rule:a.name_rule,status:a.status,sync_official:a.sync_official,show_in_square:s,tags:a.tags||"",model_type:a.model_type||"",description:a.description||"",icon:a.icon||"",vendor_id:a.vendor_id,endpoints:a.endpoints||""});e.data.success?(q(r(1===s?"已设置为显示":"已设置为隐藏")),c(s),i&&i()):D(e.data.message||r("更新失败"))}catch(t){D(t.response?.data?.message||r("更新失败"))}o(!1)},children:r(n?"更新中...":1===d?"显示":"隐藏")})},Me=t=>{const{models:a,loading:r,activePage:h,pageSize:u,modelCount:x,compactMode:g,handlePageChange:y,handlePageSizeChange:f,rowSelection:j,handleRow:v,manageModel:b,setEditingModel:w,setShowEdit:_,refresh:S,vendorMap:C,t:N}=t,k=s.useMemo(()=>(({t:s,manageModel:t,setEditingModel:a,setShowEdit:r,refresh:c,vendorMap:m})=>[{title:s("图标"),dataIndex:"icon",width:70,align:"center",render:(s,t)=>((s,t)=>{const a=s?.icon||t[s?.vendor_id]?.icon;return a?e.jsx("div",{className:"flex items-center justify-center",children:R(a,20)}):"-"})(t,m)},{title:s("模型名称"),dataIndex:"model_name",render:s=>e.jsx(be,{copyable:!0,onClick:e=>e.stopPropagation(),children:s})},{title:s("匹配类型"),dataIndex:"name_rule",render:(t,a)=>((s,t,a)=>{const r={0:{color:"green",label:a("精确")},1:{color:"blue",label:a("前缀")},2:{color:"orange",label:a("包含")},3:{color:"purple",label:a("后缀")}}[s];if(!r)return"-";let n=r.label;0!==s&&t.matched_count&&(n=a("{{label}} {{count}} 个模型",{label:r.label,count:t.matched_count}));const o=e.jsx(l,{color:r.color,size:"small",shape:"circle",children:n});return 0!==s&&t.matched_models&&0!==t.matched_models.length?e.jsx(i,{content:t.matched_models.join(", "),showArrow:!0,children:o}):o})(t,a,s)},{title:s("排序"),dataIndex:"sort_order",width:100,render:(t,a)=>e.jsx(ke,{value:t,record:a,refresh:c,t:s})},{title:s("参与官方同步"),dataIndex:"sync_official",render:t=>e.jsx(l,{size:"small",shape:"circle",color:1===t?"green":"orange",children:s(1===t?"是":"否")})},{title:s("模型广场显示"),dataIndex:"show_in_square",render:(t,a)=>e.jsx(ze,{value:t,record:a,refresh:c,t:s})},{title:s("描述"),dataIndex:"description",render:e=>le(e,200)},{title:s("供应商"),dataIndex:"vendor_id",render:(s,t)=>((s,t)=>{if(!s||!t[s])return"-";const a=t[s];return e.jsx(l,{color:"white",shape:"circle",prefixIcon:R(a.icon||"L
1ayers",14),children:a.name})})(s,m)},{title:s("标签"),dataIndex:"tags",render:Se},{title:s("模型类型"),dataIndex:"model_type",render:s=>{return(t=s)?e.jsx(l,{size:"small",shape:"circle",color:K(t),children:t}):"-";var t}},{title:s("端点"),dataIndex:"endpoints",render:Ce},{title:s("已绑定渠道"),dataIndex:"bound_channels",render:Ne},{title:s("可用分组"),dataIndex:"enable_groups",render:_e},{title:s("计费类型"),dataIndex:"quota_types",render:t=>((s,t)=>Array.isArray(s)&&0!==s.length?ie({items:s,renderItem:(s,a)=>1===s?e.jsx(l,{color:"teal",size:"small",shape:"circle",children:t("按次计费")},`${s}-${a}`):0===s?e.jsx(l,{color:"violet",size:"small",shape:"circle",children:t("按量计费")},`${s}-${a}`):e.jsx(l,{color:"white",size:"small",shape:"circle",children:s},`${s}-${a}`),maxDisplay:3}):"-")(t,s)},{title:s("创建时间"),dataIndex:"created_time",render:(s,t,a)=>e.jsx("div",{children:we(s)})},{title:s("更新时间"),dataIndex:"updated_time",render:(s,t,a)=>e.jsx("div",{children:we(s)})},{title:"",dataIndex:"operate",fixed:"right",render:(l,i,m)=>((s,t,a,l,i,r,c)=>e.jsxs(n,{wrap:!0,children:[1===t.status?e.jsx(o,{type:"danger",size:"small",onClick:()=>i(t.id,"disable",t),children:c("禁用")}):e.jsx(o,{size:"small",onClick:()=>i(t.id,"enable",t),children:c("启用")}),e.jsx(o,{type:"tertiary",size:"small",onClick:()=>{a(t),l(!0)},children:c("编辑")}),e.jsx(o,{type:"danger",size:"small",onClick:()=>{d.confirm({title:c("确定是否要删除此模型?"),content:c("此修改将不可逆"),onOk:()=>{(async()=>{await i(t.id,"delete",t),await r()})()}})},children:c("删除")})]}))(0,i,a,r,t,c,s)}])({t:N,manageModel:b,setEditingModel:w,setShowEdit:_,refresh:S,vendorMap:C}),[N,b,w,_,S,C]),z=s.useMemo(()=>g?k.map(e=>{if("operate"===e.dataIndex){const{fixed:s,...t}=e;return t}return e}):k,[g,k]);return e.jsx(L,{columns:z,dataSource:a,scroll:g?void 0:{x:"max-content"},pagination:{currentPage:h,pageSize:u,total:x,showSizeChanger:!0,pageSizeOptions:[10,20,50,100],onPageSizeChange:f,onPageChange:y},hidePagination:!0,loading:r,rowSelection:j,onRow:v,empty:e.jsx(c,{image:e.jsx(p,{style:{width:150,height:150}}),darkModeImage:e.jsx(m,{style:{width:150,height:150}}),description:N("搜索无结果"),style:{padding:30}}),className:"rounded-xl overflow-hidden",size:"middle"})},Te=({visible:t,onClose:l,onConfigureModel:i,t:r})=>{const[n,g]=s.useState(!1),[y,f]=s.useState([]),[j,v]=s.useState(""),[b,w]=s.useState(1),_=ne();s.useEffect(()=>{t?((async()=>{g(!0);try{const e=await U.get("/api/models/missing");e.data.success?f(e.data.data||[]):D(e.data.message)}catch(e){D(r("获取未配置模型失败"))}g(!1)})(),v(""),w(1)):f([])},[t]);const S=y.filter(e=>e.toLowerCase().includes(j.toLowerCase())),C=(()=>{const e=(b-1)*re,s=e+re;return S.slice(e,s).map(e=>({model:e,key:e}))})(),N=[{title:r("模型名称"),dataIndex:"model",render:s=>e.jsx("div",{className:"flex items-center",children:e.jsx(a.Text,{strong:!0,children:s})})},{title:"",dataIndex:"operate",fixed:"right",width:120,render:(s,t)=>e.jsx(o,{type:"primary",size:"small",onClick:()=>i(t.model),children:r("配置")})}];return e.jsx(d,{title:e.jsx("div",{className:"flex flex-col gap-2 w-full",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(a.Text,{strong:!0,className:"!text-[hsl(var(--foreground))] !text-base",children:r("未配置的模型列表")}),e.jsx(a.Text,{type:"tertiary",size:"small",children:r("共 {{count}} 个未配置模型",{count:y.length})})]})}),visible:t,onCancel:l,footer:null,size:_?"full-width":"medium",className:"!rounded-lg",children:e.jsx(h,{spinning:n,children:0!==y.length||n?e.jsxs("div",{className:"missing-models-content",children:[e.jsx("div",{className:"flex items-center justify-end gap-2 w-full mb-4",children:e.jsx(u,{placeholder:r("搜索模型..."),value:j,onChange:e=>{v(e),w(1)},className:"!w-full",prefix:e.jsx(oe,{size:16}),showClear:!0})}),S.length>0?e.jsx(x,{columns:N,dataSource:C,pagination:{currentPage:b,pageSize:re,total:S.length,showSizeChanger:!1,onPageChange:e=>w(e)}}):e.jsx(c,{image:e.jsx(p,{style:{width:100,height:100}}),darkModeImage:e.jsx(m,{style:{width:100,height:100}}),description:r(j?"未找到匹配的模型":"暂无缺失模型"),style:{padding:20}})]}):e.jsx(c,{image:e.jsx(p,{style:{width:150,height:150}}),darkModeImage:e.jsx(m,{style:{width:150,height:150}}),description:r("暂无缺失模型"),style:{padding:30}})})})},{Text:Ie}=a,Oe=(()=>{let e=0;return()=>"kv_"+e++})(),Ve=({value:t="",onChange:a,field:l,label:n,placeholder:d,extraText:c,extraFooter:m,showClear:p=!0,template:h,templateLabel:x,editorType:C="keyValue",rules:N=[],formApi:k=null,...z})=>{const{t:M}=B(),T=s.useCallback((e,s=[])=>e&&"object"==typeof e?Object.entries(e).map(([e,t],a)=>{const l=s[a];return{id:l&&l.key===e?l.id:Oe(),key:e,value:t}}):[],[]),I=s.useCallback(e=>{const s={};
1return e.forEach(e=>{e.key&&(s[e.key]=e.value)}),s},[]),[O,V]=s.useState(()=>{if("string"==typeof t&&t.trim())try{const e=JSON.parse(t);return T(e)}catch(e){return[]}return"object"==typeof t&&null!==t?T(t):[]}),[A,E]=s.useState(()=>"string"==typeof t?t:t&&"object"==typeof t?JSON.stringify(t,null,2):""),[P,$]=s.useState(()=>{if("string"==typeof t&&t.trim())try{const e=JSON.parse(t);return Object.keys(e).length>10?"manual":"visual"}catch(e){return"manual"}return"visual"}),[J,L]=s.useState(""),K=s.useMemo(()=>{const e={},s=new Set;return O.forEach(t=>{t.key&&(e[t.key]=(e[t.key]||0)+1,e[t.key]>1&&s.add(t.key))}),s},[O]);s.useEffect(()=>{try{let e={};"string"==typeof t&&t.trim()?e=JSON.parse(t):"object"==typeof t&&null!==t&&(e=t);const s=I(O);JSON.stringify(e)!==JSON.stringify(s)&&V(T(e,O)),L("")}catch(e){e.message,L(e.message)}},[t]),s.useEffect(()=>{"manual"!==P&&E("string"==typeof t?t:t&&"object"==typeof t?JSON.stringify(t,null,2):"")},[t,P]);const R=s.useCallback(e=>{V(e);const s=I(e),t=0===Object.keys(s).length?"":JSON.stringify(s,null,2);L(""),k&&l&&k.setValue(l,t),a?.(t)},[a,k,l,I]),F=s.useCallback(e=>{if(E(e),e&&e.trim())try{const s=JSON.parse(e);V(T(s,O)),L(""),a?.(e)}catch(s){L(s.message)}else V([]),L(""),a?.("")},[a,T,O]),U=s.useCallback(()=>{if("visual"===P){const e=I(O);E(0===Object.keys(e).length?"":JSON.stringify(e,null,2)),$("manual")}else try{let e={};A&&A.trim()?e=JSON.parse(A):"string"==typeof t&&t.trim()?e=JSON.parse(t):"object"==typeof t&&null!==t&&(e=t),V(T(e,O)),L(""),$("visual")}catch(e){return void L(e.message)}},[P,t,A,O,I,T]),q=s.useCallback(()=>{const e=[...O],s=e.map(e=>e.key);let t=1,a=`field_${t}`;for(;s.includes(a);)t+=1,a=`field_${t}`;e.push({id:Oe(),key:a,value:""}),R(e)},[O,R]),D=s.useCallback(e=>{const s=O.filter(s=>s.id!==e);R(s)},[O,R]),G=s.useCallback((e,s)=>{const t=O.map(t=>t.id===e?{...t,key:s}:t);R(t)},[O,R]),H=s.useCallback((e,s)=>{const t=O.map(t=>t.id===e?{...t,value:s}:t);R(t)},[O,R]),W=s.useCallback(()=>{if(h){const e=JSON.stringify(h,null,2);k&&l&&k.setValue(l,e),E(e),V(T(h,O)),a?.(e),L("")}},[h,a,k,l,T,O]),Z=(s,t)=>{const a=typeof t;return"boolean"===a?e.jsxs("div",{className:"flex items-center",children:[e.jsx(S,{checked:t,onChange:e=>H(s,e)}),e.jsx(Ie,{type:"tertiary",className:"ml-2",children:M(t?"true":"false")})]}):"number"===a?e.jsx(r,{value:t,onChange:e=>H(s,e),style:{width:"100%"},placeholder:M("输入数字")}):"object"===a&&null!==t?e.jsx(j,{rows:2,value:JSON.stringify(t,null,2),onChange:e=>{try{const t=e.trim()?JSON.parse(e):{};H(s,t)}catch{}},placeholder:M("输入JSON对象")}):e.jsx(u,{placeholder:M("参数值"),value:String(t),onChange:e=>{let t=e;"true"===e?t=!0:"false"===e&&(t=!1),H(s,t)}})},Y=J&&""!==J.trim();return e.jsx(g.Slot,{label:n,children:e.jsxs(y,{header:e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs(v,{type:"slash",activeKey:P,onChange:e=>{"manual"===e&&"visual"===P?$("manual"):"visual"===e&&"manual"===P&&U()},children:[e.jsx(b,{tab:M("可视化"),itemKey:"visual"}),e.jsx(b,{tab:M("手动编辑"),itemKey:"manual"})]}),h&&x&&e.jsx(o,{type:"tertiary",onClick:W,size:"small",children:x})]}),headerStyle:{padding:"12px 16px"},bodyStyle:{padding:"16px"},className:"!rounded-2xl",children:[Y&&e.jsx(f,{type:"danger",description:`JSON 格式错误: ${J}`,className:"mb-3"}),"visual"===P?e.jsxs("div",{children:["region"===C?(()=>{const s=O.find(e=>"default"===e.key),t=O.filter(e=>"default"!==e.key);return e.jsxs("div",{className:"space-y-2",children:[K.size>0&&e.jsx(f,{type:"warning",icon:e.jsx(de,{size:16}),description:e.jsxs("div",{children:[e.jsx(Ie,{strong:!0,children:M("存在重复的键名:")}),e.jsx(Ie,{children:Array.from(K).join(", ")}),e.jsx("br",{}),e.jsx(Ie,{type:"tertiary",size:14,children:M("注意:JSON中重复的键只会保留最后一个同名键的值")})]}),className:"mb-3"}),e.jsx(g.Slot,{label:M("默认区域"),children:e.jsx(u,{placeholder:M("默认区域,如: us-central1"),value:s?s.value:"",onChange:e=>{if(s)H(s.id,e);else{const s=[...O,{id:Oe(),key:"default",value:e}];R(s)}}})}),e.jsx(g.Slot,{label:M("模型专用区域"),children:e.jsxs("div",{children:[t.map(s=>{const t=K.has(s.key);return e.jsxs(w,{gutter:8,align:"middle",className:"mb-2",children:[e.jsx(_,{span:10,children:e.jsxs("div",{className:"relative",children:[e.jsx(u,{placeholder:M("模型名称"),value:s.key,onChange:e=>G(s.id,e),status:t?"warning":void 0}),t&&e.jsx(i,{content:M("重复的键名"),children:e.jsx(de,{size:16,className:"absolute right-2 top-1/2 transform -translate-y-1/2",style:{color:"hsl(var(--warning))",fontSize:"14px"}})})]})}),e.jsx(_,{span:12,children:e.jsx(u,{placeholder:M("区域"),value:s.value,onChange:e=>H(s.id,e)})}),e.jsx(_,{span:2,children:e.jsx(o,{icon:e.jsx(ce,{size:16}),type:"danger",theme:"borderless",onClick:()=>D(s.id),style:{width:"100%"}})})]},s.id)}),e.jsx("div",{className:"mt-2 flex justify-center",children:e.jsx(o,{icon:e.jsx(me,{size:16}),onClick:q,type:"primary",theme:"outline",children:M("添加模型区域")})})]})})]})})():e.jsxs("div",{className:"space-y-1",children:[K.size>0&&e.jsx(f,{type:"warning",icon:e.jsx(de,{size:16}),description:e.jsxs("div",{children:[e.jsx(Ie,{strong:!0,children:M("存在重复的键名:")}),e.jsx(Ie,{children:Array.from(K).join(", ")}),e.jsx("br",{}),e.jsx(Ie,{type:"tertiary",size:14,children:M("注意:JSON中重复的键只会保留最后一个同名键的值")}
1)]}),className:"mb-3"}),0===O.length&&e.jsx("div",{className:"text-center py-6 px-4",children:e.jsx(Ie,{type:"tertiary",className:"text-gray-500 text-sm",children:M("暂无数据,点击下方按钮添加键值对")})}),O.map((s,t)=>{const a=K.has(s.key),l=a&&O.slice(t+1).every(e=>e.key!==s.key);return e.jsxs(w,{gutter:8,align:"middle",children:[e.jsx(_,{span:10,children:e.jsxs("div",{className:"relative",children:[e.jsx(u,{placeholder:M("键名"),value:s.key,onChange:e=>G(s.id,e),status:a?"warning":void 0}),a&&e.jsx(i,{content:M(l?"这是重复键中的最后一个,其值将被使用":"重复的键名,此值将被后面的同名键覆盖"),children:e.jsx(de,{size:16,className:"absolute right-2 top-1/2 transform -translate-y-1/2",style:{color:l?"#ff7d00":"#faad14",fontSize:"14px"}})})]})}),e.jsx(_,{span:12,children:Z(s.id,s.value)}),e.jsx(_,{span:2,children:e.jsx(o,{icon:e.jsx(ce,{size:16}),type:"danger",theme:"borderless",onClick:()=>D(s.id),style:{width:"100%"}})})]},s.id)}),e.jsx("div",{className:"mt-2 flex justify-center",children:e.jsx(o,{icon:e.jsx(me,{size:16}),type:"primary",theme:"outline",onClick:q,children:M("添加键值对")})})]}),e.jsx(g.Input,{field:l,value:t,rules:N,style:{display:"none"},noLabel:!0,...z})]}):e.jsxs("div",{children:[e.jsx(j,{placeholder:d,value:A,onChange:F,showClear:p,rows:Math.max(8,A?A.split("\n").length:8)}),e.jsx(g.Input,{field:l,value:t,rules:N,style:{display:"none"},noLabel:!0,...z})]}),c&&e.jsx("div",{className:"mt-3 pt-3",style:{borderTop:"1px solid hsl(var(--border))"},children:e.jsx(Ie,{type:"tertiary",size:"small",style:{display:"block",whiteSpace:"normal",wordBreak:"break-word",lineHeight:1.6},children:c})}),m&&e.jsx("div",{className:"mt-1",children:m})]})})},{Text:Ae,Title:Ee}=a,Pe={openai:{path:"/v1/chat/completions",method:"POST"},"openai-response":{path:"/v1/responses",method:"POST"},anthropic:{path:"/v1/messages",method:"POST"},gemini:{path:"/v1beta/models/{model}:generateContent",method:"POST"},"jina-rerank":{path:"/rerank",method:"POST"},"image-generation":{path:"/v1/images/generations",method:"POST"}},$e=({visible:t,onClose:a,editingGroup:i,onSuccess:r})=>{const{t:d}=B(),c=ne(),[m,p]=s.useState(!1),u=s.useRef(null),x=i&&void 0!==i.id,[f,j]=s.useState(i?.type||"tag");s.useEffect(()=>{j(i?.type||"tag")},[i?.type]);const v=[{label:d("模型组"),value:"model"},{label:d("标签组"),value:"tag"},{label:d("端点组"),value:"endpoint"}];return e.jsx(C,{placement:"left",title:e.jsxs(n,{children:[x?e.jsx(l,{color:"blue",shape:"circle",children:d("更新")}):e.jsx(l,{color:"green",shape:"circle",children:d("新建")}),e.jsx(Ee,{heading:4,className:"m-0",children:d(x?"更新预填组":"创建新的预填组")})]}),visible:t,onCancel:a,width:c?"100%":600,bodyStyle:{padding:"0"},footer:e.jsx("div",{className:"flex justify-end bg-white",children:e.jsxs(n,{children:[e.jsx(o,{theme:"solid",className:"!rounded-lg",onClick:()=>u.current?.submitForm(),icon:e.jsx(he,{size:16}),loading:m,children:d("提交")}),e.jsx(o,{theme:"light",className:"!rounded-lg",type:"primary",onClick:a,icon:e.jsx(ue,{size:16}),children:d("取消")})]})}),closeIcon:null,children:e.jsx(h,{spinning:m,children:e.jsx(g,{getFormApi:e=>u.current=e,initValues:{name:i?.name||"",type:i?.type||"tag",description:i?.description||"",items:(()=>{try{return"endpoint"===i?.type?"string"==typeof i?.items?i.items:JSON.stringify(i.items||{},null,2):Array.isArray(i?.items)?i.items:[]}catch{return"endpoint"===i?.type?"":[]}})()},onSubmit:async e=>{p(!0);try{const s={...e};if("endpoint"===e.type?s.items=e.items||"":s.items=Array.isArray(e.items)?e.items:[],i.id){s.id=i.id;const e=await U.put("/api/prefill_group",s);e.data.success?(q(d("更新成功")),r()):D(e.data.message||d("更新失败"))}else{const e=await U.post("/api/prefill_group",s);e.data.success?(q(d("创建成功")),r()):D(e.data.message||d("创建失败"))}}catch(s){D(d("操作失败"))}p(!1)},children:e.jsx("div",{className:"p-2",children:e.jsxs(y,{className:"!rounded-2xl shadow-sm border-0",children:[e.jsxs("div",{className:"flex items-center mb-2",children:[e.jsx(N,{size:14,color:"green",className:"mr-2 shadow-md",children:e.jsx(pe,{size:16})}),e.jsxs("div",{children:[e.jsx(Ae,{className:"text-lg font-medium",children:d("基本信息")}),e.jsx("div",{className:"text-xs text-gray-600",children:d("设置预填组的基本信息")})]})]}),e.jsxs(w,{gutter:12,children:[e.jsx(_,{span:24,children:e.jsx(g.Input,{field:"name",label:d("组名"),placeholder:d("请输入组名"),rules:[{required:!0,message:d("请输入组名")}],showClear:!0})}),e.jsx(_,{span:24,children:e.jsx(g.Select,{field:"type",label:d("类型"),placeholder:d("选择组类型"),optionList:v,rules:[{required:!0,message:d("请选择组类型")}],style:{width:"100%"},onChange:e=>j(e)})}),e.jsx(_,{span:24,children:e.jsx(g.TextArea,{field:"description",label:d("描述"),placeholder:d("请输入组描述"),rows:3,showClear:!0})}),e.jsx(_,{span:24,children:"endpoint"===f?e.jsx(Ve,{field:"items",label:d("端点映射"),value:u.current?.getValue("items")??("string"==typeof i?.items?i.items:JSON.stringify(i.items||{},null,2)),onChange:e=>u.current?.setValue("items",e),editorType:"object",placeholder:'{\n  "openai": {"path": "/v1/chat/completions", "method": "POST"}\n}',template:Pe,templateLabel:d("填入模板"),extraText:d("键为端点类型,值为路径和方法对象")}):e.jsx(g.TagInput,{field:"items",label:d("项目"),placeholder:d("输入项目名称,按回车添加"),addOnBlur:!0,showClear:!0,style:{width:"100%"}})})]})]})})})})})},{Text:Je,Title:Le}=a,Ke=({visible:t,onClose:a})=>{const{t:i}=B(),r=ne(),[d,u]=s.useState(!1),[x,g]=s.useState([]),[f,j]=s.useState(!1),[v,b]=s.useState({id:void 0}),w=[{label:i("模型组"),value:"model"},{label:i("标签组"),value:"tag"},{label:i("端点组"),value:"endpoint"}],_=async()=>{u(!0);try{const e=await U.get("/api/prefill_group");e.data.success?g(e.data.data||[]):D(e.data.message||i("获取组列表失败"))}catch(e){D(i("获取组列表失败"))}u(!1)},S=(e={})=>{b(e),j(!0)},z=()=>{j(!1),setTimeout(()=>{b({id:void 0})},300)},M=[{title:i("组名"),dataIndex:"name",key:"name",render:(s,t)=>e.jsxs(n,{children:[e.jsx(Je,{strong:!0,children:s}),e.jsx(l,{color:"white",shape:"circle",size:"small",children:w.find(e=>e.value===t.type)?.label||t.type})]})},{title:i("描述"),dataIndex:"description",key:"description",render:e=>le(e,150)},{title:i("项目内容"),dataIndex:"items",key:"items",render:(s,t)=>{try{if("endpoint"===t.type){const t="string"==typeof s?JSON.parse(s||"{}"):s||{},a=Object.keys(t);return 0===a.length?e.jsx(Je,{type:"tertiary",children:i("暂无项目")}):ie({items:a,renderItem:(s,t)=>e.jsx(l,{size:"small",shape:"circle",color:K(s),children:s},t),maxDisplay:3})}const a="string"==typeof s?JSON.parse(s):s;return Array.isArray(a)&&0!==a.length?ie({items:a,renderItem:(s,t)=>e.jsx(l,{size:"small",shape:"circle",color:K(s),children:s},t),maxDisplay:3}):e.jsx(Je,{type:"tertiary",children:i("暂无项目")})}catch{return e.jsx(Je,{type:"tertiary",children:i("数据格式错误")})}}},{title:"",key:"action",fixed:"right",width:140,render:(s,t)=>e.jsxs(n,{children:[e.jsx(o,{size:"small",onClick:()=>S(t),children:i("编辑")}),e.jsx(k,{title:i("确定删除此组?"),onConfirm:()=>(async e=>{try{const s=await U.delete(`/api/prefill_group/${e}`);s.data.success?(q(i("删除成功")),_()):D(s.data.message||i("删除失败"))}catch(s){D(i("删除失败"))}})(t.id),children:e.jsx(o,{size:"small",type:"danger",children:i("删除")})})]})}];return s.useEffect(()=>{t&&_()},[t]),e.jsxs(e.Fragment,{children:[e.jsx(C,{placement:"left",title:e.jsxs(n,{children:[e.jsx(l,{color:"blue",shape:"circle",children:i("管理")}),e.jsx(Le,{heading:4,className:"m-0",children:i("预填组管理")})]}),visible:t,onCancel:a,width:r?"100%":800,bodyStyle:{padding:"0"},closeIcon:null,children:e.jsx(h,{spinning:d,children:e.jsx("div",{className:"p-2",children:e.jsxs(y,{className:"!rounded-2xl shadow-sm border-0",children:[e.jsxs("div",{className:"flex items-center mb-2",children:[e.jsx(N,{size:14,color:"blue",className:"mr-2 shadow-md",children:e.jsx(pe,{size:16})}),e.jsxs("div",{children:[e.jsx(Je,{className:"text-lg font-medium",children:i("组列表")}),e.jsx("div",{className:"text-xs text-gray-600",children:i("管理模型、标签、端点等预填组")})]})]}),e.jsx("div",{className:"flex justify-end mb-4",children:e.jsx(o,{type:"primary",theme:"solid",size:"small",icon:e.jsx(me,{size:16}),onClick:()=>S(),children:i("新建组")}
1)}),x.length>0?e.jsx(L,{columns:M,dataSource:x,rowKey:"id",hidePagination:!0,size:"small",scroll:{x:"max-content"}}):e.jsx(c,{image:e.jsx(p,{style:{width:150,height:150}}),darkModeImage:e.jsx(m,{style:{width:150,height:150}}),description:i("暂无预填组"),style:{padding:30}})]})})})}),e.jsx($e,{visible:f,onClose:z,editingGroup:v,onSuccess:()=>{z(),_()}})]})},Re=({compactMode:s,setCompactMode:t,t:a,size:l="small",type:i="tertiary",className:r="",...n})=>ne()?null:e.jsx(o,{type:i,size:l,className:`w-full md:w-auto ${r}`,onClick:()=>t(!s),...n,children:a(s?"自适应列表":"紧凑列表")});Re.propTypes={compactMode:z.bool.isRequired,setCompactMode:z.func.isRequired,t:z.func.isRequired,size:z.string,type:z.string,className:z.string};const Fe="models-batch-actions",Ue=({selectedKeys:t=[],t:l,onDelete:i,onAddPrefill:r,onClear:d,onCopy:c})=>(s.useEffect(()=>{const s=t.length;if(s>0){const t=e.jsxs(n,{wrap:!0,children:[e.jsx("span",{children:l("批量操作")}),e.jsx(a.Text,{type:"tertiary",size:"small",children:l("已选择 {{count}} 个模型",{count:s})})]}),m=e.jsxs(n,{wrap:!0,children:[e.jsx(o,{size:"small",type:"tertiary",theme:"solid",onClick:d,children:l("取消全选")}),e.jsx(o,{size:"small",type:"primary",theme:"solid",onClick:r,children:l("加入预填组")}),e.jsx(o,{size:"small",type:"secondary",theme:"solid",onClick:c,children:l("复制名称")}),e.jsx(o,{size:"small",type:"danger",theme:"solid",onClick:i,children:l("删除所选")})]});M.info({id:Fe,title:t,content:m,duration:0,position:"bottom",showClose:!1})}else M.close(Fe)},[t,l,i,r,d,c]),s.useEffect(()=>()=>{M.close(Fe)},[]),null),{Text:qe}=a,De={description:"描述",icon:"图标",tags:"标签",vendor:"供应商",name_rule:"命名规则",status:"状态"},Be=Object.keys(De),Ge=({visible:t,onClose:a,conflicts:i=[],onSubmit:r,t:n,loading:o=!1})=>{const[m,p]=s.useState({}),h=ne(),[g,y]=s.useState(1),[f,j]=s.useState(""),v=e=>{if(null==e)return"-";if("string"==typeof e)return e||"-";try{return JSON.stringify(e,null,2)}catch(s){return String(e)}};s.useEffect(()=>{if(t){const e={};i.forEach(s=>{e[s.model_name]=new Set}),p(e),y(1),j("")}else p({})},[t,i]);const b=s.useCallback((e,s,t)=>{p(a=>{const l={...a},i=new Set(l[e]||[]);return t?i.add(s):i.delete(s),l[e]=i,l})},[]),w=s.useMemo(()=>(i||[]).map(e=>({key:e.model_name,model_name:e.model_name,fields:e.fields||[]})),[i]),_=s.useMemo(()=>{const e=(f||"").toLowerCase();return e?w.filter(s=>(s.model_name||"").toLowerCase().includes(e)):w},[w,f]),S=s.useCallback(e=>(_||[]).filter(s=>(s.fields||[]).some(s=>s.field===e)),[_]),C=s.useCallback(e=>{const s=S(e),t=s.filter(s=>m[s.model_name]?.has(e)).length,a=s.length;return{headerChecked:a>0&&t===a,headerIndeterminate:t>0&&t<a,hasAny:a>0}},[S,m]),N=s.useCallback((e,s)=>{p(t=>{const a={...t};return S(e).forEach(t=>{const l=new Set(a[t.model_name]||[]);s?l.add(e):l.delete(e),a[t.model_name]=l}),a})},[S]),k=s.useMemo(()=>[{title:n("模型"),dataIndex:"model_name",fixed:"left",render:s=>e.jsx(qe,{strong:!0,children:s})},...Be.map(s=>{const t=n(De[s]||s),{headerChecked:a,headerIndeterminate:i,hasAny:r}=C(s);return r?{title:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(T,{checked:a,indeterminate:i,onChange:e=>N(s,e?.target?.checked)}),e.jsx(qe,{children:t})]}),dataIndex:s,render:(t,a)=>{const i=(a.fields||[]).find(e=>e.field===s);if(!i)return e.jsx(qe,{type:"tertiary",children:"-"});const r=m[a.model_name]?.has(s)||!1;return e.jsx(T,{checked:r,onChange:e=>b(a.model_name,s,e?.target?.checked),children:e.jsx(I,{trigger:"hover",position:"top",content:e.jsxs("div",{className:"p-2 max-w-[520px]",children:[e.jsxs("div",{className:"mb-2",children:[e.jsx(qe,{type:"tertiary",size:"small",children:n("本地")}),e.jsx("pre",{className:"whitespace-pre-wrap m-0",children:v(i.local)})]}),e.jsxs("div",{children:[e.jsx(qe,{type:"tertiary",size:"small",children:n("官方")}),e.jsx("pre",{className:"whitespace-pre-wrap m-0",children:v(i.upstream)})]})]}),children:e.jsx(l,{color:"white",size:"small",prefixIcon:e.jsx(xe,{size:14}),children:n("点击查看差异")})})})}}:null}
1).filter(Boolean)],[n,m,_,C,N,b]),z=s.useMemo(()=>{const e=(g-1)*re,s=e+re;return _.slice(e,s)},[_,g]);return e.jsx(d,{title:n("选择要覆盖的冲突项"),visible:t,onCancel:a,onOk:async()=>{const e=Object.entries(m).map(([e,s])=>({model_name:e,fields:Array.from(s||[])})).filter(e=>e.fields.length>0);await(r?.(e))&&a?.()},confirmLoading:o,okText:n("应用覆盖"),cancelText:n("取消"),width:h?"100%":1e3,children:0===w.length?e.jsx(c,{description:n("无冲突项"),className:"p-6"}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"mb-3 text-[hsl(var(--muted-foreground))]",children:n("仅会覆盖你勾选的字段,未勾选的字段保持本地不变。")}),e.jsx("div",{className:"flex items-center justify-end gap-2 w-full mb-4",children:e.jsx(u,{placeholder:n("搜索模型..."),value:f,onChange:e=>{j(e),y(1)},className:"!w-full",prefix:e.jsx(oe,{size:16}),showClear:!0})}),_.length>0?e.jsx(x,{columns:k,dataSource:z,pagination:{currentPage:g,pageSize:re,total:_.length,showSizeChanger:!1,onPageChange:e=>y(e)},scroll:{x:"max-content"}}):e.jsx(c,{description:n(f?"未找到匹配的模型":"无冲突项"),className:"p-6"})]})})},He=({visible:t,onClose:a,onConfirm:l,loading:i,t:r})=>{const[n,c]=s.useState(0),[m,p]=s.useState("official"),[h,u]=s.useState("zh"),x=ne();return s.useEffect(()=>{t&&(c(0),p("official"),u("zh"))},[t]),e.jsxs(d,{title:r("同步向导"),visible:t,onCancel:a,footer:e.jsxs("div",{className:"flex justify-end",children:[1===n&&e.jsx(o,{onClick:()=>c(0),children:r("上一步")}),e.jsx(o,{onClick:a,children:r("取消")}),0===n&&e.jsx(o,{type:"primary",onClick:()=>c(1),disabled:"official"!==m,children:r("下一步")}),1===n&&e.jsx(o,{type:"primary",theme:"solid",loading:i,onClick:async()=>{await(l?.({option:m,locale:h}))},children:r("开始同步")})]}),width:x?"100%":"small",children:[e.jsx("div",{className:"mb-3",children:e.jsxs(O,{type:"basic",current:n,size:"small",children:[e.jsx(O.Step,{title:r("选择方式"),description:r("选择同步来源")}),e.jsx(O.Step,{title:r("选择语言"),description:r("选择同步语言")})]})}),0===n&&e.jsx("div",{className:"mt-2 flex justify-center",children:e.jsxs(V,{value:m,onChange:e=>p(e?.target?.value??e),type:"card",direction:"horizontal","aria-label":"同步方式选择",name:"sync-mode-selection",children:[e.jsx(A,{value:"official",extra:r("从官方模型库同步"),children:r("官方模型同步")}),e.jsx(A,{value:"config",extra:r("从配置文件同步"),disabled:!0,children:r("配置文件同步")})]})}),1===n&&e.jsxs("div",{className:"mt-2",children:[e.jsx("div",{className:"mb-2 text-[hsl(var(--muted-foreground))]",children:r("请选择同步语言")}),e.jsx("div",{className:"flex justify-center",children:e.jsxs(V,{value:h,onChange:e=>u(e?.target?.value??e),type:"card",direction:"horizontal","aria-label":"语言选择",name:"sync-locale-selection",children:[e.jsx(A,{value:"en",extra:"English",children:"EN"}),e.jsx(A,{value:"zh",extra:"中文",children:"ZH"}),e.jsx(A,{value:"ja",extra:"日本語",children:"JA"})]})})]})]})},We=({selectedKeys:t,setSelectedKeys:a,setEditingModel:l,setShowEdit:i,batchDeleteModels:r,syncing:n,previewing:c,syncUpstream:m,previewUpstreamDiff:p,applyUpstreamOverwrite:h,compactMode:u,setCompactMode:x,t:g})=>{const[y,f]=s.useState(!1),[j,v]=s.useState(!1),[b,w]=s.useState(!1),[_,S]=s.useState(!1),[C,N]=s.useState({id:void 0}),[k,z]=s.useState(!1),[M,T]=s.useState([]),[O,V]=s.useState(!1),[A,E]=s.useState("zh");return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap gap-2 w-full md:w-auto order-2 md:order-1",children:[e.jsx(o,{type:"primary",className:"flex-1 md:flex-initial",onClick:()=>{l({id:void 0}),i(!0)},size:"small",children:g("添加模型")}),e.jsx(o,{type:"secondary",className:"flex-1 md:flex-initial",size:"small",onClick:()=>v(!0),children:g("未配置模型")}),G()&&e.jsx(I,{position:"bottom",trigger:"hover",content:e.jsxs("div",{className:"p-2 max-w-[360px]",children:[e.jsx("div",{className:"text-[hsl(var(--muted-foreground))] text-sm",children:g("模型社区需要大家的共同维护,如发现数据有误或想贡献新的模型数据,请访问:")}),e.jsx("a",{href:"https://github.com/basellm/llm-metadata",target:"_blank",rel:"noreferrer",className:"text-blue-600 underline",children:"https://github.com/basellm/llm-metadata"})]}),children:e.jsx(o,{type:"secondary",className:"flex-1 md:flex-initial",size:"small",loading:n||c,onClick:()=>{E("zh"),V(!0)},children:g("同步")})}),e.jsx(o,{type:"secondary",className:"flex-1 md:flex-initial",size:"small",onClick:()=>w(!0),children:g("预填组管理")}),e.jsx(Re,{compactMode:u,setCompactMode:x,t:g})]}),e.jsx(Ue,{selectedKeys:t,t:g,onDelete:()=>{f(!0)},onAddPrefill:()=>{const e=t.map(e=>e.model_name);N({id:void 0,type:"model",items:e}),S(!0)},onClear:()=>{a([])},onCopy:async()=>{const e=t.map(e=>e.model_name).join(",");e&&(await H(e)?q(g("已复制模型名称")):D(g("复制失败")))}}),e.jsx(d,{title:g("批量删除模型"),visible:y,onCancel:()=>f(!1),onOk:()=>{r(),f(!1)},type:"warning",children:e.jsx("div",{children:g("确定要删除所选的 {{count}} 个模型吗?",{count:t.length})})}),e.jsx(He,{visible:O,onClose:()=>V(!1),loading:n||c,t:g,onConfirm:async({option:e,locale:s})=>{E(s),"official"===e&&await(async e=>{const s=await(p?.({locale:e})),t=s?.conflicts||[];if(t.length>0)return T(t),void z(!0);await(m?.({locale:e}))})(s),V(!1)}}),e.jsx(Te,{visible:j,onClose:()=>v(!1),onConfigureModel:e=>
1{l({id:void 0,model_name:e}),i(!0),v(!1)},t:g}),e.jsx(Ke,{visible:b,onClose:()=>w(!1)}),e.jsx($e,{visible:_,onClose:()=>S(!1),editingGroup:C,onSuccess:()=>S(!1)}),e.jsx(Ge,{visible:k,onClose:()=>z(!1),conflicts:M,onSubmit:async e=>await(h?.({overwrite:e,locale:A})),t:g,loading:n})]})},Ze=({formInitValues:t,setFormApi:a,searchModels:l,loading:i,searching:r,t:n})=>{const d=s.useRef(null);return e.jsx(g,{initValues:t,getFormApi:e=>{a(e),d.current=e},onSubmit:l,allowEmpty:!0,autoComplete:"off",layout:"horizontal",trigger:"change",stopValidateWithError:!1,className:"w-full md:w-auto order-1 md:order-2",children:e.jsxs("div",{className:"flex flex-col md:flex-row items-center gap-2 w-full md:w-auto",children:[e.jsx("div",{className:"relative w-full md:w-56",children:e.jsx(g.Input,{field:"searchKeyword",prefix:e.jsx(oe,{size:16}),placeholder:n("搜索模型名称"),showClear:!0,pure:!0,size:"small"})}),e.jsx("div",{className:"relative w-full md:w-56",children:e.jsx(g.Input,{field:"searchVendor",prefix:e.jsx(oe,{size:16}),placeholder:n("搜索供应商"),showClear:!0,pure:!0,size:"small"})}),e.jsxs("div",{className:"flex gap-2 w-full md:w-auto",children:[e.jsx(o,{type:"tertiary",htmlType:"submit",loading:i||r,className:"flex-1 md:flex-initial md:w-auto",size:"small",children:n("查询")}),e.jsx(o,{type:"tertiary",onClick:()=>{d.current&&(d.current.reset(),setTimeout(()=>{l()},100))},className:"flex-1 md:flex-initial md:w-auto",size:"small",children:n("重置")})]})]})})},Ye=({activeVendorKey:s,setActiveVendorKey:t,vendorCounts:a,vendors:i,loadModels:r,activePage:n,pageSize:c,setActivePage:m,setShowAddVendor:p,setShowEditVendor:h,setEditingVendor:u,loadVendors:x,t:g})=>e.jsxs(v,{activeKey:s,type:"card",collapsible:!0,onChange:e=>{t(e),m(1),r(1,c,e)},className:"mb-2",tabBarExtraContent:e.jsx(o,{type:"primary",size:"small",onClick:()=>p(!0),children:g("新增供应商")}),children:[e.jsx(b,{itemKey:"all",tab:e.jsxs("span",{className:"flex items-center gap-2",children:[g("全部"),e.jsx(l,{color:"all"===s?"red":"grey",shape:"circle",children:a.all||0})]})}),i.map(i=>{const m=String(i.id),p=a[i.id]||0;return e.jsx(b,{itemKey:m,tab:e.jsxs("span",{className:"flex items-center gap-2",children:[R(i.icon||"Layers",14),i.name,e.jsx(l,{color:s===m?"red":"grey",shape:"circle",children:p}),e.jsx(E,{trigger:"click",position:"bottomRight",render:e.jsxs(E.Menu,{children:[e.jsx(E.Item,{icon:e.jsx(ge,{size:16}),onClick:e=>((e,s)=>{s.stopPropagation(),u(e),h(!0)})(i,e),children:g("编辑")}),e.jsx(E.Item,{type:"danger",icon:e.jsx(ce,{size:16}),onClick:e=>{e.stopPropagation(),d.confirm({title:g("确认删除"),content:g('确定要删除供应商 "{{name}}" 吗?此操作不可撤销。',{name:i.name}),onOk:()=>(async(e,a)=>{a.stopPropagation();try{const a=await U.delete(`/api/vendors/${e.id}`);a.data.success?(q(g("供应商删除成功")),s===String(e.id)?(t("all"),r(1,c,"all")):r(n,c,s),x()):D(a.data.message||g("删除失败"))}catch(l){D(l.response?.data?.message||g("删除失败"))}})(i,e),okText:g("删除"),cancelText:g("取消"),type:"warning",okType:"danger"})},children:g("删除")})]}),onClickOutSide:e=>e.stopPropagation(),children:e.jsx(o,{size:"small",type:"tertiary",theme:"outline",onClick:e=>e.stopPropagation(),children:g("操作")})})]})},m)})]}),{Text:Qe,Title:Xe}=a,es={openai:{path:"/v1/chat/completions",method:"POST"},"openai-response":{path:"/v1/responses",method:"POST"},anthropic:{path:"/v1/messages",method:"POST"},gemini:{path:"/v1beta/models/{model}:generateContent",method:"POST"},"jina-rerank":{path:"/rerank",method:"POST"},"image-generation":{path:"/v1/images/generations",method:"POST"}},ss=[{label:"精确名称匹配",value:0},{label:"前缀名称匹配",value:1},{label:"包含名称匹配",value:2},{label:"后缀名称匹配",value:3}],ts=t=>{const{t:i}=B(),[r,d]=s.useState(!1),c=ne(),m=s.useRef(null),p=t.editingModel&&void 0!==t.editingModel.id,u=s.useMemo(()=>p?"right":"left",[p]),x=s.useMemo(()=>{const e=W();return e?i("edit_model_hint_002",{currencySymbol:e}):i("edit_model_hint_003")},[i]),f=(s,t)=>{if(null==s||""===s)return null;let a=!1;
1if("number"==typeof s)a=Number.isFinite(s)&&s>0;else if(s&&"object"==typeof s&&!Array.isArray(s))a=!0;else if("string"==typeof s){const e=s.trim();if(!e)return null;const t=Number(e);if(Number.isFinite(t)&&t>0)a=!0;else try{JSON.parse(e),a=!0}catch{a=!1}}if(!a)return e.jsx("div",{className:"rounded-lg px-3 py-2",style:{border:"1px solid hsl(var(--warning))",background:"hsl(var(--warning) / 0.12)"},children:e.jsx(Qe,{size:"small",style:{color:"hsl(var(--warning))"},children:i("输入有效 JSON 后,将在这里实时显示按 原始价格 x 汇率 x 2 换算后的保存结果。")})});const l=Q(s,t);return l?e.jsxs("div",{className:"rounded-lg px-3 py-2",style:{border:"1px solid hsl(var(--border))",background:"hsl(var(--foreground) / 0.02)"},children:[e.jsx(Qe,{type:"tertiary",size:"small",style:{display:"block",marginBottom:8},children:i("实时换算预览:按汇率 {{rate}} 换算后,保存时将写入以下值",{rate:Number(t)||1})}),e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap",wordBreak:"break-word",fontSize:12,lineHeight:1.6,color:"hsl(var(--foreground))"},children:l})]}):null},[j,v]=s.useState([]),[b,S]=s.useState([]),[k,z]=s.useState([]);s.useEffect(()=>{t.visiable&&((async()=>{try{const e=await U.get("/api/vendors/?page_size=1000");if(e.data.success){const s=e.data.data.items||e.data.data||[];v(Array.isArray(s)?s:[])}}catch(e){}})(),(async()=>{try{const[e,s]=await Promise.all([U.get("/api/prefill_group?type=tag"),U.get("/api/prefill_group?type=endpoint")]);e?.data?.success&&S(e.data.data||[]),s?.data?.success&&z(s.data.data||[])}catch(e){}})())},[t.visiable]);const M=()=>({model_name:t.editingModel?.model_name||"",description:"",icon:"",cover_image:"",preset_prompt:"",preset_image:"",example_output:"",example_output_type:"text",detail_image:"",tags:[],official_price:"",official_price_exchange_rate:1,model_type:"",vendor_id:void 0,vendor:"",vendor_icon:"",endpoints:"",name_rule:t.editingModel?.model_name?0:void 0,status:!0,sync_official:!0,show_in_square:!0,sort_order:0}),T=()=>{t.handleClose()};return s.useEffect(()=>{m.current&&(p||m.current.setValues({...M(),model_name:t.editingModel?.model_name||""}))},[t.editingModel?.id,t.editingModel?.model_name]),s.useEffect(()=>{t.visiable?p?(async()=>{if(p&&t.editingModel.id){d(!0);try{const e=await U.get(`/api/models/${t.editingModel.id}`),{success:s,message:a,data:l}=e.data;if(s){l.tags?l.tags=l.tags.split(",").filter(Boolean):l.tags=[],l.endpoints||(l.endpoints="");const e=Z(l.official_price);l.official_price_exchange_rate=e,l.official_price=Y(l.official_price,e),l.status=1===l.status,l.sync_official=1===(l.sync_official??1),l.show_in_square=1===(l.show_in_square??1),m.current&&m.current.setValues({...M(),...l})}else D(a)}catch(e){D(i("加载模型信息失败"))}d(!1)}})():m.current?.setValues({...M(),model_name:t.editingModel?.model_name||""}):m.current?.reset()},[t.visiable,t.editingModel?.id,t.editingModel?.model_name]),e.jsx(C,{placement:u,title:e.jsxs(n,{children:[p?e.jsx(l,{color:"blue",shape:"circle",children:i("更新")}):e.jsx(l,{color:"green",shape:"circle",children:i("新建")}),e.jsx(Xe,{heading:4,className:"m-0",children:i(p?"更新模型信息":"创建新的模型")})]}),bodyStyle:{padding:"0"},visible:t.visiable,width:c?"100%":600,footer:e.jsx("div",{className:"flex justify-end bg-white",children:e.jsxs(n,{children:[e.jsx(o,{theme:"solid",className:"!rounded-lg",onClick:()=>m.current?.submitForm(),icon:e.jsx(he,{size:16}),loading:r,children:i("提交")}),e.jsx(o,{theme:"light",className:"!rounded-lg",type:"primary",onClick:T,icon:e.jsx(ue,{size:16}),children:i("取消")})]})}),closeIcon:null,onCancel:()=>T(),children:e.jsx(h,{spinning:r,children:e.jsx(g,{initValues:M(),getFormApi:e=>m.current=e,onSubmit:async e=>{d(!0);try{const s={...e,tags:Array.isArray(e.tags)?e.tags.join(","):e.tags,official_price:Q(e.official_price,e.official_price_exchange_rate),cover_image:e.cover_image||"",preset_prompt:e.preset_prompt||"",preset_image:e.preset_image||"",example_output:e.example_output||"",example_output_type:e.example_output_type||"text",detail_image:e.detail_image||"",model_type:e.model_type||"",endpoints:e.endpoints||"",status:e.status?1:0,sync_official:e.sync_official?1:0,show_in_square:e.show_in_square?1:0,sort_order:Math.floor(Number(e.sort_order)||0)};if(p){s.id=t.editingModel.id;const e=await U.put("/api/models/",s),{success:a,message:l}=e.data;a?(q(i("模型更新成功!")),t.refresh(),t.handleClose()):D(i(l))}else{const e=await U.post("/api/models/",s),{success:a,message:l}=e.data;a?(q(i("模型创建成功!")),t.refresh(),t.handleClose()):D(i(l))}}catch(s){D(s.response?.data?.message||i("操作失败"))}d(!1),m.current?.setValues(M())},children:({values:s})=>e.jsxs("div",{className:"p-2",children:[e.jsxs(y,{className:"!rounded-2xl shadow-sm border-0",children:[e.jsxs("div",{className:"flex items-center mb-2",children:[e.jsx(N,{size:14,color:"green",className:"mr-2 shadow-md",children:e.jsx(ye,{size:16})}),e.jsxs("div",{children:[e.jsx(Qe,{className:"text-lg font-medium",children:i("基本信息")}),e.jsx("div",{className:"text-xs text-gray-600",children:i("设置模型的基本信息")})]})]}),e.jsxs(w,{gutter:12,children:[e.jsx(_,{span:24,children:e.jsx(g.Input,{field:"model_name",label:i("模型名称"),placeholder:i("请输入模型名称,如:gpt-4"),rules:[{required:!0,message:i("请输入模型名称")}],showClear:!0})}),e.jsx(_,{span:24,children:e.jsx(g.Select,{field:"name_rule",label:i("名称匹配类型"),placeholder:i("请选择名称匹配类型"),optionList:ss.map(e=>({label:i(e.label),value:e.value})),rules:[{required:!0,message:i("请选择名称匹配类型")}],extraText:i("根据模型名称和匹配规则查找模型元数据,优先级:精确 > 前缀 >
1 后缀 > 包含"),style:{width:"100%"}})}),e.jsx(_,{span:24,children:e.jsx(g.Input,{field:"icon",label:i("模型图标"),placeholder:i("请输入图标名称"),extraText:e.jsxs("span",{children:[i("edit_model_hint_001"),e.jsx(a.Text,{link:{href:"https://icons.lobehub.com/components/lobe-hub",target:"_blank"},icon:e.jsx(fe,{size:16}),underline:!0,children:i("请点击我")})]}),showClear:!0})}),e.jsx(_,{span:24,children:e.jsx(g.Slot,{label:i("封面图"),children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g.Input,{noLabel:!0,field:"cover_image",placeholder:i("输入图片 URL 或点击右侧上传"),style:{flex:1},showClear:!0}),e.jsx(P,{action:"/api/admin/upload-file",name:"file",accept:"image/*",showUploadList:!1,withCredentials:!0,maxSize:10240,onSuccess:e=>{const s=e?.data?.url||e?.url;s?m.current?.setValue("cover_image",s):$.error(i("上传失败"))},onError:()=>$.error(i("封面图上传失败,请确认已配置对象存储")),children:e.jsx(o,{icon:e.jsx(je,{size:14}),theme:"light",type:"tertiary",children:i("上传")})})]}),s.cover_image&&e.jsx("img",{src:s.cover_image,alt:"cover preview",style:{height:80,objectFit:"cover",borderRadius:8,border:"1px solid hsl(var(--border))"}}),e.jsx(a.Text,{type:"tertiary",size:"small",children:i("封面图将在模型广场卡片中展示,建议尺寸 16:9,最大 10MB")})]})})}),e.jsx(_,{span:24,children:e.jsx(g.TextArea,{field:"description",label:i("描述"),placeholder:i("请输入模型描述"),rows:3,showClear:!0})}),e.jsx(_,{span:24,children:e.jsxs("div",{className:"rounded-xl p-3",style:{border:"1px solid hsl(var(--border))",background:"hsl(var(--foreground) / 0.02)"},children:[e.jsx(Ve,{field:"official_price",label:i("官方价格"),placeholder:'{\n  "input": 0.005,\n  "output": 0.015\n}\n\n{\n  "price": 0.04\n}\n\n{\n  "base_price": 0.01\n}',value:s.official_price,onChange:e=>m.current?.setValue("official_price",e),formApi:m.current,editorType:"object",extraText:x,extraFooter:f(s.official_price,s.official_price_exchange_rate)}),e.jsx(J,{margin:"12px"}),e.jsx(g.InputNumber,{field:"official_price_exchange_rate",label:i("官方价格汇率"),placeholder:i("请输入汇率,默认 1"),min:0,step:.01,precision:6,extraText:i("默认值为 1。官方原价为人民币时填 1;若官方原价为美元或其他币种,请填写换算到人民币的汇率。"),style:{width:"100%"}})]})}),e.jsx(_,{span:24,children:e.jsx(g.TagInput,{field:"tags",label:i("标签"),placeholder:i('输入标签或使用","分隔多个标签'),addOnBlur:!0,showClear:!0,onChange:e=>{if(!m.current)return;const s=(t=e,Array.isArray(t)?[...new Set(t.flatMap(e=>e.split(",").map(e=>e.trim()).filter(Boolean)))]:[]);var t;m.current.setValue("tags",s)},style:{width:"100%"},...b.length>0&&{extraText:e.jsx(n,{wrap:!0,children:b.map(s=>e.jsx(o,{size:"small",type:"primary",onClick:()=>{if(m.current){const e=[...m.current.getValue("tags")||[],...s.items||[]],t=[...new Set(e)];m.current.setValue("tags",t)}},children:s.name},s.id))})}})}),e.jsx(_,{span:24,children:e.jsx(g.Input,{field:"model_type",label:i("模型类型"),placeholder:i("输入模型类型,如:对话、图像、视频等"),showClear:!0,extraText:i("设置模型的功能类型,用于分类筛选"),style:{width:"100%"}})}),e.jsx(_,{span:24,children:e.jsx(g.Select,{field:"vendor_id",label:i("供应商"),placeholder:i("选择模型供应商"),optionList:j.map(e=>({label:e.name,value:e.id})),filter:!0,showClear:!0,onChange:e=>{const s=j.find(s=>s.id===e);s&&m.current&&m.current.setValue("vendor",s.name)},style:{width:"100%"}})}),e.jsx(_,{span:24,children:e.jsx(Ve,{field:"endpoints",label:i("端点映射"),placeholder:'{\n  "openai": {"path": "/v1/chat/completions", "method": "POST"}\n}',value:s.endpoints,onChange:e=>m.current?.setValue("endpoints",e),formApi:m.current,editorType:"object",template:es,templateLabel:i("填入模板"),extraText:i("留空则使用默认端点;支持 {path, method}"),extraFooter:k.length>0&&e.jsx(n,{wrap:!0,children:k.map(s=>e.jsx(o,{size:"small",type:"primary",onClick:()=>{try{const e=m.current?.getValue("endpoints")||"";let t={};e&&e.trim()&&(t=JSON.parse(e));const a="string"==typeof s.items?JSON.parse(s.items||"{}"):s.items||{},l={...t,...a};m.current?.setValue("endpoints",JSON.stringify(l,null,2))}catch(e){try{const e="string"==typeof s.items?JSON.parse(s.items||"{}"):s.items||{};m.current?.setValue("endpoints",JSON.stringify(e,null,2))}catch{}}},children:s.name},s.id))})})}),e.jsx(_,{span:24,children:e.jsx(g.Switch,{field:"sync_official",label:i("参与官方同步"),extraText:i("关闭后,此模型将不会被“同步官方”自动覆盖或创建"),size:"large"})}),e.jsx(_,{span:24,children:e.jsx(g.Switch,{field:"show_in_square",label:i("模型广场显示"),extraText:i("控制该模型是否在模型广场(定价页面)中显示"),size:"large"})}),e.jsx(_,{span:24,children:e.jsx(g.Switch,{field:"status",label:i("状态"),size:"large"})}),e.jsx(_,{span:24,children:e.jsx(g.InputNumber,{field:"sort_order",label:i("排序"),placeholder:i("请输入排序值,数值越大越靠前"),extraText:i("排序值越大,模型在列表中越靠前。默认值为0"),min:0,step:1,precision:0,style:{width:"100%"}})})]})]}),e.jsxs(y,{className:"!rounded-2xl shadow-sm border-0 mt-3",children:[e.jsxs("div",{className:"flex items-center mb-4",children:[e.jsx(N,{size:14,color:"violet",className:"mr-2 shadow-md",children:e.jsx(ve,{size:16})}),e.jsxs("div",{children:[e.jsx(Qe,{className:"text-lg font-medium",children:i("模型体验预设")}),e.jsx("div",{className:"text-xs text-gray-600",children:i("配置模型体验页面的预设提示词、参考图和示例输出")})]})]}),e.jsxs(w,{gutter:12,children:[e.jsx(_,{span:24,children:e.jsx(g.TextArea,{field:"preset_prompt",label:i("预设提示词"),placeholder:i("在模型体验页面自动填入此提示词,留空则使用系统默认"),rows:3,showClear:!0})}),e.jsx(_,{span:24,children:e.jsx(g.Slot,{label:i("预设参考图"),children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g.Input,{noLabel:!0,field:"preset_image",placeholder:i("输入图片 URL 或点击右侧上传(图生视频/图片编辑模型适用)"),style:{flex:1},showClear:!0}),e.jsx(P,{action:"/api/admin/upload-file",name:"file",accept:"image/*",showUploadList:!1,withCredentials:!0,maxSize:10240,onSuccess:e=>{const s=e?.data?.url||e?.url;s?m.current?.setValue("preset_image",s):$.error(i("上传失败"))},onError:()=>$.error(i("图片上传失败,请确认已配置对象存储")),children:e.jsx(o,{icon:e.jsx(je,{size:14}),theme:"light",type:"tertiary",children:i("上传")})})]}),s.preset_image&&e.jsx("img",{src:s.preset_image,alt:"preset preview",style:{height:64,objectFit:"cover",borderRadius:8,border:"1px solid hsl(var(--border))"}}),e.jsx(a.Text,{type:"tertiary",size:"small",children:i("图生视频或图片编辑模型可在体验页面预加载此参考图")})]})})}),e.jsx(_,{span:24,children:e.jsx(g.Select,{field:"example_output_type",label:i("示例输出类型"),placeholder:i("选择示例输出的内容类型"),optionList:[{label:i("文字"),value:"text"},{label:i("图片"),value:"image"},{label:i("视频"),value:"video"}],style:{width:"100%"}})}),e.jsx(_,{span:24,children:"image"===s.example_output_type||"video"===s.example_output_type?e.jsx(g.Slot,{label:i("示例输出"),
1children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g.Input,{noLabel:!0,field:"example_output",placeholder:"image"===s.example_output_type?i("输入示例图片 URL 或上传"):i("输入示例视频 URL"),style:{flex:1},showClear:!0}),"image"===s.example_output_type&&e.jsx(P,{action:"/api/admin/upload-file",name:"file",accept:"image/*",showUploadList:!1,withCredentials:!0,maxSize:10240,onSuccess:e=>{const s=e?.data?.url||e?.url;s?m.current?.setValue("example_output",s):$.error(i("上传失败"))},onError:()=>$.error(i("图片上传失败")),children:e.jsx(o,{icon:e.jsx(je,{size:14}),theme:"light",type:"tertiary",children:i("上传")})})]}),s.example_output&&"image"===s.example_output_type&&e.jsx("img",{src:s.example_output,alt:"example output",style:{height:80,objectFit:"cover",borderRadius:8,border:"1px solid hsl(var(--border))"}}),e.jsx(a.Text,{type:"tertiary",size:"small",children:"image"===s.example_output_type?i("将在模型体验页面输出区展示此示例图片"):i("将在模型体验页面输出区展示此示例视频")})]})}):e.jsx(g.TextArea,{field:"example_output",label:i("示例输出(文字)"),placeholder:i("输入示例文字输出,支持 Markdown 格式,将在体验页面预览区展示"),rows:5,showClear:!0})}),e.jsx(_,{span:24,children:e.jsx(g.Slot,{label:i("详情描述图"),extraText:i("在模型体验页底部展示,支持多张图片(逗号分隔多个 URL),用于展示模型能力说明"),children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g.Input,{noLabel:!0,field:"detail_image",placeholder:i("输入图片 URL,多张用英文逗号分隔;或点击右侧上传"),style:{flex:1},showClear:!0}),e.jsx(P,{action:"/api/admin/upload-file",name:"file",accept:"image/*",showUploadList:!1,withCredentials:!0,maxSize:20480,onSuccess:e=>{const s=e?.data?.url||e?.url;if(s){const e=m.current?.getValue("detail_image")||"",t=e?`${e},${s}`:s;m.current?.setValue("detail_image",t)}else $.error(i("上传失败"))},onError:()=>$.error(i("图片上传失败,请确认已配置对象存储")),children:e.jsx(o,{icon:e.jsx(je,{size:14}),theme:"light",type:"tertiary",children:i("上传")})})]}),s.detail_image&&e.jsx("div",{className:"flex flex-wrap gap-2",children:s.detail_image.split(",").filter(Boolean).map((t,a)=>e.jsxs("div",{className:"relative group",children:[e.jsx("img",{src:t.trim(),alt:`detail-${a}`,style:{height:72,maxWidth:180,objectFit:"cover",borderRadius:8,border:"1px solid hsl(var(--border))"}}),e.jsx("button",{type:"button",onClick:()=>{const e=s.detail_image.split(",").filter((e,s)=>s!==a);m.current?.setValue("detail_image",e.join(","))},className:"absolute top-1 right-1 w-4 h-4 bg-red-500 text-white rounded-full text-[10px] items-center justify-center hidden group-hover:flex",children:"✕"})]},a))})]})})})]})]})]})},p?"edit":"new")})})},as=({visible:t,handleClose:l,refresh:i,editingVendor:r})=>{const{t:n}=B(),[o,c]=s.useState(!1),m=s.useRef(null),p=ne(),h=r&&void 0!==r.id;return s.useEffect(()=>{t?h?(async()=>{if(h&&r.id){c(!0);try{const e=await U.get(`/api/vendors/${r.id}`),{success:s,message:t,data:a}=e.data;s?(a.status=1===a.status,m.current&&m.current.setValues({name:"",description:"",icon:"",status:!0,priority:0,...a})):D(t)}catch(e){D(n("加载供应商信息失败"))}c(!1)}})():m.current?.setValues({name:"",description:"",icon:"",status:!0,priority:0}):m.current?.reset()},[t,r?.id]),e.jsx(d,{title:n(h?"编辑供应商":"新增供应商"),visible:t,onOk:()=>m.current?.submitForm(),onCancel:()=>{l(),m.current?.reset()},confirmLoading:o,size:p?"full-width":"small",children:e.jsx(g,{initValues:{name:"",description:"",icon:"",status:!0,priority:0},getFormApi:e=>m.current=e,onSubmit:async e=>{c(!0);try{const s={...e,status:e.status?1:0};if(h){s.id=r.id;const e=await U.put("/api/vendors/",s),{success:t,message:a}=e.data;t?(q(n("供应商更新成功!")),i(),l()):D(n(a))}else{const e=await U.post("/api/vendors/",s),{success:t,message:a}=e.data;t?(q(n("供应商创建成功!")),i(),l()):D(n(a))}}catch(s){D(s.response?.data?.message||n("操作失败"))}c(!1)},children:e.jsxs(w,{gutter:12,children:[e.jsx(_,{span:24,children:e.jsx(g.Input,{field:"name",label:n("供应商名称"),placeholder:n("请输入供应商名称,如:OpenAI"),rules:[{required:!0,message:n("请输入供应商名称")}],showClear:!0})}),e.jsx(_,{span:24,children:e.jsx(g.TextArea,{field:"description",label:n("描述"),placeholder:n("请输入供应商描述"),rows:3,showClear:!0})}),e.jsx(_,{span:24,children:e.jsx(g.Input,{field:"icon",label:n("供应商图标"),placeholder:n("请输入图标名称"),extraText:e.jsxs("span",{children:[n("edit_model_hint_001"),e.jsx(a.Text,{link:{href:"https://icons.lobehub.com/components/lobe-hub",target:"_blank"},icon:e.jsx(fe,{size:16}),underline:!0,children:n("请点击我")})]}),showClear:!0})}),e.jsx(_,{span:24,children:e.jsx(g.InputNumber,{field:"priority",label:n("优先级"),placeholder:n("请输入优先级,数值越大越靠前"),initValue:0,min:0,extraText:n("优先级用于控制供应商的显示顺序,数值越大越靠前"),showClear:!0})}),e.jsx(_,{span:24,children:e.jsx(g.Switch,{field:"status",label:n("状态"),initValue:!0})})]})})})},ls=()=>{const a=(()=>{const{t:e}=B(),[t,a]=function(e="global"){const[t,a]=s.useState(()=>X(e)),l=s.useCallback(s=>{a(s),ee(s,e)},[e]);return s.useEffect(()=>{const s=s=>{if(s.key===se)try{const t=JSON.parse(s.newValue||"{}");a(!!t[e])}catch{}};
1return window.addEventListener("storage",s),()=>window.removeEventListener("storage",s)},[e]),[t,l]}("models"),[l,i]=s.useState([]),[r,n]=s.useState(!0),[o,d]=s.useState(1),[c,m]=s.useState(te),[p,h]=s.useState(!1),[u,x]=s.useState(0),g=s.useRef(!1),[y,f]=s.useState(!1),[j,v]=s.useState({id:void 0}),[b,w]=s.useState([]),_={getCheckboxProps:e=>({name:e.model_name}),selectedRowKeys:b.map(e=>e.id),onChange:(e,s)=>{w(s)}},S={searchKeyword:"",searchVendor:""},C=e=>{const s=e?.items||e||[];return Array.isArray(s)?s:[]},[N,k]=s.useState(null),z=()=>N?.getValues()||S,M=e=>{for(let s=0;s<e.length;s++)e[s].key=e[s].id;i(e)},[T,I]=s.useState([]),[O,V]=s.useState({}),[A,E]=s.useState("all"),[P,$]=s.useState(!1),[J,L]=s.useState(!1),[K,R]=s.useState({id:void 0}),[F,G]=s.useState(!1),[H,W]=s.useState(!1),Z=s.useMemo(()=>{const e={};return T.forEach(s=>{e[s.id]=s}),e},[T]),Y=async()=>{try{const e=await U.get("/api/vendors/?page_size=1000");if(e.data.success){const s=e.data.data.items||e.data.data||[];I(Array.isArray(s)?s:[])}}catch(e){}},Q=async(s=1,t=c,a=A)=>{n(!0);try{let e=`/api/models/?p=${s}&page_size=${t}`;a&&"all"!==a&&(e=`/api/models/search?vendor=${a}&p=${s}&page_size=${t}`);const l=await U.get(e),{success:r,message:n,data:o}=l.data;if(r){const e=C(o);if(d(o.page||s),x(o.total||e.length),M(e),o.vendor_counts){const e=Object.values(o.vendor_counts).reduce((e,s)=>e+s,0);V({...o.vendor_counts,all:e})}}else D(n),i([])}catch(l){console.error(l),D(e("获取模型列表失败")),i([])}n(!1)},ae=async(s=o)=>{const{searchKeyword:t="",searchVendor:a=""}=z(),l=a||("all"!==A?A:"");if(""!==t||""!==l){h(!0);try{const e=await U.get(`/api/models/search?keyword=${encodeURIComponent(t)}&vendor=${encodeURIComponent(l)}&p=${s}&page_size=${c}`),{success:a,message:r,data:n}=e.data;if(a){const e=C(n);if(d(n.page||s),x(n.total||e.length),M(e),n.vendor_counts){const e=Object.values(n.vendor_counts).reduce((e,s)=>e+s,0);V({...n.vendor_counts,all:e})}}else D(r),i([])}catch(r){console.error(r),D(e("刷新模型失败")),i([])}h(!1)}else await Q(s,c,A)},le=async(s=1,t=c)=>{const{searchKeyword:a="",searchVendor:l=""}=z(),r=l||("all"!==A?A:"");if(""!==a||""!==r){h(!0);try{const e=await U.get(`/api/models/search?keyword=${encodeURIComponent(a)}&vendor=${encodeURIComponent(r)}&p=${s}&page_size=${t}`),{success:l,message:n,data:o}=e.data;if(l){const e=C(o);if(d(o.page||s),x(o.total||e.length),M(e),o.vendor_counts){const e=Object.values(o.vendor_counts).reduce((e,s)=>e+s,0);V({...o.vendor_counts,all:e})}}else D(n),i([])}catch(n){console.error(n),D(e("搜索模型失败")),i([])}h(!1)}else await Q(s,t,A)};return s.useEffect(()=>{Q(1,c,A)},[A]),s.useEffect(()=>{(async()=>{await Y()})()},[]),{models:l,loading:r,searching:p,activePage:o,pageSize:c,modelCount:u,selectedKeys:b,rowSelection:_,handleRow:(e,s)=>({...1!==e.status?{style:{background:"hsl(var(--border))"}}:{},onClick:s=>{if(s.target.closest("button, .semi-button"))return;const t=b.some(s=>s.id===e.id)?b.filter(s=>s.id!==e.id):[...b,e];w(t)}}),setSelectedKeys:w,showEdit:y,editingModel:j,setEditingModel:v,setShowEdit:f,closeEdit:()=>{f(!1),setTimeout(()=>{v({id:void 0})},500)},formInitValues:S,setFormApi:k,loadModels:Q,searchModels:le,refresh:ae,manageModel:async(s,t,a)=>{let l;switch(t){case"delete":l=await U.delete(`/api/models/${s}`);break;case"enable":l=await U.put("/api/models/?status_only=true",{id:s,status:1});break;case"disable":l=await U.put("/api/models/?status_only=true",{id:s,status:0});break;default:return}const{success:r,message:n}=l.data;r?(q(e("操作成功完成!")),"delete"===t?await ae():i(e=>e.map(e=>e.id===s?{...e,status:"enable"===t?1:0}:e))):D(n)},batchDeleteModels:async()=>{if(0!==b.length)try{const s=b.map(e=>U.delete(`/api/models/${e.id}`)),t=await Promise.all(s);let a=0;t.forEach((e,s)=>{e.data.success?a++:D(`删除模型 ${b[s].model_name} 失败: ${e.data.message}`)}),a>0&&(q(e("成功删除 {{count}} 个模型",{count:a})),w([]),await ae())}catch(s){D(e("批量删除失败"))}else D(e("请至少选择一个模型"))},copyText:async s=>{try{await navigator.clipboard.writeText(s),q(e("复制成功"))}catch(t){console.error("Copy failed:",t),D(e("复制失败"))}}
1,setActivePage:d,handlePageChange:e=>{if(g.current)return;d(e);const{searchKeyword:s="",searchVendor:t=""}=z();""!==s||""!==(t||("all"!==A?A:""))?le(e,c):Q(e,c,A)},handlePageSizeChange:async e=>{m(e),d(1),g.current=!0;const{searchKeyword:s="",searchVendor:t=""}=z(),a=t||("all"!==A?A:"");try{""!==s||""!==a?await le(1,e):await Q(1,e,A)}finally{g.current=!1}},compactMode:t,setCompactMode:a,vendors:T,vendorMap:Z,vendorCounts:O,activeVendorKey:A,setActiveVendorKey:E,showAddVendor:P,setShowAddVendor:$,showEditVendor:J,setShowEditVendor:L,editingVendor:K,setEditingVendor:R,loadVendors:Y,t:e,syncing:F,previewing:H,syncUpstream:async(s={})=>{const t=s?.locale;G(!0);try{const s={};t&&(s.locale=t);const a=await U.post("/api/models/sync_upstream",s),{success:l,message:i,data:r}=a.data||{};if(l){const s=r?.created_models||0,t=r?.created_vendors||0,a=(r?.skipped_models||[]).length||0;q(e(`已同步:新增 ${s} 模型,新增 ${t} 供应商,跳过 ${a} 项`)),await Y(),await ae()}else D(i||e("同步失败"))}catch(a){D(e("同步失败"))}G(!1)},previewUpstreamDiff:async(s={})=>{const t=s?.locale;W(!0);try{const s="/api/models/sync_upstream/preview"+(t?`?locale=${t}`:""),a=await U.get(s),{success:l,message:i,data:r}=a.data||{};return l?r||{missing:[],conflicts:[]}:(D(i||e("预览失败")),{missing:[],conflicts:[]})}catch(a){return D(e("预览失败")),{missing:[],conflicts:[]}}finally{W(!1)}},applyUpstreamOverwrite:async(s=[])=>{const t=Array.isArray(s),a=t?s:s.overwrite||[],l=t?void 0:s.locale;G(!0);try{const s={overwrite:a};l&&(s.locale=l);const t=await U.post("/api/models/sync_upstream",s),{success:i,message:r,data:n}=t.data||{};if(i){const s=n?.created_models||0,t=n?.updated_models||0,a=n?.created_vendors||0,l=(n?.skipped_models||[]).length||0;return q(e(`完成:新增 ${s} 模型,更新 ${t} 模型,新增 ${a} 供应商,跳过 ${l} 项`)),await Y(),await ae(),!0}return D(r||e("同步失败")),!1}catch(i){return D(e("同步失败")),!1}finally{G(!1)}}}})(),l=ne(),{showEdit:i,editingModel:r,closeEdit:n,refresh:o,selectedKeys:d,setSelectedKeys:c,setEditingModel:m,setShowEdit:p,batchDeleteModels:h,formInitValues:u,setFormApi:x,searchModels:g,loading:y,searching:f,compactMode:j,setCompactMode:v,showAddVendor:b,setShowAddVendor:w,showEditVendor:_,setShowEditVendor:S,editingVendor:C,setEditingVendor:N,loadVendors:k,t:z}=a;return e.jsxs(e.Fragment,{children:[e.jsx(ts,{refresh:o,editingModel:r,visiable:i,handleClose:n}),e.jsx(as,{visible:b||_,handleClose:()=>{w(!1),S(!1),N({id:void 0})},editingVendor:_?C:{id:void 0},refresh:()=>{k(),o()}}),e.jsx(t,{type:"type3",tabsArea:e.jsx(Ye,{...a}),actionsArea:e.jsxs("div",{className:"flex flex-col md:flex-row justify-between items-center gap-2 w-full",children:[e.jsx(We,{selectedKeys:d,setSelectedKeys:c,setEditingModel:m,setShowEdit:p,batchDeleteModels:h,syncing:a.syncing,syncUpstream:a.syncUpstream,previewing:a.previewing,previewUpstreamDiff:a.previewUpstreamDiff,applyUpstreamOverwrite:a.applyUpstreamOverwrite,compactMode:j,setCompactMode:v,t:z}),e.jsx("div",{className:"w-full md:w-full lg:w-auto order-1 md:order-2",children:e.jsx(Ze,{formInitValues:u,setFormApi:x,searchModels:g,loading:y,searching:f,t:z})})]}),paginationArea:ae({currentPage:a.activePage,pageSize:a.pageSize,total:a.modelCount,onPageChange:a.handlePageChange,onPageSizeChange:a.handlePageSizeChange,isMobile:l,t:a.t}),t:a.t,children:e.jsx(Me,{...a})})]})},is=()=>e.jsx("div",{className:"px-2",children:e.jsx(ls,{})});export{is as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.