3 lines
9.8 KiB
JavaScript
3 lines
9.8 KiB
JavaScript
import{d as se,o as ae,w as ne,b as a,c as n,u as j,e as ie,f,F as O,g as t,t as i,r as le,n as $,h as y,j as g,i as h,q as A,s as M,T as N,k as d,x as B,m as re}from"./runtime-dom.esm-bundler.js";import{S as de,u as ue}from"./SecondaryGate.js";import{_ as ce}from"./_plugin-vue_export-helper.js";const ve={class:"page-header"},pe={class:"actions"},me=["disabled"],fe={key:0,class:"panel"},ye={class:"error"},ge={key:1,class:"panel"},he={class:"tool-list-header"},we={class:"muted"},ke={key:0,class:"empty"},be={class:"tool-grid"},_e=["onClick"],Ce={class:"tool-card-title"},xe={class:"tag"},je={class:"desc"},$e={class:"meta"},Te={class:"files"},Ie={key:2,class:"editor-page"},Ue={class:"editor-page-header"},Se={key:0,class:"status"},Ve={key:1,class:"status error"},Ee={key:0,class:"editor-panel"},Re={class:"drawer-header"},De={class:"drawer-actions"},Pe=["disabled"],Oe={class:"tabs"},Ae={class:"editor"},Me={key:1,class:"empty"},Ne={key:0,class:"modal-backdrop"},Be={class:"modal"},Fe={class:"modal-actions"},Le=["disabled"],ze={key:0,class:"modal-backdrop"},qe={class:"modal"},Je={class:"delete-tip"},Ze={class:"modal-actions"},Ge=["disabled"],He=se({__name:"CustomToolsApp",setup(Qe){const{verified:v,configured:F,loading:L,error:z,check:P,verify:q}=ue(),w=d([]),k=d(!1),r=d(""),u=d(null),b=d(""),D=d(!1),c=d("definition"),T=d(!1),I=d(!1),U=d(!1),S=d(!1),V=d(!1),_=d(""),p=B({id:"",description:""}),l=B({definition:"",execution:"",return:"",meta:""}),m=async()=>{if(v.value){k.value=!0,r.value="";try{const e=await(await fetch("/api/admin/custom-tools",{credentials:"same-origin"})).json();if(!e.success)throw new Error(e.error||"加载失败");if(w.value=(e.data||[]).map(o=>({...o,execution_file:o.execution&&o.execution.file||"execution.py",return_file:o.return?"return.json":"(无返回层)"})),b.value){const o=w.value.find(C=>C.id===b.value);o?await J(o):r.value=`未找到工具 ${b.value}`,b.value=""}}catch(s){r.value=s.message}finally{k.value=!1}}},J=async s=>{u.value=s,c.value="definition",await G(s.id)},Z=s=>{const e=`/admin/custom-tools?tool=${encodeURIComponent(s.id)}`;window.open(e,"_blank","noopener")},G=async s=>{if(v.value)try{l.definition=await E(`/api/admin/custom-tools/file?id=${encodeURIComponent(s)}&name=definition.json`),l.execution=await E(`/api/admin/custom-tools/file?id=${encodeURIComponent(s)}&name=execution.py`),l.return=await E(`/api/admin/custom-tools/file?id=${encodeURIComponent(s)}&name=return.json`,""),l.meta=await E(`/api/admin/custom-tools/file?id=${encodeURIComponent(s)}&name=meta.json`,"")}catch(e){r.value=e.message}},E=async(s,e="")=>{const o=await fetch(s,{credentials:"same-origin"});return o.status===404?e:await o.text()||e},H=async()=>{if(v.value&&u.value){T.value=!0;try{await R(u.value.id,"definition.json",l.definition),await R(u.value.id,"execution.py",l.execution),await R(u.value.id,"return.json",l.return),await R(u.value.id,"meta.json",l.meta),await K(),await m()}catch(s){r.value=s.message}finally{T.value=!1}}},R=async(s,e,o)=>{const x=await(await fetch("/api/admin/custom-tools/file",{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:s,name:e,content:o})})).json();if(!x.success)throw new Error(x.error||`保存 ${e} 失败`)},K=async()=>{await fetch("/api/admin/custom-tools/reload",{method:"POST",credentials:"same-origin"})},Q=s=>{const e=u.value;e&&(_.value=e.id,S.value=!0)},W=async()=>{if(v.value&&_.value){V.value=!0;try{const e=await(await fetch(`/api/admin/custom-tools?id=${encodeURIComponent(_.value)}`,{method:"DELETE",credentials:"same-origin"})).json();if(!e.success)throw new Error(e.error||"删除失败");u.value=null,S.value=!1,_.value="",await m()}catch(s){r.value=s.message}V.value=!1}},X=()=>{p.id="",p.description="",I.value=!0},Y=async()=>{if(!v.value)return;const s=p.id.trim();if(!s){r.value="请填写工具 ID";return}if(!/^[A-Za-z][A-Za-z0-9_-]*$/.test(s)){r.value="工具 ID 需以字母开头,可包含字母/数字/_/-";return}U.value=!0;try{const o={id:s,description:p.description,parameters:{type:"object",properties:{},required:[]},execution_code:`print('hello')
|
||
`,category:"custom"},x=await(await fetch("/api/admin/custom-tools",{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)})).json();if(!x.success)throw new Error(x.error||"创建失败");I.value=!1,u.value=null,await m(),window.location.href=`/admin/custom-tools?tool=${encodeURIComponent(s)}`}catch(o){r.value=o.message}finally{U.value=!1}},ee=()=>{window.location.href="/admin/custom-tools"},te=s=>{var o;const e=((o=s.parameters)==null?void 0:o.properties)||{};return Object.keys(e).length},oe=async s=>{await q(s),v.value&&await m()};return ae(async()=>{const e=new URLSearchParams(window.location.search).get("tool");e&&(b.value=e,D.value=!0),await P(),v.value&&await m()}),ne(v,async s=>{s&&await m()}),(s,e)=>(a(),n("div",{class:$(["custom-tools-page",{"editor-only":D.value}])},[j(v)?f("",!0):(a(),ie(de,{key:0,configured:j(F),loading:j(L),error:j(z),description:"输入管理员二级密码后可管理自定义工具。",onVerify:oe,onRecheck:j(P)},null,8,["configured","loading","error","onRecheck"])),D.value?(a(),n("section",Ie,[t("div",Ue,[e[18]||(e[18]=t("div",{class:"breadcrumbs"},[t("a",{class:"ghost",href:"/admin/custom-tools"},"返回列表")],-1)),k.value?(a(),n("div",Se,"加载中...")):r.value?(a(),n("div",Ve,i(r.value),1)):f("",!0)]),u.value?(a(),n("div",Ee,[t("header",Re,[t("div",null,[t("h3",null,i(u.value.id),1),t("p",null,i(u.value.description||"未填写描述"),1)]),t("div",De,[t("button",{type:"button",class:"primary",onClick:H,disabled:T.value},i(T.value?"保存中...":"保存"),9,Pe),t("button",{type:"button",class:"danger",onClick:e[0]||(e[0]=o=>Q())},"删除"),t("button",{type:"button",class:"ghost",onClick:ee},"关闭")])]),t("div",Oe,[t("button",{class:$({active:c.value==="definition"}),onClick:e[1]||(e[1]=o=>c.value="definition")}," definition.json ",2),t("button",{class:$({active:c.value==="execution"}),onClick:e[2]||(e[2]=o=>c.value="execution")}," execution.py ",2),t("button",{class:$({active:c.value==="return"}),onClick:e[3]||(e[3]=o=>c.value="return")},"return.json",2),t("button",{class:$({active:c.value==="meta"}),onClick:e[4]||(e[4]=o=>c.value="meta")},"meta.json",2)]),t("div",Ae,[c.value==="definition"?y((a(),n("textarea",{key:0,"onUpdate:modelValue":e[5]||(e[5]=o=>l.definition=o),spellcheck:"false"},null,512)),[[g,l.definition]]):c.value==="execution"?y((a(),n("textarea",{key:1,"onUpdate:modelValue":e[6]||(e[6]=o=>l.execution=o),spellcheck:"false"},null,512)),[[g,l.execution]]):c.value==="return"?y((a(),n("textarea",{key:2,"onUpdate:modelValue":e[7]||(e[7]=o=>l.return=o),spellcheck:"false"},null,512)),[[g,l.return]]):y((a(),n("textarea",{key:3,"onUpdate:modelValue":e[8]||(e[8]=o=>l.meta=o),spellcheck:"false"},null,512)),[[g,l.meta]])]),e[19]||(e[19]=t("div",{class:"hint"},[t("p",null,[h(" 提示:execution.py 中的字典/集合需要用 "),t("code",null,"{{ ... }}"),h(" 包裹,避免被模板替换。 ")]),t("p",null,"保存后无需重启,系统会自动 reload 自定义工具。")],-1))])):r.value?f("",!0):(a(),n("div",Me,"正在加载工具..."))])):(a(),n(O,{key:1},[t("header",ve,[e[16]||(e[16]=t("div",null,[t("h1",null,"自定义工具管理"),t("p",null,"每个工具一个文件夹,三层文件独立存放;仅管理员可见并可调用。")],-1)),t("div",pe,[t("button",{type:"button",class:"primary",onClick:X},"新建工具"),t("button",{type:"button",class:"ghost",onClick:m,disabled:k.value},i(k.value?"刷新中...":"刷新列表"),9,me),e[13]||(e[13]=t("a",{class:"ghost",href:"/static/custom_tools/guide.html",target:"_blank",rel:"noopener"},"查看开发指南",-1)),e[14]||(e[14]=t("a",{class:"ghost",href:"/admin/monitor",target:"_blank",rel:"noopener"},"返回监控",-1)),e[15]||(e[15]=t("a",{class:"ghost",href:"/admin/policy",target:"_blank",rel:"noopener"},"策略配置",-1))])]),r.value?(a(),n("section",fe,[t("p",ye,"加载失败:"+i(r.value),1)])):(a(),n("section",ge,[t("div",he,[e[17]||(e[17]=t("h2",null,"工具列表",-1)),t("span",we,"共 "+i(w.value.length)+" 个",1)]),w.value.length?f("",!0):(a(),n("div",ke,"暂无自定义工具")),t("div",be,[(a(!0),n(O,null,le(w.value,o=>(a(),n("div",{key:o.id,class:"tool-card",onClick:C=>Z(o)},[t("div",Ce,[t("strong",null,i(o.id),1),t("span",xe,i(o.category||"custom"),1)]),t("p",je,i(o.description||"暂无描述"),1),t("div",$e,[t("span",null,"参数:"+i(te(o))+" 个",1),t("span",null,"超时:"+i(o.timeout||30)+"s",1)]),t("div",Te,[t("span",null,i(o.execution_file||"execution.py"),1),t("span",null,i(o.return_file||"return.json"),1)])],8,_e))),128))])]))],64)),A(N,{name:"fade"},{default:M(()=>[I.value?(a(),n("div",Ne,[t("div",Be,[e[22]||(e[22]=t("h3",null,"创建新工具",-1)),t("label",null,[e[20]||(e[20]=h("工具 ID(小写/下划线):",-1)),y(t("input",{"onUpdate:modelValue":e[9]||(e[9]=o=>p.id=o)},null,512),[[g,p.id]])]),t("label",null,[e[21]||(e[21]=h("描述:",-1)),y(t("input",{"onUpdate:modelValue":e[10]||(e[10]=o=>p.description=o)},null,512),[[g,p.description]])]),t("div",Fe,[t("button",{type:"button",class:"ghost",onClick:e[11]||(e[11]=o=>I.value=!1)},"取消"),t("button",{type:"button",class:"primary",onClick:Y,disabled:U.value},i(U.value?"创建中...":"创建"),9,Le)])])])):f("",!0)]),_:1}),A(N,{name:"fade"},{default:M(()=>[S.value?(a(),n("div",ze,[t("div",qe,[e[25]||(e[25]=t("h3",null,"确认删除",-1)),t("p",Je,[e[23]||(e[23]=h(" 确定删除工具 ",-1)),t("strong",null,i(_.value),1),e[24]||(e[24]=h(" 吗?该操作不可恢复。 ",-1))]),t("div",Ze,[t("button",{type:"button",class:"ghost",onClick:e[12]||(e[12]=o=>S.value=!1)},"取消"),t("button",{type:"button",class:"danger",onClick:W,disabled:V.value},i(V.value?"删除中...":"确认删除"),9,Ge)])])])):f("",!0)]),_:1})],2))}}),Ke=ce(He,[["__scopeId","data-v-1fb9e62c"]]);re(Ke).mount("#custom-tools-app");
|