PageSourceSearch

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

js nickz.ai collected 2026-10-05 14:20:15 UTC 607,335 bytes, 1 lines download raw bytes

1import{g as e,r as t,j as n,R as i,u as s,h as l}from"./vendor-react-DejgYtBM.js";import{o as a,m as r,R as o,C as c,B as d,f as u,ba as p,p as h,M as x,l as m,j as g,Y as y,i as j,z as f,T as b,a as _,a1 as S,F as k,y as v,E as C,J as w,K as T,D as I,r as E,A as R,ap as P,bb as z,k as N,X as A,u as M,G as O,v as D,s as L,t as B,_ as F,aQ as W,O as J,aK as U,aX as V,aP as K,bc as G,ar as q,as as $,ay as H,az as Q,aA as X,at as Y,au as Z,av as ee,aw as te,ax as ne,aB as ie,aC as se,L as le,bd as ae,P as re,an as oe}from"./vendor-semi-D8d7bTtM.js";import{bl as ce,bm as de,bn as ue,bo as pe,bp as he,bq as xe,br as me,u as ge,A as ye,s as je,bs as fe,w as be,bt as _e,bu as Se,bv as ke,aT as ve,g as Ce,bw as we,S as Te,Y as Ie,a0 as Ee,aU as Re,$ as Pe,a as ze,V as Ne,bx as Ae,ax as Me,v as Oe,J as De}from"./index-BeIIFw6E.js";import{T as Le,a as Be,D as Fe,b as We,g as Je,S as Ue,c as Ve,d as Ke}from"./i18nFieldCore-CS3IirKt.js";import{o as Ge,bT as qe,br as $e,T as He,bU as Qe,B as Xe,x as Ye,bB as Ze,R as et,q as tt,ah as nt,S as it,X as st,ba as lt,am as at,bV as rt,bW as ot,a7 as ct,aj as dt,b6 as ut,k as pt,aS as ht,ae as xt,I as mt,bm as gt,C as yt,bC as jt,u as ft,n as bt,c as _t,G as St,bX as kt,O as vt,f as Ct,a as wt,bY as Tt,bt as It,bZ as Et,b_ as Rt,b9 as Pt}from"./vendor-icons-EJvJ5X-w.js";import{m as zt}from"./marked.esm-B28mcIGu.js";import{p as Nt}from"./noticeI18n-CXa-dBKj.js";import"./index-BOZr6JVI.js";import"./index-KF7PEnkU.js";import"./captchaCrypto-qWW2iG_E.js";import{d as At}from"./dayjs.min-CASHsil8.js";import{g as Mt}from"./index-3LiQSZK3.js";import{f as Ot,g as Dt,b as Lt,c as Bt,B as Ft,a as Wt,m as Jt,d as Ut,D as Vt}from"./customerSupportContactOrder-BvYdiOIa.js";import"./vendor-motion-Chfy_MiU.js";const Kt=e({area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});var Gt=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function qt(e){var t={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},n=e.match(/<\/?([^\s]+?)[/\s>]/);if(n&&(t.name=n[1],(Kt[n[1]]||"/"===e.charAt(e.length-2))&&(t.voidElement=!0),t.name.startsWith("!--"))){var i=e.indexOf("--\x3e");return{type:"comment",comment:-1!==i?e.slice(4,i):""}}for(var s=new RegExp(Gt),l=null;null!==(l=s.exec(e));)if(l[0].trim())if(l[1]){var a=l[1].trim(),r=[a,""];a.indexOf("=")>-1&&(r=a.split("=")),t.attrs[r[0]]=r[1],s.lastIndex--}else l[2]&&(t.attrs[l[2]]=l[3].trim().substring(1,l[3].length-1));return t}var $t=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,Ht=/^\s*$/,Qt=Object.create(null);const Xt=(e,t)=>{if(!e)return!1;const n=e.props?.children??e.children;return t?n.length>0:!!n},Yt=e=>{if(!e)return[];const t=e.props?.children??e.children;return e.props?.i18nIsDynamicList?Zt(t):t},Zt=e=>Array.isArray(e)?e:[e],en=(e,n,i,s)=>{if(!e)return"";let l="";const a=Zt(e),r=n?.transSupportBasicHtmlNodes?n.transKeepBasicHtmlNodesFor??[]:[];return a.forEach((e,a)=>{if(pe(e))l+=`${e}`;else{if(t.isValidElement(e)){const{props:t,type:o}=e,c=Object.keys(t).length,d=r.indexOf(o)>-1,u=t.children;if(!u&&d&&!c)return void(l+=`<${o}/>`);if(!u&&(!d||c)||t.i18nIsDynamicList)return void(l+=`<${a}></${a}>`);if(d&&1===c&&pe(u))return void(l+=`<${o}>${u}</${o}>`);const p=en(u,n,i,s);return void(l+=`<${a}>${p}</${a}>`)}if(null!==e){if(xe(e)){const{format:t,...n}=e,a=Object.keys(n);if(1===a.length){const e=t?`${a[0]}, ${t}`:a[0];return void(l+=`{{${e}}}`)}return void he(i,"TRANS_INVALID_OBJ","Invalid child - Object should only have keys {{ value, format }} (format is optional).",{i18nKey:s,child:e})}he(i,"TRANS_INVALID_VAR","Passed in a variable like {number} - pass variables for interpolation as full objects like {{number}}.",{i18nKey:s,child:e})}else he(i,"TRANS_NULL_VALUE","Passed in a null value as child",{i18nKey:s})}}),l},tn=(e,n,i,s,l,a,r)=>{if(""===i)return[];const o=l.transKeepBasicHtmlNodesFor||[],c=i&&new RegExp(o.map(e=>`<${e}`).join("|")).test(i);if(!(e||n||c||r))return[i];const d=n??{},u=e=>{Zt(e).forEach(e=>{pe(e)||(Xt(e)?u(Yt(e)):xe(e)&&!t.isValidElement(e)&&Object.assign(d,e))})};u(e);const p=function(e,t){t||(t={}),t.components||(t.components=Qt);var n,i=[],s=[],l=-1,a=!1;if(0!==e.indexOf("<")){var r=e.indexOf("<");i.push({type:"text",content:-1===r?e:e.substring(0,r)})}return e.replace($t,function(r,o){if(a){if(r!=="</"+n.name+">")return;a=!1}var c,d="/"!==r.charAt(1),u=r.startsWith("\x3c!--"),p=o+r.length,h=e.charAt(p);if(u){var x=qt(r);return l<0?(i.push(x),i):((c=s[l]).children.push(x),i)}
vendor: 3,722 bytes, line 1
1if(d&&(l++,"tag"===(n=qt(r)).type&&t.components[n.name]&&(n.type="component",a=!0),n.voidElement||a||!h||"<"===h||n.children.push({type:"text",content:e.slice(p,e.indexOf("<",p))}),0===l&&i.push(n),(c=s[l-1])&&c.children.push(n),s[l]=n),(!d||n.voidElement)&&(l>-1&&(n.voidElement||n.name===r.slice(2,-1))&&(l--,n=-1===l?i:s[l]),!a&&"<"!==h&&h)){c=-1===l?i:s[l].children;var m=e.indexOf("<",p),g=e.slice(p,-1===m?void 0:m);Ht.test(g)&&(g=" "),(m>-1&&l+c.length>=0||" "!==g)&&c.push({type:"text",content:g})}}),i}(`<0>${i}</0>`),h={...d,...a},x=(e,n,i)=>{const s=Yt(e),l=g(s,n.children,i);return(e=>Array.isArray(e)&&e.every(t.isValidElement))(s)&&0===l.length||e.props?.i18nIsDynamicList?s:l},m=(e,n,i,s,l)=>{e.dummy?(e.children=n,i.push(t.cloneElement(e,{key:s},l?void 0:n))):i.push(...t.Children.map([e],e=>{const i={...e.props};return delete i.i18nIsDynamicList,t.createElement(e.type,{...i,key:s,ref:e.props.ref??e.ref},l?null:n)}))},g=(e,i,a)=>{const d=Zt(e);return Zt(i).reduce((e,i,u)=>{const p=i.children?.[0]?.content&&s.services.interpolator.interpolate(i.children[0].content,h,s.language);if("tag"===i.type){let r=d[parseInt(i.name,10)];!r&&n&&(r=n[i.name]),1!==a.length||r||(r=a[0][i.name]),r||(r={});const y=0!==Object.keys(i.attrs).length?((e,t)=>{const n={...t};return n.props=Object.assign(e.props,t.props),n})({props:i.attrs},r):r,j=t.isValidElement(y),f=j&&Xt(i,!0)&&!i.voidElement,b=c&&xe(y)&&y.dummy&&!j,_=xe(n)&&Object.hasOwnProperty.call(n,i.name);if(pe(y)){const t=s.services.interpolator.interpolate(y,h,s.language);e.push(t)}else if(Xt(y)||f){const t=x(y,i,a);m(y,t,e,u)}else if(b){const t=g(d,i.children,a);m(y,t,e,u)}else if(Number.isNaN(parseFloat(i.name)))if(_){const t=x(y,i,a);m(y,t,e,u,i.voidElement)}else if(l.transSupportBasicHtmlNodes&&o.indexOf(i.name)>-1)if(i.voidElement)e.push(t.createElement(i.name,{key:`${i.name}-${u}`}));else{const n=g(d,i.children,a);e.push(t.createElement(i.name,{key:`${i.name}-${u}`},n))}else if(i.voidElement)e.push(`<${i.name} />`);else{const t=g(d,i.children,a);e.push(`<${i.name}>${t}</${i.name}>`)}else if(xe(y)&&!j){const t=i.children[0]?p:null;t&&e.push(t)}else m(y,p,e,u,1!==i.children.length||!p)}else if("text"===i.type){const n=l.transWrapTextNodes,a=r?l.unescape(s.services.interpolator.interpolate(i.content,h,s.language)):s.services.interpolator.interpolate(i.content,h,s.language);n?e.push(t.createElement(n,{key:`${i.name}-${u}`},a)):e.push(a)}return e},[])},y=g([{dummy:!0,children:e||[]}],p,Zt(e||[]));return Yt(y[0])},nn=(e,n,i)=>{const s=e.key||n,l=t.cloneElement(e,{key:s});return!l.props||!l.props.children||i.indexOf(`${n}/>`)<0&&i.indexOf(`${n} />`)<0?l:t.createElement(function(){return t.createElement(t.Fragment,null,l)},{key:s})};function sn({children:e,count:n,parent:i,i18nKey:s,context:l,tOptions:a={},values:r,defaults:o,components:c,ns:d,i18n:u,t:p,shouldUnescape:h,...x}){const m=u||ue();if(!m)return ce(m,"NO_I18NEXT_INSTANCE","Trans: You need to pass in an i18next instance using i18nextReactModule",{i18nKey:s}),e;const g=p||m.t.bind(m)||(e=>e),y={...de(),...m.options?.react};let j=d||g.ns||m.options?.defaultNS;j=pe(j)?[j]:j||["translation"];const f=en(e,y,m,s),b=o||f||y.transEmptyNodeValue||s,{hashTransKey:_}=y,S=s||(_?_(f||b):f||b);m.options?.interpolation?.defaultVariables&&(r=r&&Object.keys(r).length>0?{...r,...m.options.interpolation.defaultVariables}:{...m.options.interpolation.defaultVariables});const k=r||void 0!==n&&!m.options?.interpolation?.alwaysFormat||!e?a.interpolation:{interpolation:{...a.interpolation,prefix:"#$?",suffix:"?$#"}},v={...a,context:l||a.context,count:n,...r,...k,defaultValue:b,ns:j},C=S?g(S,v):b,w=((e,t,n,i)=>e?Array.isArray(e)?((e,t)=>e.map((e,n)=>nn(e,n,t)))(e,t):xe(e)?((e,t)=>
1{const n={};return Object.keys(e).forEach(i=>{Object.assign(n,{[i]:nn(e[i],i,t)})}),n})(e,t):(ce(n,"TRANS_INVALID_COMPONENTS",'<Trans /> "components" prop expects an object or array',{i18nKey:i}),null):null)(c,C,m,s);let T=w||e,I=null;var E;xe(E=w)&&!Array.isArray(E)&&Object.keys(E).reduce((e,t)=>e&&Number.isNaN(Number.parseFloat(t)),!0)&&(I=w,T=e);const R=tn(T,I,C,m,y,v,h),P=i??y.defaultTransParent;return P?t.createElement(P,x,R):R}function ln({children:e,count:n,parent:i,i18nKey:s,context:l,tOptions:a={},values:r,defaults:o,components:c,ns:d,i18n:u,t:p,shouldUnescape:h,...x}){const{i18n:m,defaultNS:g}=t.useContext(me)||{},y=u||m||ue(),j=p||y?.t.bind(y);return sn({children:e,count:n,parent:i,i18nKey:s,context:l,tOptions:a,values:r,defaults:o,components:c,ns:d||j?.ns||g||y?.options?.defaultNS,i18n:y,t:p,shouldUnescape:h,...x})}const an=e=>{if("boolean"==typeof e)return e;if("number"==typeof e)return 1===e;if("string"==typeof e){const t=e.toLowerCase();return"true"===t||"1"===t}return!1},{Text:rn}=u,on=()=>{const{t:e}=ge();let[i,s]=t.useState({PasswordLoginEnabled:"",PasswordRegisterEnabled:"",EmailVerificationEnabled:"",GitHubOAuthEnabled:"",GitHubClientId:"",GitHubClientSecret:"",GoogleOAuthEnabled:"",GoogleClientId:"",GoogleClientSecret:"","oidc.enabled":"","oidc.client_id":"","oidc.client_secret":"","oidc.well_known":"","oidc.authorization_endpoint":"","oidc.token_endpoint":"","oidc.user_info_endpoint":"",Notice:"",SMTPServer:"",SMTPPort:"",SMTPAccount:"",SMTPFrom:"",SMTPToken:"",WorkerUrl:"",WorkerValidKey:"",WorkerAllowHttpImageRequestEnabled:"",Footer:"",WeChatAuthEnabled:"",WeChatServerAddress:"",WeChatServerToken:"",WeChatAccountQRCodeImageURL:"",TurnstileCheckEnabled:"",TurnstileSiteKey:"",TurnstileSecretKey:"",RegisterEnabled:"",EmailDomainRestrictionEnabled:"",EmailAliasRestrictionEnabled:"",SMTPSSLEnabled:"",EmailDomainWhitelist:[],TelegramOAuthEnabled:"",TelegramBotToken:"",TelegramBotName:"",LinuxDOOAuthEnabled:"",LinuxDOClientId:"",LinuxDOClientSecret:"",ServerAddress:""});const[l,u]=t.useState({}),[g,y]=t.useState(!1),[j,f]=t.useState(!1),b=t.useRef(null),[_,S]=t.useState([]),[k,v]=t.useState(!1),[C,w]=t.useState(!1),[T,I]=t.useState("");t.useEffect(()=>{(async()=>{y(!0);const e=await ye.get("/api/option/"),{success:t,message:n,data:i}=e.data;if(t){let e={};i.forEach(t=>{switch(t.key){case"TopupGroupRatio":t.value=JSON.stringify(JSON.parse(t.value),null,2);break;case"EmailDomainWhitelist":S(t.value?t.value.split(","):[]);break;case"PasswordLoginEnabled":case"PasswordRegisterEnabled":case"EmailVerificationEnabled":case"GitHubOAuthEnabled":case"GoogleOAuthEnabled":case"WeChatAuthEnabled":case"TelegramOAuthEnabled":case"RegisterEnabled":case"TurnstileCheckEnabled":case"EmailDomainRestrictionEnabled":case"EmailAliasRestrictionEnabled":case"SMTPSSLEnabled":case"LinuxDOOAuthEnabled":case"oidc.enabled":case"WorkerAllowHttpImageRequestEnabled":t.value=an(t.value);break;case"Price":case"MinTopUp":t.value=parseFloat(t.value)}e[t.key]=t.value}),s(e),u(e),b.current&&b.current.setValues(e),f(!0)}else je(n);y(!1)})()},[]);const E=async t=>{y(!0);try{const n=t.filter(e=>e.key.toLowerCase().endsWith("enabled")),l=t.filter(e=>!e.key.toLowerCase().endsWith("enabled"));for(const e of n){const t=await ye.put("/api/option/",{key:e.key,value:e.value.toString()});if(!t.data.success)return void je(t.data.message)}if(l.length>0){const e=l.map(e=>ye.put("/api/option/",{key:e.key,value:"boolean"==typeof e.value?e.value.toString():e.value}));(await Promise.all(e)).filter(e=>!e.data.success).forEach(e=>{je(e.data.message)})}be(e("更新成功"));const a={...i};t.forEach(e=>{a[e.key]=e.value}),s(a)}catch(n){je(e("更新失败"))}y(!1)},R=async()=>{let e=fe(i.WorkerUrl);const t=[{key:"WorkerUrl",value:e},{key:"WorkerAllowHttpImageRequestEnabled",value:i.WorkerAllowHttpImageRequestEnabled?"true":"false"}];""===i.WorkerValidKey&&""!==e||t.push({key:"WorkerValidKey",value:i.WorkerValidKey}),await E(t)},P=async()=>{let e=fe(i.ServerAddress);await E([{key:"ServerAddress",value:e}])},z=async()=>{const e=[];l.SMTPServer!==i.SMTPServer&&e.push({key:"SMTPServer",value:i.SMTPServer}),l.SMTPAccount!==i.SMTPAccount&&e.push({key:"SMTPAccount",value:i.SMTPAccount}),l.SMTPFrom!==i.SMTPFrom&&e.push({key:"SMTPFrom",value:i.SMTPFrom}),l.SMTPPort!==i.SMTPPort&&""!==i.SMTPPort&&e.push({key:"SMTPPort",value:i.SMTPPort}),l.SMTPToken!==i.SMTPToken&&""!==i.SMTPToken&&e.push({key:"SMTPToken",value:i.SMTPToken}),e.length>0&&await E(e)},N=async()=>{Array.isArray(_)?await E([{key:"EmailDomainWhitelist",value:_.join(",")}]):je(e("邮箱域名白名单格式不正确"))},A=()=>{if(T&&""!==T.trim()){const t=T.trim();if(!/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/.test(t))return void je(e("邮箱域名格式不正确,请输入有效的域名,如 gmail.com"));if(_.includes(t))return void je(e("该域名已存在于白名单中"));S([..._,t]),I(""),be(e("已添加到白名单"))}},M=async()=>{const e=[];l.WeChatServerAddress!==i.WeChatServerAddress&&e.push({key:"WeChatServerAddress",value:fe(i.WeChatServerAddress)}),l.WeChatAccountQRCodeImageURL!==i.WeChatAccountQRCodeImageURL&&e.push({key:"WeChatAccountQRCodeImageURL",value:i.WeChatAccountQRCodeImageURL}),l.WeChatServerToken!==i.WeChatServerToken&&""!==i.WeChatServerToken&&e.push({key:"WeChatServerToken",value:i.WeChatServerToken}),e.length>0&&await E(e)},O=async()=>{const e=[];l.GitHubClientId!==i.GitHubClientId&&e.push({key:"GitHubClientId",value:i.GitHubClientId}),l.GitHubClientSecret!==i.GitHubClientSecret&&""!==i.GitHubClientSecret&&e.push({key:"GitHubClientSecret",value:i.GitHubClientSecret}),e.length>0&&await E(e)},D=async()=>{const e=[];l.GoogleClientId!==i.GoogleClientId&&e.push({key:"GoogleClientId",value:i.GoogleClientId}),l.GoogleClientSecret!==i.GoogleClientSecret&&""!==i.GoogleClientSecret&&e.push({key:"GoogleClientSecret",value:i.GoogleClientSecret}),e.length>0&&await E(e)},L=async()=>
1{if(i["oidc.well_known"]&&""!==i["oidc.well_known"]){if(!i["oidc.well_known"].startsWith("http://")&&!i["oidc.well_known"].startsWith("https://"))return void je(e("Well-Known URL 必须以 http:// 或 https:// 开头"));try{const t=await _e.create().get(i["oidc.well_known"]);i["oidc.authorization_endpoint"]=t.data.authorization_endpoint,i["oidc.token_endpoint"]=t.data.token_endpoint,i["oidc.user_info_endpoint"]=t.data.userinfo_endpoint,be(e("获取 OIDC 配置成功!"))}catch(n){return console.error(n),void je(e("获取 OIDC 配置失败,请检查网络状况和 Well-Known URL 是否正确"))}}const t=[];l["oidc.well_known"]!==i["oidc.well_known"]&&t.push({key:"oidc.well_known",value:i["oidc.well_known"]}),l["oidc.client_id"]!==i["oidc.client_id"]&&t.push({key:"oidc.client_id",value:i["oidc.client_id"]}),l["oidc.client_secret"]!==i["oidc.client_secret"]&&""!==i["oidc.client_secret"]&&t.push({key:"oidc.client_secret",value:i["oidc.client_secret"]}),l["oidc.authorization_endpoint"]!==i["oidc.authorization_endpoint"]&&t.push({key:"oidc.authorization_endpoint",value:i["oidc.authorization_endpoint"]}),l["oidc.token_endpoint"]!==i["oidc.token_endpoint"]&&t.push({key:"oidc.token_endpoint",value:i["oidc.token_endpoint"]}),l["oidc.user_info_endpoint"]!==i["oidc.user_info_endpoint"]&&t.push({key:"oidc.user_info_endpoint",value:i["oidc.user_info_endpoint"]}),t.length>0&&await E(t)},B=async()=>{const e=[{key:"TelegramBotToken",value:i.TelegramBotToken},{key:"TelegramBotName",value:i.TelegramBotName}];await E(e)},F=async()=>{const e=[];l.TurnstileSiteKey!==i.TurnstileSiteKey&&e.push({key:"TurnstileSiteKey",value:i.TurnstileSiteKey}),l.TurnstileSecretKey!==i.TurnstileSecretKey&&""!==i.TurnstileSecretKey&&e.push({key:"TurnstileSecretKey",value:i.TurnstileSecretKey}),e.length>0&&await E(e)},W=async()=>{const e=[];l.LinuxDOClientId!==i.LinuxDOClientId&&e.push({key:"LinuxDOClientId",value:i.LinuxDOClientId}),l.LinuxDOClientSecret!==i.LinuxDOClientSecret&&""!==i.LinuxDOClientSecret&&e.push({key:"LinuxDOClientSecret",value:i.LinuxDOClientSecret}),e.length>0&&await E(e)},J=async(t,n)=>{const s=n.target.checked;"GitHubOAuthEnabled"!==t||!s||i.GitHubClientId&&i.GitHubClientSecret?"GoogleOAuthEnabled"!==t||!s||i.GoogleClientId&&i.GoogleClientSecret?"LinuxDOOAuthEnabled"!==t||!s||i.LinuxDOClientId&&i.LinuxDOClientSecret?("PasswordLoginEnabled"!==t||s?await E([{key:t,value:s}]):v(!0),"LinuxDOOAuthEnabled"===t&&w(s)):je(e("请先在下方配置 LinuxDO Client ID 和 Client Secret")):je(e("请先在下方配置 Google Client ID 和 Client Secret")):je(e("请先在下方配置 GitHub Client ID 和 Client Secret"))},U=async()=>{await E([{key:"PasswordLoginEnabled",value:!1}]),v(!1)};return n.jsx("div",{children:j?n.jsx(a,{initValues:i,onValueChange:e=>{s(e)},getFormApi:e=>b.current=e,children:({formState:t,values:s,formApi:l})=>n.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"10px",marginTop:"10px"},children:[n.jsx(r,{children:n.jsxs(a.Section,{text:e("通用设置"),children:[n.jsx(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:n.jsx(c,{xs:24,sm:24,md:24,lg:24,xl:24,children:n.jsx(a.Input,{field:"ServerAddress",label:e("服务器地址"),placeholder:"https://yourdomain.com",extraText:e("该服务器地址将影响支付回调地址以及默认首页展示的地址,请确保正确配置")})})}),n.jsx(d,{onClick:P,children:e("更新服务器地址")})]})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("代理设置"),children:[n.jsx(rn,{children:n.jsx(ln,{i18nKey:"worker_proxy_support",components:{workerLink:n.jsx("a",{href:"https://github.com/Calcium-Ion/new-api-worker",target:"_blank",rel:"noreferrer"})}})}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"WorkerUrl",label:e("Worker地址"),placeholder:e("例如:https://workername.yourdomain.workers.dev")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"WorkerValidKey",label:e("Worker密钥"),placeholder:e("敏感信息不会发送到前端显示"),type:"password"})})]}),n.jsx(a.Checkbox,{field:"WorkerAllowHttpImageRequestEnabled",noLabel:!0,children:e("允许 HTTP 协议
1图片请求(适用于自部署代理)")}),n.jsx(d,{onClick:R,children:e("更新Worker设置")})]})}),n.jsx(r,{children:n.jsx(a.Section,{text:e("配置登录注册"),children:n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsxs(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:[n.jsx(a.Checkbox,{field:"PasswordLoginEnabled",noLabel:!0,onChange:e=>J("PasswordLoginEnabled",e),children:e("允许通过密码进行登录")}),n.jsx(a.Checkbox,{field:"PasswordRegisterEnabled",noLabel:!0,onChange:e=>J("PasswordRegisterEnabled",e),children:e("允许通过密码进行注册")}),n.jsx(a.Checkbox,{field:"EmailVerificationEnabled",noLabel:!0,onChange:e=>J("EmailVerificationEnabled",e),children:e("通过密码注册时需要进行邮箱验证")}),n.jsx(a.Checkbox,{field:"RegisterEnabled",noLabel:!0,onChange:e=>J("RegisterEnabled",e),children:e("允许新用户注册")}),n.jsx(a.Checkbox,{field:"TurnstileCheckEnabled",noLabel:!0,onChange:e=>J("TurnstileCheckEnabled",e),children:e("允许 Turnstile 用户校验")})]}),n.jsxs(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:[n.jsx(a.Checkbox,{field:"GitHubOAuthEnabled",noLabel:!0,onChange:e=>J("GitHubOAuthEnabled",e),children:e("允许通过 GitHub 账户登录 & 注册")}),n.jsx(a.Checkbox,{field:"GoogleOAuthEnabled",noLabel:!0,onChange:e=>J("GoogleOAuthEnabled",e),children:e("允许通过 Google 账户登录 & 注册")}),n.jsx(a.Checkbox,{field:"LinuxDOOAuthEnabled",noLabel:!0,onChange:e=>J("LinuxDOOAuthEnabled",e),children:e("允许通过 Linux DO 账户登录 & 注册")}),n.jsx(a.Checkbox,{field:"WeChatAuthEnabled",noLabel:!0,onChange:e=>J("WeChatAuthEnabled",e),children:e("允许通过微信登录 & 注册")}),n.jsx(a.Checkbox,{field:"TelegramOAuthEnabled",noLabel:!0,onChange:e=>J("TelegramOAuthEnabled",e),children:e("允许通过 Telegram 进行登录")}),n.jsx(a.Checkbox,{field:"['oidc.enabled']",noLabel:!0,onChange:e=>J("oidc.enabled",e),children:e("允许通过 OIDC 进行登录")})]})]})})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置邮箱域名白名单"),children:[n.jsx(rn,{children:e("用以防止恶意用户利用临时邮箱批量注册")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Checkbox,{field:"EmailDomainRestrictionEnabled",noLabel:!0,onChange:e=>J("EmailDomainRestrictionEnabled",e),children:e("启用邮箱域名白名单")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Checkbox,{field:"EmailAliasRestrictionEnabled",noLabel:!0,onChange:e=>J("EmailAliasRestrictionEnabled",e),children:e("启用邮箱别名限制")})})]}),n.jsx(p,{value:_,onChange:S,placeholder:e("输入域名后回车"),style:{width:"100%",marginTop:16}}),n.jsx(a.Input,{placeholder:e("输入要添加的邮箱域名"),value:T,onChange:e=>I(e),style:{marginTop:16},suffix:n.jsx(d,{theme:"solid",type:"primary",onClick:A,children:e("添加")}),onEnterPress:A}),n.jsx(d,{onClick:N,style:{marginTop:10},children:e("保存邮箱域名白名单设置")})]})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置 SMTP"),children:[n.jsx(rn,{children:e("用以支持系统的邮件发送")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"SMTPServer",label:e("SMTP 服务器地址")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"SMTPPort",label:e("SMTP 端口")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"SMTPAccount",label:e("SMTP 账户")})})]}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:[n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"SMTPFrom",label:e("SMTP 发送者邮箱")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"SMTPToken",label:e("SMTP 访问凭证"),type:"password",placeholder:e("敏感信息不会发送到前端显示")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Checkbox,{field:"SMTPSSLEnabled",noLabel:!0,onChange:e=>J("SMTPSSLEnabled",e),children:e("启用SMTP SSL")})})]}),n.jsx(d,{onClick:z,children:e("保存 SMTP 设置")})]})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置 OIDC"),children:[n.jsx(rn,{children:e("用以支持通过 OIDC 登录,例如 Okta、Auth0 等兼容 OIDC 协议的 IdP")}),n.jsx(h,{type:"info",description:`${e("主页链接填")} ${i.ServerAddress?i.ServerAddress:e("网站地址")},${e("重定向 URL 填")} ${i.ServerAddress?i.ServerAddress:e("网站地址")}/oauth/oidc`,style:{marginBottom:20,marginTop:16}}),n.jsx(rn,{children:e("system_hint_001")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"['oidc.well_known']",label:e("Well-Known URL"),placeholder:e("请输入 OIDC 的 Well-Known URL")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"['oidc.client_id']",label:e("Client ID"),placeholder:e("输入 OIDC 的 Client ID")})})]}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"['oidc.client_secret']",label:e("Client Secret"),type:"password",placeholder:e("敏感信息不会发送到前端显示")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"['oidc.authorization_endpoint']",label:e("Authorization Endpoint"),placeholder:e("输入 OIDC 的 Authorization Endpoint")})})]}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"['oidc.token_endpoint']",label:e("Token Endpoint"),placeholder:e("输入 OIDC 的 Token Endpoint")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"['oidc.user_info_endpoint']",label:e("User Info Endpoint"),placeholder:e("输入 OIDC 的 Userinfo Endpoint")})})]}),n.jsx(d,{onClick:L,children:e("保存 OIDC 设置")})]})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置 GitHub OAuth App"),children:[n.jsx(rn,{children:e("用以支持通过 GitHub 进行登录注册")}),n.jsx(h,{type:"info",description:`${e("Homepage URL 填")} ${i.ServerAddress?i.ServerAddress:e("网站地址")},${e("Authorization callback URL 填")} ${i.ServerAddress?i.ServerAddress:e("网站地址")}/oauth/github`,style:{marginBottom:20,marginTop:16}}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"GitHubClientId",label:e("GitHub Client ID")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"GitHubClientSecret",label:e("GitHub Client Secret"),type:"password",placeholder:e("敏感信息不会发送到前端显示")})})]}),n.jsx(d,{onClick:O,children:e("保存 GitHub OAuth 设置")})]})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置 Google OAuth 2.0"),children:[n.jsx(rn,{children:e("用以支持通过 Google 进行登录注册")}),n.jsx(h,{type:"info",description:`${e('请在 Google Cloud Console 创建 OAuth 2.0 客户端 ID,应用类型选择"Web应用"。授权的重定向 URI 填')} ${i.ServerAddress?i.ServerAddress:e("网站地址")}/oauth/google`,style:{marginBottom:20,marginTop:16}}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"GoogleClientId",label:e("Google Client ID")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"GoogleClientSecret",label:e("Google Client Secret"),type:"password",placeholder:e("敏感信息不会发送到前端显示")})})]}),n.jsx(d,{onClick:D,children:e("保存 Google OAuth 设置")})]})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置 Linux DO OAuth"),children:[n.jsxs(rn,{children:[e("用以支持通过 Linux DO 进行登录注册"),n.jsx("a",{href:"https://connect.linux.do/",target:"_blank",rel:"noreferrer",style:{display:"inline-block",marginLeft:4,marginRight:4},children:e("点击此处")}),e("管理你的 LinuxDO OAuth App")]}),n.jsx(h,{type:"info",description:`${e("回调 URL 填")} ${i.ServerAddress?i.ServerAddress:e("网站地址")}/oauth/linuxdo`,style:{marginBottom:20,marginTop:16}}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"LinuxDOClientId",label:e("Linux DO Client ID"),placeholder:e("输入你注册的 
1LinuxDO OAuth APP 的 ID")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"LinuxDOClientSecret",label:e("Linux DO Client Secret"),type:"password",placeholder:e("敏感信息不会发送到前端显示")})})]}),n.jsx(d,{onClick:W,children:e("保存 Linux DO OAuth 设置")})]})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置 WeChat Server"),children:[n.jsx(rn,{children:e("用以支持通过微信进行登录注册")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"WeChatServerAddress",label:e("WeChat Server 服务器地址")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"WeChatServerToken",label:e("WeChat Server 访问凭证"),type:"password",placeholder:e("敏感信息不会发送到前端显示")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"WeChatAccountQRCodeImageURL",label:e("微信公众号二维码图片链接")})})]}),n.jsx(d,{onClick:M,children:e("保存 WeChat Server 设置")})]})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置 Telegram 登录"),children:[n.jsx(rn,{children:e("用以支持通过 Telegram 进行登录注册")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"TelegramBotToken",label:e("Telegram Bot Token"),placeholder:e("敏感信息不会发送到前端显示"),type:"password"})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"TelegramBotName",label:e("Telegram Bot 名称")})})]}),n.jsx(d,{onClick:B,children:e("保存 Telegram 登录设置")})]})}),n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置 Turnstile"),children:[n.jsx(rn,{children:e("用以支持用户校验")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"TurnstileSiteKey",label:e("Turnstile Site Key")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"TurnstileSecretKey",label:e("Turnstile Secret Key"),type:"password",placeholder:e("敏感信息不会发送到前端显示")})})]}),n.jsx(d,{onClick:F,children:e("保存 Turnstile 设置")})]})}),n.jsx(x,{title:e("确认取消密码登录"),visible:k,onOk:U,onCancel:()=>{v(!1),b.current.setValue("PasswordLoginEnabled",!0)},okText:e("确认"),cancelText:e("取消"),children:n.jsx("p",{children:e("您确定要取消密码登录功能吗?这可能会影响用户的登录方式。")})})]})}):n.jsx("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:n.jsx(m,{size:"large"})})})};const cn=({options:e,refresh:i})=>{const{t:s}=ge(),l=t.useRef(null),[r,u]=t.useState(!1),[p,x]=t.useState(!1),[j,f]=t.useState({enabled:!1,base_url:"",api_key:"",model:""}),[b,_]=t.useState(j);t.useEffect(()=>{if(!e)return;const t={enabled:an(e["translation_setting.enabled"]),base_url:e["translation_setting.base_url"]||"",api_key:"",model:e["translation_setting.model"]||""};f(t),_(structuredClone(t)),l.current&&l.current.setValues(t)},[e?.["translation_setting.enabled"],e?.["translation_setting.base_url"],e?.["translation_setting.model"]]);const S=e=>t=>{f(n=>({...n,[e]:t}))};return n.jsx(m,{spinning:r,children:n.jsx(a,{getFormApi:e=>l.current=e,values:j,layout:"vertical",style:{marginBottom:15},children:n.jsxs(a.Section,{text:n.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[n.jsx(Ge,{size:16}),s("多语言自动翻译")]}),children:[n.jsx(h,{type:"info",description:s("开启后,在保存系统公告 / 常见问答 / API 信息时,对未翻译或原文已修改的条目自动调用 AI 模型翻译为 6 种语言(en / ja / ko / ru / es / de),并随原文一同保存。前台用户访问时会按当前语言读取译文,不再消耗 token。"),fullMode:!1,closeIcon:null}),n.jsxs(o,{gutter:16,style:{marginTop:12},children:[n.jsx(c,{xs:24,md:6,children:n.jsx(a.Switch,{field:"enabled",label:s("启用自动翻译"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:S("enabled")})}),n.jsx(c,{xs:24,md:9,children:n.jsx(a.Input,{field:"base_url",label:s("翻译模型 Base URL"),placeholder:"https://yunwu.ai/v1",onChange:S("base_url"),showClear:!0})}),n.jsx(c,{xs:24,md:9,children:n.jsx(a.Input,{field:"model",label:s("翻译模型"),placeholder:"gpt-4o-mini",onChange:S("model"),showClear:!0})})]}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,md:18,children:n.jsx(a.Input,{field:"api_key",label:s("翻译模型 API Key"),placeholder:s("留空保持原值不变"),mode:"password",onChange:S("api_key"),showClear:!0})})}),n.jsx(o,{style:{marginTop:8},children:n.jsxs(g,{children:[n.jsx(d,{onClick:async()=>{const e=(()=>{const e=[];return String(j.enabled)!==String(b.enabled)&&e.push({key:"translation_setting.enabled",value:String(!!j.enabled)}),j.base_url!==b.base_url&&e.push({key:"translation_setting.base_url",value:j.base_url||""}),j.model!==b.model&&e.push({key:"translation_setting.model",value:j.model||""}),j.api_key&&""!==j.api_key.trim()&&e.push({key:"translation_setting.api_key",value:j.api_key}),e})();if(0!==e.length){u(!0);try{await Promise.all(e.map(e=>ye.put(Se(),e))),be(s("保存成功")),f(e=>({...e,api_key:""})),_(e=>({enabled:j.enabled,base_url:j.base_url,api_key:"",model:j.model})),i&&i()}catch(t){je(s("保存失败,请重试"))}finally{u(!1)}}else y.info(s("未检测到变更"))},type:"primary",theme:"solid",loading:r,children:s("保存翻译设置")}),n.jsx(d,{onClick:async()=>{x(!0);try{const e={};j.api_key&&""!==j.api_key.trim()&&(e.baseURL=j.base_url,e.apiKey=j.api_key,e.model=j.model);const t=await async function({baseURL:e,apiKey:t,model:n}={}){const i=new URLSearchParams;e&&i.set("base_url",e),t&&i.set("api_key",t),n&&i.set("model",n);const s=await ye.post("/api/option/translate-test"+(i.toString()?`?${i.toString()}`:"")),{success:l,message:a,data:r}=s.data||{};if(!l)throw new Error(a||"连接测试失败");return r}(e);y.success(`${s("连接成功")}: ${t?.sample||""}`)}catch(e){je(e&&e.message||s("连接失败"))}finally{x(!1)}},loading:p,children:s("测试连通性")})]})})]})})})},{Text:dn}=u,un=()=>{const{t:e}=ge();let[i,s]=t.useState({EmailDomainRestrictionEnabled:"",EmailAliasRestrictionEnabled:"",EmailDomainWhitelist:[],"translation_setting.enabled":!1,"translation_setting.base_url":"","translation_setting.model":""});const[l,u]=t.useState({}),[h,x]=t.useState(!1),[g,y]=t.useState(!1),j=t.useRef(null),[f,b]=t.useState([]),[_,S]=t.useState(""),k=async()=>{x(!0);try{const e=await ye.get("/api/option/admin"),{success:t,message:n,data:i}=e.data;if(t){let e={};
1i.forEach(t=>{switch(t.key){case"EmailDomainWhitelist":b(t.value?t.value.split(","):[]);break;case"EmailDomainRestrictionEnabled":case"EmailAliasRestrictionEnabled":case"translation_setting.enabled":t.value=an(t.value)}e[t.key]=t.value}),s(e),u(e),j.current&&j.current.setValues(e)}else je(n);y(!0)}catch(t){console.error("获取选项失败:",t),je(e("获取选项失败,请刷新重试")),y(!0)}finally{x(!1)}};t.useEffect(()=>{k()},[]);const v=async t=>{x(!0);try{const n=t.filter(e=>e.key.toLowerCase().endsWith("enabled")),l=t.filter(e=>!e.key.toLowerCase().endsWith("enabled")),a="/api/option/admin";for(const e of n){const t=await ye.put(a,{key:e.key,value:e.value.toString()});if(!t.data.success)return void je(t.data.message)}if(l.length>0){const e=l.map(e=>ye.put(a,{key:e.key,value:"boolean"==typeof e.value?e.value.toString():e.value}));(await Promise.all(e)).filter(e=>!e.data.success).forEach(e=>{je(e.data.message)})}be(e("更新成功"));const r={...i};t.forEach(e=>{r[e.key]=e.value}),s(r)}catch(n){je(e("更新失败"))}x(!1)},C=async()=>{Array.isArray(f)?await v([{key:"EmailDomainWhitelist",value:f.join(",")}]):je(e("邮箱域名白名单格式不正确"))},w=()=>{if(_&&""!==_.trim()){const t=_.trim();if(!/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/.test(t))return void je(e("邮箱域名格式不正确,请输入有效的域名,如 gmail.com"));if(f.includes(t))return void je(e("该域名已存在于白名单中"));b([...f,t]),S(""),be(e("已添加到白名单"))}},T=async(e,t)=>{const n=t.target.checked;await v([{key:e,value:n}])};return n.jsx("div",{children:g?n.jsx(a,{initValues:i,onValueChange:e=>{s(e)},getFormApi:e=>j.current=e,children:({formState:t,values:s,formApi:l})=>n.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"10px",marginTop:"10px"},children:[n.jsx(r,{children:n.jsxs(a.Section,{text:e("配置邮箱域名白名单"),children:[n.jsx(dn,{children:e("用以防止恶意用户利用临时邮箱批量注册")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Checkbox,{field:"EmailDomainRestrictionEnabled",noLabel:!0,onChange:e=>T("EmailDomainRestrictionEnabled",e),children:e("启用邮箱域名白名单")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Checkbox,{field:"EmailAliasRestrictionEnabled",noLabel:!0,onChange:e=>T("EmailAliasRestrictionEnabled",e),children:e("启用邮箱别名限制")})})]}),n.jsx(p,{value:f,onChange:b,placeholder:e("输入域名后回车"),style:{width:"100%",marginTop:16}}),n.jsx(a.Input,{placeholder:e("输入要添加的邮箱域名"),value:_,onChange:e=>S(e),style:{marginTop:16},suffix:n.jsx(d,{theme:"solid",type:"primary",onClick:w,children:e("添加")}),onEnterPress:w}),n.jsx(d,{onClick:C,style:{marginTop:10},children:e("保存邮箱域名白名单设置")})]})}),n.jsx(r,{children:n.jsx(cn,{options:i,refresh:k})})]})}):n.jsx("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:n.jsx(m,{size:"large"})})})};function pn(e){const{t:i}=ge(),s=[{key:"hour",label:i("小时"),value:"hour"},{key:"day",label:i("天"),value:"day"},{key:"week",label:i("周"),value:"week"},{key:"month",label:i("月"),value:"month"}],[l,r]=t.useState(!1),[u,p]=t.useState({DataExportEnabled:!1,DataExportInterval:"",DataExportDefaultTime:""}),h=t.useRef(),[x,g]=t.useState(u);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(u).includes(n)&&(t[n]=e.options[n]);p(t),g(structuredClone(t)),h.current.setValues(t),localStorage.setItem("data_export_default_time",String(u.DataExportDefaultTime))},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:l,children:n.jsx(a,{values:u,getFormApi:e=>h.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("数据看板设置"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"DataExportEnabled",label:i("启用数据看板(实验性)"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{p({...u,DataExportEnabled:e})}})})}),n.jsxs(o,{children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("数据看板更新间隔"),step:1,min:1,suffix:i("分钟"),extraText:i("设置过短会影响数据库性能"),placeholder:i("数据看板更新间隔"),field:"DataExportInterval",onChange:e=>p({...u,DataExportInterval:String(e)})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Select,{label:i("数据看板默认时间粒度"),optionList:s,field:"DataExportDefaultTime",extraText:i("仅修改展示粒度,统计精确到小时"),placeholder:i("数据看板默认时间粒度"),style:{width:180},onChange:e=>p({...u,DataExportDefaultTime:String(e)})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(u,x);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof u[e.key]?String(u[e.key]):u[e.key],ye.put("/api/option/admin",{key:e.key,value:t})});r(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{r(!1)})},children:i("保存数据看板设置")})})]})})})})}const hn=({item:e,fields:t,targetLangs:i,onClick:s})=>{const{t:l}=ge(),a=Je(e,t,i),r=Ue[a]||Ue.none,o=n.jsx(j,{color:r.color,shape:"circle",style:{cursor:s?"pointer":"default"},onClick:s,children:l(r.textKey)});return"failed"===a&&e?.translation_error?n.jsx(f,{content:e.translation_error,position:"top",children:o}):"stale"===a?n.jsx(f,{content:l("原文已修改,译文可能过期,请重新翻译"),position:"top",children:o}):o},xn=({visible:e,onClose:i,item:s,fields:l,sourceLang:a=Fe,targetLangs:r=Le,onApply:o,translationEnabled:c=!1})=>{const{t:p}=ge(),[m,j]=t.useState({}),[f,v]=t.useState(!1),[C,w]=t.useState(a),T=t.useMemo(()=>l.map(e=>e.key),[l]),I=t.useMemo(()=>Je(s,T,r),[s,T,r]);t.useEffect(()=>{if(!e)return;const t={};t[a]={}
1,l.forEach(e=>{t[a][e.key]=s?.[e.key]??""}),r.forEach(e=>{const n=s?.translations?.[e]||{};t[e]={},l.forEach(i=>{t[e][i.key]=n[i.key]??""})}),j(t),w(a)},[e,s,a,r,l]);const E=(e,t,n)=>{j(i=>({...i,[e]:{...i[e]||{},[t]:n}}))};return n.jsxs(x,{title:p("查看 / 编辑多语言译文"),visible:e,onOk:()=>{const e={...s};l.forEach(t=>{e[t.key]=m[a]?.[t.key]??""});const t={...s?.translations||{}};let n=!1;r.forEach(e=>{const i=m[e]||{},s={...t[e]||{}};let a=!1;l.forEach(e=>{const t=i[e.key]??"";s[e.key]=t,""!==String(t).trim()&&(a=!0)}),a?(t[e]=s,n=!0):delete t[e]}),n?(e.translations=t,e.translation_hash=Ke(Be(e,T)),e.translation_updated_at=(new Date).toISOString(),delete e.translation_error):(delete e.translations,delete e.translation_hash,delete e.translation_updated_at),o&&o(e),i&&i()},onCancel:i,okText:p("确定"),cancelText:p("取消"),width:800,children:[n.jsx(h,{type:"stale"===I?"warning":"failed"===I?"danger":"info",description:n.jsxs(g,{children:[n.jsxs("span",{children:[p("当前状态"),":"," ","done"===I&&p("已翻译"),"partial"===I&&p("部分翻译"),"stale"===I&&p("原文已改"),"failed"===I&&(s?.translation_error||p("翻译失败")),"none"===I&&p("未翻译")]}),n.jsx(d,{icon:"none"===I?n.jsx(Ge,{size:14}):n.jsx(qe,{size:14}),size:"small",theme:"solid",type:"primary",loading:f,disabled:!c||f,onClick:async()=>{try{v(!0);const e={...s,...m[a]||{}},t=await async function(e,t,n=Le){const i=Be(e,t),{results:s,errors:l}=await async function(e,t=Le,n=Fe){const i=await ye.post("/api/option/translate-batch",{fields:e,source_lang:n,target_langs:t}),{success:s,message:l,data:a}=i.data||{};if(!s)throw new Error(l||"翻译失败");return{results:a?.results||{},errors:a?.errors||{}}}(i,n);return We(e,t,s,l)}(e,T,r),n={...m};r.forEach(e=>{const i=t?.translations?.[e]||{};n[e]={},l.forEach(t=>{n[e][t.key]=i[t.key]??""})}),j(n),y.success(p("AI 翻译完成"))}catch(e){y.error(e&&e.message||p("AI 翻译失败"))}finally{v(!1)}},children:p("none"===I?"AI 翻译":"重新翻译")})]}),fullMode:!1,closeIcon:null}),n.jsx(b,{activeKey:C,onChange:w,type:"line",style:{marginTop:12},children:[a,...r].map(e=>n.jsx(_,{tab:`${Ve(e)}${e===a?` (${p("原文")})`:""}`,itemKey:e,children:n.jsx("div",{style:{display:"flex",flexDirection:"column",gap:16,paddingTop:8},children:l.map(t=>{const i=m[e]?.[t.key]??"";return n.jsxs("div",{children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:4},children:t.label}),"textarea"===t.type?n.jsx(S,{value:i,rows:t.rows||4,maxCount:t.maxCount,showClear:!0,onChange:n=>E(e,t.key,n),placeholder:e===a?"":p("留空将回退到原文")}):n.jsx(k,{value:i,maxLength:t.maxLength,showClear:!0,onChange:n=>E(e,t.key,n),placeholder:e===a?"":p("留空将回退到原文")})]},t.key)})})},e))})]})},mn=["content","extra"],gn=[{key:"content",label:"内容",type:"textarea",rows:4,maxCount:500},{key:"extra",label:"说明",type:"input",maxLength:200}],{Text:yn}=u,jn=({options:e,refresh:i})=>{const{t:s}=ge(),[l,r]=t.useState([]),[o,c]=t.useState(!1),[u,p]=t.useState(!1),[h,m]=t.useState(!1),[y,b]=t.useState(null),[_,k]=t.useState(null),[R,P]=t.useState(!1),[z,N]=t.useState(!1),[A,M]=t.useState(!1),[O,D]=t.useState({content:"",publishDate:new Date,type:"default",extra:""}),[L,B]=t.useState(1),[F,W]=t.useState(10),[J,U]=t.useState([]),[V,K]=t.useState(!0),[G,q]=t.useState(null),$=an(e?.["translation_setting.enabled"]),H=t.useRef(null),Q=[{value:"default",label:s("默认")},{value:"ongoing",label:s("进行中")},{value:"success",label:s("成功")},{value:"warning",label:s("警告")},{value:"error",label:s("错误")}],X=e=>({default:"grey",ongoing:"blue",success:"green",warning:"orange",error:"red"}[e]||"grey"),Y=[{title:s("内容"),dataIndex:"content",key:"content",render:e=>n.jsx(f,{content:e,position:"topLeft",showArrow:!0,children:n.jsx("div",{style:{maxWidth:"300px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e})})},{title:s("发布时间"),dataIndex:"publishDate",key:"publishDate",width:180,render:e=>n.jsxs("div",{children:[n.jsx("div",{style:{fontWeight:"bold"},children:Ce(e)}),n.jsx("div",{style:{fontSize:"12px",color:"hsl(var(--muted-foreground))",marginTop:"2px"},children:e?we(new Date(e)):"-"})]})},{title:s("类型"),dataIndex:"type",key:"type",width:100,render:e=>n.jsx(j,{color:X(e),shape:"circle",children:Q.find(t=>t.value===e)?.label||e})},{title:s("说明"),dataIndex:"extra",key:"extra",render:e=>n.jsx(f,{content:e||"-",showArrow:!0,children:n.jsx("div",{style:{maxWidth:"200px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"hsl(var(--muted-foreground))"},children:e||"-"})})},{title:s("翻译"),key:"translation_status",width:110,render:(e,t)=>n.jsx(hn,{item:t,fields:mn,onClick:()=>q(t)})},{title:s("操作"),key:"action",fixed:"right",width:220,render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(Ge,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>q(t),children:s("译文")}),n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>ee(t),children:s("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",onClick:()=>te(t),children:s("删除")})]})}],Z=async()=>{try{N(!0);let e=l;const t=JSON.stringify(e);await(async(e,t)=>
1{const n=await ye.put("/api/option/admin",{key:"console_setting.announcements",value:t}),{success:l,message:a}=n.data;l?(be(s("系统公告已更新")),i&&i()):je(a)})(0,t),M(!1)}catch(e){console.error("系统公告更新失败",e),je(s("系统公告更新失败"))}finally{N(!1)}},ee=e=>{k(e),D({content:e.content,publishDate:e.publishDate?new Date(e.publishDate):new Date,type:e.type||"default",extra:e.extra||""}),c(!0)},te=e=>{b(e),p(!0)};t.useEffect(()=>{const t=e["console_setting.announcements"]??e.Announcements;void 0!==t&&(e=>{if(e)try{const t=JSON.parse(e),n=(Array.isArray(t)?t:[]).map((e,t)=>({...e,id:e.id||t+1}));r(n)}catch(t){console.error("解析系统公告失败:",t),r([])}else r([])})(t)},[e["console_setting.announcements"],e.Announcements]),t.useEffect(()=>{const t=e["console_setting.announcements_enabled"];K(void 0===t||"true"===t||!0===t)},[e["console_setting.announcements_enabled"]]);const ne={selectedRowKeys:J,onChange:(e,t)=>{U(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsxs("div",{className:"mb-2",children:[n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(Xe,{size:16,className:"mr-2"}),n.jsx(yn,{children:s("系统公告管理,可以发布系统通知和重要消息(最多100个,前端显示最新20条)")})]}),$&&n.jsxs("div",{className:"flex items-center text-amber-500 mt-1",children:[n.jsx(Ge,{size:14,className:"mr-2"}),n.jsx(yn,{type:"warning",size:"small",children:s('已开启自动翻译:点击"触发翻译"或"保存设置",将对未翻译/原文已改的条目自动翻译为 6 种语言(翻译在保存时同步执行,需稍等)')})]})]}),n.jsx(I,{margin:"12px"}),n.jsxs("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:[n.jsxs("div",{className:"flex gap-2 w-full md:w-auto order-2 md:order-1",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"w-full md:w-auto",onClick:()=>{k(null),D({content:"",publishDate:new Date,type:"default",extra:""}),c(!0)},children:s("添加公告")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===J.length)return void je(s("请先选择要删除的系统公告"));const e=l.filter(e=>!J.includes(e.id));r(e),U([]),M(!0),be(s('已删除 {{count}} 个系统公告,请及时点击"保存设置"进行保存',{count:J.length}))},disabled:0===J.length,className:"w-full md:w-auto",children:[s("批量删除")," ",J.length>0&&`(${J.length})`]}),n.jsx(d,{icon:n.jsx(Ze,{size:14}),onClick:Z,loading:z,disabled:!A,type:"secondary",className:"w-full md:w-auto",children:s("保存设置")}),$&&n.jsx(f,{content:s("对所有未翻译/原文已改的条目触发翻译,无需修改公告内容"),children:n.jsx(d,{icon:n.jsx(et,{size:14}),onClick:Z,loading:z,type:"tertiary",className:"w-full md:w-auto",children:s("触发翻译")})})]}),n.jsxs("div",{className:"order-1 md:order-2 flex items-center gap-2",children:[n.jsx(E,{checked:V,onChange:async e=>{const t=e?"true":"false";try{const n=await ye.put("/api/option/admin",{key:"console_setting.announcements_enabled",value:t});n.data.success?(K(e),be(s("设置已保存")),i?.()):je(n.data.message)}catch(n){je(n.message)}}}),n.jsx(yn,{children:s(V?"已启用":"已禁用")})]})]})]}),children:n.jsx(v,{columns:Y,dataSource:(()=>{const e=[...l].sort((e,t)=>{const n=new Date(e.publishDate).getTime();return new Date(t.publishDate).getTime()-n}),t=(L-1)*F,n=t+F;return e.slice(t,n)})(),rowSelection:ne,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:L,pageSize:F,total:l.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:e=>s("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:l.length}),pageSizeOptions:["5","10","20","50"],onChange:(e,t)=>
1{B(e),W(t)},onShowSizeChange:(e,t)=>{B(1),W(t)}},size:"middle",loading:z,empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:s("暂无系统公告"),style:{padding:30}}),className:"overflow-hidden"})}),n.jsx(x,{title:s(_?"编辑公告":"添加公告"),visible:o,onOk:async()=>{if(O.content&&O.publishDate)try{P(!0);const e={...O,publishDate:O.publishDate.toISOString()};let t;if(_)t=l.map(t=>t.id===_.id?{...t,...e}:t);else{const n={id:Math.max(...l.map(e=>e.id),0)+1,...e};t=[...l,n]}r(t),M(!0),c(!1),be(s(_?'公告已更新,请及时点击"保存设置"进行保存':'公告已添加,请及时点击"保存设置"进行保存'))}catch(e){je(s("操作失败")+": "+e.message)}finally{P(!1)}else je(s("请填写完整的公告信息"))},onCancel:()=>c(!1),okText:s("保存"),cancelText:s("取消"),confirmLoading:R,children:n.jsxs(a,{layout:"vertical",initValues:O,getFormApi:e=>H.current=e,children:[n.jsx(a.TextArea,{field:"content",label:s("公告内容"),placeholder:s("请输入公告内容(支持 Markdown/HTML)"),maxCount:500,rows:3,rules:[{required:!0,message:s("请输入公告内容")}],onChange:e=>D({...O,content:e})}),n.jsx(d,{theme:"light",type:"tertiary",size:"small",icon:n.jsx(Qe,{size:14}),style:{marginBottom:16},onClick:()=>m(!0),children:s("放大编辑")}),n.jsx(a.DatePicker,{field:"publishDate",label:s("发布日期"),type:"dateTime",rules:[{required:!0,message:s("请选择发布日期")}],onChange:e=>D({...O,publishDate:e})}),n.jsx(a.Select,{field:"type",label:s("公告类型"),optionList:Q,onChange:e=>D({...O,type:e})}),n.jsx(a.Input,{field:"extra",label:s("说明信息"),placeholder:s("可选,公告的补充说明"),onChange:e=>D({...O,extra:e})})]},_?_.id:"new")}),n.jsx(x,{title:s("确认删除"),visible:u,onOk:()=>{if(y){const e=l.filter(e=>e.id!==y.id);r(e),M(!0),be(s('公告已删除,请及时点击"保存设置"进行保存'))}p(!1),b(null)},onCancel:()=>{p(!1),b(null)},okText:s("确认删除"),cancelText:s("取消"),type:"warning",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(yn,{children:s("确定要删除此公告吗?")})}),n.jsx(xn,{visible:!!G,onClose:()=>q(null),item:G||{},fields:gn.map(e=>({...e,label:s(e.label)})),translationEnabled:$,onApply:e=>{if(!G)return;const t=l.map(t=>t.id===G.id?{...t,...e}:t);r(t),M(!0)}}),n.jsx(x,{title:s("编辑公告内容"),visible:h,onOk:()=>{H.current&&H.current.setValue("content",O.content),m(!1)},onCancel:()=>m(!1),okText:s("确定"),cancelText:s("取消"),width:800,children:n.jsx(S,{value:O.content,placeholder:s("请输入公告内容(支持 Markdown/HTML)"),maxCount:500,rows:15,style:{width:"100%"},onChange:e=>D({...O,content:e})})})]})},{Text:fn}=u,bn=["question","answer"],_n=[{key:"question",label:"问题标题",type:"input",maxLength:200},{key:"answer",label:"回答内容",type:"textarea",rows:6,maxCount:1e3}],Sn=({options:e,refresh:i})=>{const{t:s}=ge(),[l,r]=t.useState([]),[o,c]=t.useState(!1),[u,p]=t.useState(!1),[h,m]=t.useState(null),[y,j]=t.useState(null),[b,_]=t.useState(!1),[S,k]=t.useState(!1),[R,P]=t.useState(!1),[z,N]=t.useState({question:"",answer:""}),[A,M]=t.useState(1),[O,D]=t.useState(10),[L,B]=t.useState([]),[F,W]=t.useState(!0),[J,U]=t.useState(null),V=an(e?.["translation_setting.enabled"]),K=[{title:s("问题标题"),dataIndex:"question",key:"question",render:e=>n.jsx(f,{content:e,showArrow:!0,children:n.jsx("div",{style:{maxWidth:"300px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontWeight:"bold"},children:e})})},{title:s("回答内容"),dataIndex:"answer",key:"answer",render:e=>n.jsx(f,{content:e,showArrow:!0,children:n.jsx("div",{style:{maxWidth:"400px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"hsl(var(--foreground) / 0.80)"},children:e})})},{title:s("翻译"),key:"translation_status",width:110,render:(e,t)=>n.jsx(hn,{item:t,fields:bn,onClick:()=>U(t)})},{title:s("操作"),key:"action",fixed:"right",width:220,render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(Ge,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>U(t),children:s("译文")}),n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>G(t),children:s("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",onClick:()=>q(t),children:s("删除")})]})}],G=e=>{j(e),N({question:e.question,answer:e.answer}),c(!0)},q=e=>{m(e),p(!0)};t.useEffect(()=>{void 0!==e["console_setting.faq"]&&(e=>{if(e)try{const t=JSON.parse(e),n=(Array.isArray(t)?t:[]).map((e,t)=>({...e,id:e.id||t+1}));r(n)}catch(t){console.error("解析常见问答失败:",t),r([])}else r([])})(e["console_setting.faq"])},[e["console_setting.faq"]]),t.useEffect(()=>{const t=e["console_setting.faq_enabled"];W(void 0===t||"true"===t||!0===t)},[e["console_setting.faq_enabled"]]);const $={selectedRowKeys:L,onChange:(e,t)=>
1{B(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsxs("div",{className:"mb-2",children:[n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(tt,{size:16,className:"mr-2"}),n.jsx(fn,{children:s("常见问答管理,为用户提供常见问题的答案(最多50个,前端显示最新20条)")})]}),V&&n.jsxs("div",{className:"flex items-center text-amber-500 mt-1",children:[n.jsx(Ge,{size:14,className:"mr-2"}),n.jsx(fn,{type:"warning",size:"small",children:"t('已开启自动翻译:保存设置时会对未翻译/原文已修改的条目自动翻译为 6 种语言')"})]})]}),n.jsx(I,{margin:"12px"}),n.jsxs("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:[n.jsxs("div",{className:"flex gap-2 w-full md:w-auto order-2 md:order-1",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"w-full md:w-auto",onClick:()=>{j(null),N({question:"",answer:""}),c(!0)},children:s("添加问答")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===L.length)return void je(s("请先选择要删除的常见问答"));const e=l.filter(e=>!L.includes(e.id));r(e),B([]),P(!0),be(s('已删除 {{count}} 个常见问答,请及时点击"保存设置"进行保存',{count:L.length}))},disabled:0===L.length,className:"w-full md:w-auto",children:[s("批量删除")," ",L.length>0&&`(${L.length})`]}),n.jsx(d,{icon:n.jsx(Ze,{size:14}),onClick:async()=>{try{k(!0);let e=l;const t=JSON.stringify(e);await(async(e,t)=>{const n=await ye.put("/api/option/admin",{key:"console_setting.faq",value:t}),{success:l,message:a}=n.data;l?(be(s("常见问答已更新")),i&&i()):je(a)})(0,t),P(!1)}catch(e){console.error("常见问答更新失败",e),je(s("常见问答更新失败"))}finally{k(!1)}},loading:S,disabled:!R,type:"secondary",className:"w-full md:w-auto",children:s("保存设置")})]}),n.jsxs("div",{className:"order-1 md:order-2 flex items-center gap-2",children:[n.jsx(E,{checked:F,onChange:async e=>{const t=e?"true":"false";try{const n=await ye.put("/api/option/admin",{key:"console_setting.faq_enabled",value:t});n.data.success?(W(e),be(s("设置已保存")),i?.()):je(n.data.message)}catch(n){je(n.message)}}}),n.jsx(fn,{children:s(F?"已启用":"已禁用")})]})]})]}),children:n.jsx(v,{columns:K,dataSource:(()=>{const e=(A-1)*O,t=e+O;return l.slice(e,t)})(),rowSelection:$,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:A,pageSize:O,total:l.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:e=>s("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:l.length}),pageSizeOptions:["5","10","20","50"],onChange:(e,t)=>
1{M(e),D(t)},onShowSizeChange:(e,t)=>{M(1),D(t)}},size:"middle",loading:S,empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:s("暂无常见问答"),style:{padding:30}}),className:"overflow-hidden"})}),n.jsx(x,{title:s(y?"编辑问答":"添加问答"),visible:o,onOk:async()=>{if(z.question&&z.answer)try{let e;if(_(!0),y)e=l.map(e=>e.id===y.id?{...e,...z}:e);else{const t={id:Math.max(...l.map(e=>e.id),0)+1,...z};e=[...l,t]}r(e),P(!0),c(!1),be(s(y?'问答已更新,请及时点击"保存设置"进行保存':'问答已添加,请及时点击"保存设置"进行保存'))}catch(e){je(s("操作失败")+": "+e.message)}finally{_(!1)}else je(s("请填写完整的问答信息"))},onCancel:()=>c(!1),okText:s("保存"),cancelText:s("取消"),confirmLoading:b,width:800,children:n.jsxs(a,{layout:"vertical",initValues:z,children:[n.jsx(a.Input,{field:"question",label:s("问题标题"),placeholder:s("请输入问题标题"),maxLength:200,rules:[{required:!0,message:s("请输入问题标题")}],onChange:e=>N({...z,question:e})}),n.jsx(a.TextArea,{field:"answer",label:s("回答内容"),placeholder:s("请输入回答内容(支持 Markdown/HTML)"),maxCount:1e3,rows:6,rules:[{required:!0,message:s("请输入回答内容")}],onChange:e=>N({...z,answer:e})})]},y?y.id:"new")}),n.jsx(x,{title:s("确认删除"),visible:u,onOk:()=>{if(h){const e=l.filter(e=>e.id!==h.id);r(e),P(!0),be(s('问答已删除,请及时点击"保存设置"进行保存'))}p(!1),m(null)},onCancel:()=>{p(!1),m(null)},okText:s("确认删除"),cancelText:s("取消"),type:"warning",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(fn,{children:s("确定要删除此问答吗?")})}),n.jsx(xn,{visible:!!J,onClose:()=>U(null),item:J||{},fields:_n.map(e=>({...e,label:s(e.label)})),translationEnabled:V,onApply:e=>{if(!J)return;const t=l.map(t=>t.id===J.id?{...t,...e}:t);r(t),P(!0)}})]})},{Text:kn}=u,vn=({options:e,refresh:i})=>{const{t:s}=ge(),[l,r]=t.useState([]),[o,c]=t.useState(!1),[u,p]=t.useState(!1),[h,m]=t.useState(null),[y,j]=t.useState(null),[f,b]=t.useState(!1),[_,S]=t.useState(!1),[k,R]=t.useState(!1),[P,z]=t.useState({categoryName:"",url:"",slug:""}),[N,A]=t.useState(1),[M,O]=t.useState(10),[D,L]=t.useState([]),[B,F]=t.useState(!0),W=[{title:s("分类名称"),dataIndex:"categoryName",key:"categoryName",render:e=>n.jsx("div",{style:{fontWeight:"bold",color:"hsl(var(--foreground))"},children:e})},{title:s("Uptime Kuma地址"),dataIndex:"url",key:"url",render:e=>n.jsx("div",{style:{maxWidth:"300px",wordBreak:"break-all",fontFamily:"monospace",color:"hsl(var(--primary))"},children:e})},{title:s("状态页面Slug"),dataIndex:"slug",key:"slug",render:e=>n.jsx("div",{style:{fontFamily:"monospace",color:"hsl(var(--foreground) / 0.80)"},children:e})},{title:s("操作"),key:"action",fixed:"right",width:150,render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>J(t),children:s("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",onClick:()=>U(t),children:s("删除")})]})}],J=e=>{j(e),z({categoryName:e.categoryName,url:e.url,slug:e.slug}),c(!0)},U=e=>{m(e),p(!0)};t.useEffect(()=>{const t=e["console_setting.uptime_kuma_groups"];void 0!==t&&(e=>{if(e)try{const t=JSON.parse(e),n=(Array.isArray(t)?t:[]).map((e,t)=>({...e,id:e.id||t+1}));r(n)}catch(t){console.error("解析Uptime Kuma配置失败:",t),r([])}else r([])})(t)},[e["console_setting.uptime_kuma_groups"]]),t.useEffect(()=>{const t=e["console_setting.uptime_kuma_enabled"];F(void 0===t||"true"===t||!0===t)},[e["console_setting.uptime_kuma_enabled"]]);const V={selectedRowKeys:D,onChange:(e,t)=>
1{L(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsx("div",{className:"mb-2",children:n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(nt,{size:16,className:"mr-2"}),n.jsx(kn,{children:s("Uptime Kuma监控分类管理,可以配置多个监控分类用于服务状态展示(最多20个)")})]})}),n.jsx(I,{margin:"12px"}),n.jsxs("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:[n.jsxs("div",{className:"flex gap-2 w-full md:w-auto order-2 md:order-1",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"w-full md:w-auto",onClick:()=>{j(null),z({categoryName:"",url:"",slug:""}),c(!0)},children:s("添加分类")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===D.length)return void je(s("请先选择要删除的分类"));const e=l.filter(e=>!D.includes(e.id));r(e),L([]),R(!0),be(s('已删除 {{count}} 个分类,请及时点击"保存设置"进行保存',{count:D.length}))},disabled:0===D.length,className:"w-full md:w-auto",children:[s("批量删除")," ",D.length>0&&`(${D.length})`]}),n.jsx(d,{icon:n.jsx(Ze,{size:14}),onClick:async()=>{try{S(!0);const e=JSON.stringify(l);await(async(e,t)=>{const n=await ye.put("/api/option/admin",{key:"console_setting.uptime_kuma_groups",value:t}),{success:l,message:a}=n.data;l?(be(s("Uptime Kuma配置已更新")),i&&i()):je(a)})(0,e),R(!1)}catch(e){console.error("Uptime Kuma配置更新失败",e),je(s("Uptime Kuma配置更新失败"))}finally{S(!1)}},loading:_,disabled:!k,type:"secondary",className:"w-full md:w-auto",children:s("保存设置")})]}),n.jsxs("div",{className:"order-1 md:order-2 flex items-center gap-2",children:[n.jsx(E,{checked:B,onChange:async e=>{const t=e?"true":"false";try{const n=await ye.put("/api/option/admin",{key:"console_setting.uptime_kuma_enabled",value:t});n.data.success?(F(e),be(s("设置已保存")),i?.()):je(n.data.message)}catch(n){je(n.message)}}}),n.jsx(kn,{children:s(B?"已启用":"已禁用")})]})]})]}),children:n.jsx(v,{columns:W,dataSource:(()=>{const e=(N-1)*M,t=e+M;return l.slice(e,t)})(),rowSelection:V,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:N,pageSize:M,total:l.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:e=>s("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:l.length}),pageSizeOptions:["5","10","20","50"],onChange:(e,t)=>
1{A(e),O(t)},onShowSizeChange:(e,t)=>{A(1),O(t)}},size:"middle",loading:_,empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:s("暂无监控数据"),style:{padding:30}}),className:"overflow-hidden"})}),n.jsx(x,{title:s(y?"编辑分类":"添加分类"),visible:o,onOk:async()=>{if(P.categoryName&&P.url&&P.slug){try{new URL(P.url)}catch(e){return void je(s("请输入有效的URL地址"))}if(/^[a-zA-Z0-9_-]+$/.test(P.slug))try{let e;if(b(!0),y)e=l.map(e=>e.id===y.id?{...e,...P}:e);else{const t={id:Math.max(...l.map(e=>e.id),0)+1,...P};e=[...l,t]}r(e),R(!0),c(!1),be(s(y?'分类已更新,请及时点击"保存设置"进行保存':'分类已添加,请及时点击"保存设置"进行保存'))}catch(e){je(s("操作失败")+": "+e.message)}finally{b(!1)}else je(s("Slug只能包含字母、数字、下划线和连字符"))}else je(s("请填写完整的分类信息"))},onCancel:()=>c(!1),okText:s("保存"),cancelText:s("取消"),confirmLoading:f,width:600,children:n.jsxs(a,{layout:"vertical",initValues:P,children:[n.jsx(a.Input,{field:"categoryName",label:s("分类名称"),placeholder:s("请输入分类名称,如:OpenAI、Claude等"),maxLength:50,rules:[{required:!0,message:s("请输入分类名称")}],onChange:e=>z({...P,categoryName:e})}),n.jsx(a.Input,{field:"url",label:s("Uptime Kuma地址"),placeholder:s("请输入Uptime Kuma服务地址,如:https://status.example.com"),maxLength:500,rules:[{required:!0,message:s("请输入Uptime Kuma地址")}],onChange:e=>z({...P,url:e})}),n.jsx(a.Input,{field:"slug",label:s("状态页面Slug"),placeholder:s("请输入状态页面的Slug,如:my-status"),maxLength:100,rules:[{required:!0,message:s("请输入状态页面Slug")}],onChange:e=>z({...P,slug:e})})]},y?y.id:"new")}),n.jsx(x,{title:s("确认删除"),visible:u,onOk:()=>{if(h){const e=l.filter(e=>e.id!==h.id);r(e),R(!0),be(s('分类已删除,请及时点击"保存设置"进行保存'))}p(!1),m(null)},onCancel:()=>{p(!1),m(null)},okText:s("确认删除"),cancelText:s("取消"),type:"warning",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(kn,{children:s("确定要删除此分类吗?")})})]})},{Text:Cn}=u,wn=["description","route"],Tn=[{key:"route",label:"线路描述",type:"input",maxLength:50},{key:"description",label:"说明",type:"input",maxLength:200}],In=({options:e,refresh:i})=>{const{t:s}=ge(),[l,r]=t.useState([]),[o,c]=t.useState(!1),[u,p]=t.useState(!1),[h,m]=t.useState(null),[y,f]=t.useState(null),[b,_]=t.useState(!1),[S,k]=t.useState(!1),[P,z]=t.useState(!1),[N,A]=t.useState({url:"",description:"",route:"",color:"blue"}),[M,O]=t.useState(1),[D,L]=t.useState(10),[B,F]=t.useState([]),[W,J]=t.useState(!0),[U,V]=t.useState(null),K=an(e?.["translation_setting.enabled"]);t.useEffect(()=>{const t=e["console_setting.api_info"]??e.ApiInfo;void 0!==t&&(e=>{if(e)try{const t=JSON.parse(e);r(Array.isArray(t)?t:[])}catch(t){console.error("解析API信息失败:",t),r([])}else r([])})(t)},[e["console_setting.api_info"],e.ApiInfo]),t.useEffect(()=>{const t=e["console_setting.api_info_enabled"];J(void 0===t||"true"===t||!0===t)},[e["console_setting.api_info_enabled"]]);const G=[{title:"ID",dataIndex:"id"},{title:s("API地址"),dataIndex:"url",render:(e,t)=>n.jsx(j,{color:t.color,shape:"circle",style:{maxWidth:"280px"},children:e})},{title:s("线路描述"),dataIndex:"route",render:(e,t)=>n.jsx(j,{shape:"circle",children:e})},{title:s("说明"),dataIndex:"description",ellipsis:!0,render:(e,t)=>n.jsx(j,{shape:"circle",children:e||"-"})},{title:s("颜色"),dataIndex:"color",render:e=>n.jsx(R,{size:"extra-extra-small",color:e})},{title:s("翻译"),key:"translation_status",width:110,render:(e,t)=>n.jsx(hn,{item:t,fields:wn,onClick:()=>V(t)})},{title:s("操作"),fixed:"right",width:220,render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(Ge,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>V(t),children:s("译文")}),n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>{return f(e=t),A({url:e.url,description:e.description,route:e.route,color:e.color}),void c(!0);var e},children:s("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",onClick:()=>(m(t),void p(!0)),children:s("删除")})]})}],q={selectedRowKeys:B,onChange:(e,t)=>
1{F(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsxs("div",{className:"mb-2",children:[n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(it,{size:16,className:"mr-2"}),n.jsx(Cn,{children:s("API信息管理,可以配置多个API地址用于状态展示和负载均衡(最多50个)")})]}),K&&n.jsxs("div",{className:"flex items-center text-amber-500 mt-1",children:[n.jsx(Ge,{size:14,className:"mr-2"}),n.jsx(Cn,{type:"warning",size:"small",children:"t('已开启自动翻译:保存设置时会对未翻译/原文已修改的条目自动翻译为 6 种语言')"})]})]}),n.jsx(I,{margin:"12px"}),n.jsxs("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:[n.jsxs("div",{className:"flex gap-2 w-full md:w-auto order-2 md:order-1",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"w-full md:w-auto",onClick:()=>{f(null),A({url:"",description:"",route:"",color:"blue"}),c(!0)},children:s("添加API")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===B.length)return void je(s("请先选择要删除的API信息"));const e=l.filter(e=>!B.includes(e.id));r(e),F([]),z(!0),be(s('已删除 {{count}} 个API信息,请及时点击"保存设置"进行保存',{count:B.length}))},disabled:0===B.length,className:"w-full md:w-auto",children:[s("批量删除")," ",B.length>0&&`(${B.length})`]}),n.jsx(d,{icon:n.jsx(Ze,{size:14}),onClick:async()=>{try{k(!0);let e=l;const t=JSON.stringify(e);await(async(e,t)=>{const n=await ye.put("/api/option/admin",{key:"console_setting.api_info",value:t}),{success:l,message:a}=n.data;l?(be(s("API信息已更新")),i&&i()):je(a)})(0,t),z(!1)}catch(e){console.error("API信息更新失败",e),je(s("API信息更新失败"))}finally{k(!1)}},loading:S,disabled:!P,type:"secondary",className:"w-full md:w-auto",children:s("保存设置")})]}),n.jsxs("div",{className:"order-1 md:order-2 flex items-center gap-2",children:[n.jsx(E,{checked:W,onChange:async e=>{const t=e?"true":"false";try{const n=await ye.put("/api/option/admin",{key:"console_setting.api_info_enabled",value:t});n.data.success?(J(e),be(s("设置已保存")),i?.()):je(n.data.message)}catch(n){je(n.message)}}}),n.jsx(Cn,{children:s(W?"已启用":"已禁用")})]})]})]}),children:n.jsx(v,{columns:G,dataSource:(()=>{const e=(M-1)*D,t=e+D;return l.slice(e,t)})(),rowSelection:q,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:M,pageSize:D,total:l.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:e=>s("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:l.length}),pageSizeOptions:["5","10","20","50"],onChange:(e,t)=>
1{O(e),L(t)},onShowSizeChange:(e,t)=>{O(1),L(t)}},size:"middle",loading:S,empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:s("暂无API信息"),style:{padding:30}}),className:"overflow-hidden"})}),n.jsx(x,{title:s(y?"编辑API":"添加API"),visible:o,onOk:async()=>{if(N.url&&N.route&&N.description)try{let e;if(_(!0),y)e=l.map(e=>e.id===y.id?{...e,...N}:e);else{const t={id:Math.max(...l.map(e=>e.id),0)+1,...N};e=[...l,t]}r(e),z(!0),c(!1),be(s(y?'API信息已更新,请及时点击"保存设置"进行保存':'API信息已添加,请及时点击"保存设置"进行保存'))}catch(e){je(s("操作失败")+": "+e.message)}finally{_(!1)}else je(s("请填写完整的API信息"))},onCancel:()=>c(!1),okText:s("保存"),cancelText:s("取消"),confirmLoading:b,children:n.jsxs(a,{layout:"vertical",initValues:N,children:[n.jsx(a.Input,{field:"url",label:s("API地址"),placeholder:"https://api.example.com",rules:[{required:!0,message:s("请输入API地址")}],onChange:e=>A({...N,url:e})}),n.jsx(a.Input,{field:"route",label:s("线路描述"),placeholder:s("如:香港线路"),rules:[{required:!0,message:s("请输入线路描述")}],onChange:e=>A({...N,route:e})}),n.jsx(a.Input,{field:"description",label:s("说明"),placeholder:s("如:大带宽批量分析图片推荐"),rules:[{required:!0,message:s("请输入说明")}],onChange:e=>A({...N,description:e})}),n.jsx(a.Select,{field:"color",label:s("标识颜色"),optionList:[{value:"blue",label:"blue"},{value:"green",label:"green"},{value:"cyan",label:"cyan"},{value:"purple",label:"purple"},{value:"pink",label:"pink"},{value:"red",label:"red"},{value:"orange",label:"orange"},{value:"amber",label:"amber"},{value:"yellow",label:"yellow"},{value:"lime",label:"lime"},{value:"light-green",label:"light-green"},{value:"teal",label:"teal"},{value:"light-blue",label:"light-blue"},{value:"indigo",label:"indigo"},{value:"violet",label:"violet"},{value:"grey",label:"grey"}],onChange:e=>A({...N,color:e}),render:e=>n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[n.jsx(R,{size:"extra-extra-small",color:e.value}),e.label]})})]},y?y.id:"new")}),n.jsx(x,{title:s("确认删除"),visible:u,onOk:()=>{if(h){const e=l.filter(e=>e.id!==h.id);r(e),z(!0),be(s('API信息已删除,请及时点击"保存设置"进行保存'))}p(!1),m(null)},onCancel:()=>{p(!1),m(null)},okText:s("确认删除"),cancelText:s("取消"),type:"warning",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(Cn,{children:s("确定要删除此API信息吗?")})}),n.jsx(xn,{visible:!!U,onClose:()=>V(null),item:U||{},fields:Tn.map(e=>({...e,label:s(e.label)})),translationEnabled:K,onApply:e=>{if(!U)return;const t=l.map(t=>t.id===U.id?{...t,...e}:t);r(t),z(!0)}})]})},En=()=>{const{t:e}=ge();let[i,s]=t.useState({"console_setting.api_info":"","console_setting.announcements":"","console_setting.faq":"","console_setting.uptime_kuma_groups":"","console_setting.api_info_enabled":"","console_setting.announcements_enabled":"","console_setting.faq_enabled":"","console_setting.uptime_kuma_enabled":"","translation_setting.enabled":!1,DataExportEnabled:!1,DataExportDefaultTime:"hour",DataExportInterval:5}),[l,a]=t.useState(!1);async function o(){try{a(!0),await(async()=>{const e=await ye.get("/api/option/admin"),{success:t,message:n,data:l}=e.data;if(t){let e={};l.forEach(t=>{t.key in i&&(e[t.key]=t.value),t.key.endsWith("Enabled")&&"DataExportEnabled"===t.key&&(e[t.key]=an(t.value)),"translation_setting.enabled"===t.key&&(e[t.key]=an(t.value))}),s(e)}else je(n)})()}catch(t){je(e("刷新失败")),console.error(t)}finally{a(!1)}}return t.useEffect(()=>{o()},[]),n.jsx(n.Fragment,{children:n.jsxs(m,{spinning:l,size:"large",children:[n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(pn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(jn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(In,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Sn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(vn,{options:i,refresh:o})})]})})},Rn=()=>{const{t:e}=ge();let[i,s]=t.useState({Notice:"",NoticeI18n:"",SystemName:"",SystemNameEn:"",Logo:"",Footer:"",About:"",HomePageContent:""}),[l,u]=t.useState(!1);const[p,m]=t.useState(!1),[y,b]=t.useContext(Te),[_,S]=t.useState({tag_name:"",content:""}),k=async(e,t)=>{u(!0);const n=await ye.put("/api/option/",{key:e,value:t}),{success:i,message:l}=n.data;i?s(n=>({...n,[e]:t})):je(l),u(!1)},[v,C]=t.useState([]),[w,T]=t.useState(!1),[I,E]=t.useState({Notice:!1,SystemName:!1,SystemNameEn:!1,Logo:!1,HomePageContent:!1,About:!1,Footer:!1,CheckUpdate:!1}),R=async(e,t)=>{const n=t.target.id;s(t=>({...t,[n]:e}))},z=t.useRef(),N=t.useRef();return t.useEffect(()=>{(async()=>{const e=await ye.get("/api/option/"),{success:t,message:n,data:l}=e.data;if(t){let e={};if(l.forEach(t=>{t.key in i&&(e[t.key]=t.value)}),e.NoticeI18n){const t=Nt(e.NoticeI18n);"structured"===t.type?C(Object.keys(t.texts||{}).filter(e=>"zh"!==e)):C([])}s(e),z.current.setValues(e),N.current.setValues(e)}else je(n)})()},[]),n.jsxs(o,{children:[n.jsxs(c,{span:24,style:{marginTop:"10px",display:"flex",flexDirection:"column",gap:"10px"},children:[n.jsx(a,{children:n.jsx(r,{children:n.jsxs(a.Section,{text:e("系统信息"),children:[n.jsx(o,{children:n.jsx(c,{span:16,children:n.jsxs(g,{children:[n.jsxs(P,{children:[e("当前版本"),":",y?.status?.version||e("未知")]}),n.jsx(d,{type:"primary",onClick:async()=>{try{E(e=>({...e,CheckUpdate:!0}));const t=await fetch("https://api.github.com/repos/Calcium-Ion/new-api/releases/latest",{headers:{Accept:"application/json","Content-Type":"application/json","User-Agent":"new-api-update-checker"}}).then(e=>e.json()),{tag_name:n,body:i}=t;n===y?.status?.version?be(e("已是最新版本:{{version}}",{version:n})):(S({tag_name:n,content:zt.parse(i)}),m(!0))}catch(t){console.error("Failed to check for updates:",t),je(e("检查更新失败,请稍后再试"))}finally{E(e=>({...e,CheckUpdate:!1}))}},loading:I.CheckUpdate,children:e("检查更新")})]})})}),n.jsx(o,{children:n.jsx(c,{span:16,children:n.jsxs(P,{children:[e("启动时间"),":",(()=>{const e=y?.status?.start_time;return y.status?Ie(e):""})()]})})})]})})}),n.jsx(a,{values:i,getFormApi:e=>z.current=e,children:n.jsx(r,{children:n.jsxs(a.Section,{text:e("通用设置"),children:[n.jsx(a.TextArea,{label:e("公告"),placeholder:e("在此输入新的公告内容,支持 Markdown & HTML 代码"),field:"Notice",onChange:R,style:{fontFamily:"JetBrains Mono, Consolas"},autosize:{minRows:6,maxRows:12}}
1),n.jsxs(g,{align:"center",style:{flexWrap:"wrap",gap:8},children:[n.jsx(d,{onClick:async()=>{try{E(e=>({...e,Notice:!0})),await k("Notice",i.Notice),await k("NoticeI18n",""),C([]),be(e("公告已更新"))}catch(t){console.error(e("公告更新失败"),t),je(e("公告更新失败"))}finally{E(e=>({...e,Notice:!1}))}},loading:I.Notice,children:e("设置公告")}),n.jsx(f,{content:e("自动提取段落文本占位符,再通过 AI 翻译为 6 种语言,保存为结构化公告"),children:n.jsx(d,{icon:n.jsx(Ge,{size:14}),type:"secondary",onClick:async()=>{const t=i.Notice||"";if(t.trim()){T(!0);try{const n=zt.parse(t),i=await ye.post("/api/notice/extract-and-translate",{content:n}),{success:s,message:l,data:a}=i.data;if(!s)return void je(l);const r={original:n,template:a.template,texts:a.texts};await k("NoticeI18n",JSON.stringify(r));const o=Object.keys(a.texts||{}).filter(e=>"zh"!==e);if(C(o),be(e("公告已翻译为 {{count}} 种语言",{count:o.length})),a.errors&&Object.keys(a.errors).length>0){const t=Object.keys(a.errors).join(", ");je(e("部分语言翻译失败")+": "+t)}}catch(n){je(e("翻译失败")+": "+n.message)}finally{T(!1)}}else je(e("请先填写公告内容"))},loading:w,children:e("提取并翻译")})}),v.length>0&&n.jsxs(j,{color:"green",size:"small",children:[e("已翻译 {{count}} 语言",{count:v.length}),":",v.join(" / ")]})]})]})})}),n.jsx(a,{values:i,getFormApi:e=>N.current=e,children:n.jsx(r,{children:n.jsxs(a.Section,{text:e("个性化设置"),children:[n.jsx(a.Input,{label:e("系统名称"),placeholder:e("在此输入系统名称"),field:"SystemName",onChange:R}),n.jsx(d,{onClick:async()=>{try{E(e=>({...e,SystemName:!0})),await k("SystemName",i.SystemName),be(e("系统名称已更新"))}catch(t){console.error(e("系统名称更新失败"),t),je(e("系统名称更新失败"))}finally{E(e=>({...e,SystemName:!1}))}},loading:I.SystemName,children:e("设置系统名称")}),n.jsx(a.Input,{label:e("系统名称(英文)"),placeholder:e("在此输入英文系统名称"),field:"SystemNameEn",onChange:R}),n.jsx(d,{onClick:async()=>{try{E(e=>({...e,SystemNameEn:!0})),await k("SystemNameEn",i.SystemNameEn),be(e("英文系统名称已更新"))}catch(t){console.error(e("英文系统名称更新失败"),t),je(e("英文系统名称更新失败"))}finally{E(e=>({...e,SystemNameEn:!1}))}},loading:I.SystemNameEn,children:e("设置英文系统名称")}),n.jsx(a.Input,{label:e("Logo 图片地址"),placeholder:e("在此输入 Logo 图片地址"),field:"Logo",onChange:R}),n.jsx(d,{onClick:async()=>{try{E(e=>({...e,Logo:!0})),await k("Logo",i.Logo),be(e("Logo 已更新"))}catch(t){console.error("Logo 更新失败",t),je(e("Logo 更新失败"))}finally{E(e=>({...e,Logo:!1}))}},loading:I.Logo,children:e("设置 Logo")}),n.jsx(a.TextArea,{label:e("首页内容"),placeholder:e("other_hint_002"),field:"HomePageContent",onChange:R,style:{fontFamily:"JetBrains Mono, Consolas"},autosize:{minRows:6,maxRows:12}}),n.jsx(d,{onClick:()=>(async t=>{try{E(e=>({...e,HomePageContent:!0})),await k(t,i[t]),be(e("首页内容已更新"))}catch(n){console.error("首页内容更新失败",n),je(e("首页内容更新失败"))}finally{E(e=>({...e,HomePageContent:!1}))}})("HomePageContent"),loading:I.HomePageContent,children:e("设置首页内容")}),n.jsx(a.TextArea,{label:e("关于"),placeholder:e("other_hint_001"),field:"About",onChange:R,style:{fontFamily:"JetBrains Mono, Consolas"},autosize:{minRows:6,maxRows:12}}),n.jsx(d,{onClick:async()=>{try{E(e=>({...e,About:!0})),await k("About",i.About),be(e("关于内容已更新"))}catch(t){console.error("关于内容更新失败",t),je(e("关于内容更新失败"))}finally{E(e=>({...e,About:!1}))}},loading:I.About,children:e("设置关于")}),n.jsx(h,{fullMode:!1,type:"info",description:e("移除 One API 的版权标识必须首先获得授权,项目维护需要花费大量精力,如果本项目对你有意义,请主动支持本项目"),closeIcon:null,style:{marginTop:15}}),n.jsx(a.Input,{label:e("页脚"),placeholder:e("在此输入新的页脚,留空则使用默认页脚,支持 HTML 代码"),field:"Footer",onChange:R}),n.jsx(d,{onClick:async()=>{try{E(e=>({...e,Footer:!0})),await k("Footer",i.Footer),be(e("页脚内容已更新"))}catch(t){console.error("页脚内容更新失败",t),je(e("页脚内容更新失败"))}finally{E(e=>({...e,Footer:!1}))}},loading:I.Footer,children:e("设置页脚")})]})})})]}),n.jsx(x,{title:e("新版本")+":"+_.tag_name,visible:p,onCancel:()=>m(!1),footer:[n.jsx(d,{type:"primary",onClick:()=>{m(!1),window.open(`https://github.com/Calcium-Ion/new-api/releases/tag/${_.tag_name}`,"_blank")},children:e("详情")},"details")],children:n.jsx("div",{dangerouslySetInnerHTML:{__html:_.content}})})]})},{Text:Pn}=u;function zn(e){const{t:i}=ge(),[s,l]=t.useState(!1),[u,p]=t.useState(!1),[g,y]=t.useState({TopUpLink:"","general_setting.docs_link":"",CurrencyType:"USD",CustomCurrencySymbol:"$",CustomCurrencyExchangeRate:"",QuotaPerUnit:"",RetryTimes:"",USDExchangeRate:"",DisplayTokenStatEnabled:!1,DefaultCollapseSidebar:!1,DemoSiteEnabled:!1,SelfUseModeEnabled:!1,CustomMenuLinks:""}),j=t.useRef(),[f,b]=t.useState(g),[_,S]=t.useState([]),v=(e,t,n
1)=>{const i=[..._];i[e]={...i[e],[t]:n},S(i)};function C(e){return t=>{y(n=>({...n,[e]:t}))}}const w=t.useMemo(()=>{const e=g.CurrencyType;return"USD"===e?"1":"CNY"===e?String(g.USDExchangeRate||""):"TOKENS"===e?String(g.QuotaPerUnit||""):"CUSTOM"===e?String(g.CustomCurrencyExchangeRate||""):""},[g]);function T(){const t=JSON.stringify(_.filter(e=>e.name&&e.url)),n={...g,CustomMenuLinks:t};g.CustomCurrencyExchangeRate,f.CustomCurrencyExchangeRate;const s=ke(n,f);if(!s.length)return ve(i("你似乎并没有修改什么"));const a=s.map(e=>{let t="";return t="boolean"==typeof n[e.key]?String(n[e.key]):n[e.key],ye.put(Se(),{key:e.key,value:t})});l(!0),Promise.all(a).then(t=>{if(1===a.length){if(t.includes(void 0))return}else if(a.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})}return t.useEffect(()=>{const t={...g};for(let i in e.options)Object.keys(g).includes(i)&&(t[i]=e.options[i]);if(void 0===t.CurrencyType&&void 0!==e.options?.DisplayInCurrencyEnabled&&(t.CurrencyType=e.options.DisplayInCurrencyEnabled?"USD":"TOKENS"),t.CurrencyType||(t.CurrencyType="USD"),t.CustomCurrencySymbol||(t.CustomCurrencySymbol="$"),void 0!==t.CustomCurrencyExchangeRate&&""!==t.CustomCurrencyExchangeRate||(t.CustomCurrencyExchangeRate="1"),void 0!==t.USDExchangeRate&&""!==t.USDExchangeRate||(t.USDExchangeRate="7.3"),void 0!==t.QuotaPerUnit&&""!==t.QuotaPerUnit||(t.QuotaPerUnit="500000"),y(t),b(structuredClone(t)),j.current&&j.current.setValues(t),e.options.CustomMenuLinks)try{const t=JSON.parse(e.options.CustomMenuLinks);Array.isArray(t)&&S(t)}catch(n){console.error("解析自定义菜单链接失败",n)}},[e.options]),n.jsxs(n.Fragment,{children:[n.jsx(m,{spinning:s,children:n.jsxs(a,{values:g,getFormApi:e=>j.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:i("通用设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"TopUpLink",label:i("充值链接"),initValue:"",placeholder:i("例如发卡网站的购买链接"),onChange:C("TopUpLink"),showClear:!0})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"general_setting.docs_link",label:i("文档地址"),initValue:"",placeholder:i("例如 https://docs.newapi.pro"),onChange:C("general_setting.docs_link"),showClear:!0})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"RetryTimes",label:i("失败重试次数"),initValue:"",placeholder:i("失败重试次数"),onChange:C("RetryTimes"),showClear:!0})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Slot,{label:i("站点额度展示类型及汇率"),children:n.jsxs(z,{style:{width:"100%"},children:[n.jsx(k,{prefix:"1 USD = ",style:{width:"50%"},value:w,onChange:e=>{const t=g.CurrencyType;"CNY"===t?C("USDExchangeRate")(e):"TOKENS"===t?C("QuotaPerUnit")(e):"CUSTOM"===t&&C("CustomCurrencyExchangeRate")(e)},disabled:"USD"===g.CurrencyType}),n.jsxs(N,{style:{width:"50%"}
1,value:g.CurrencyType,onChange:C("CurrencyType"),children:[n.jsx(N.Option,{value:"USD",children:"USD ($)"}),n.jsx(N.Option,{value:"CNY",children:"CNY (¥)"}),n.jsx(N.Option,{value:"TOKENS",children:"Tokens"}),n.jsx(N.Option,{value:"CUSTOM",children:i("自定义货币")})]})]})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"CustomCurrencySymbol",label:i("自定义货币符号"),initValue:"$",placeholder:i("例如 €, £, Rp, ₩, ₹..."),onChange:C("CustomCurrencySymbol"),showClear:!0,disabled:"CUSTOM"!==g.CurrencyType})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"DisplayTokenStatEnabled",label:i("额度查询接口返回令牌额度而非用户额度"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:C("DisplayTokenStatEnabled")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"DefaultCollapseSidebar",label:i("默认折叠侧边栏"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:C("DefaultCollapseSidebar")})})]}),n.jsxs(o,{children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"DemoSiteEnabled",label:i("演示站点模式"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:C("DemoSiteEnabled")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"SelfUseModeEnabled",label:i("自用模式"),extraText:i("开启后不限制:必须设置模型倍率"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:C("SelfUseModeEnabled")})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:T,children:i("保存通用设置")})})]}),n.jsxs(a.Section,{text:i("自定义菜单链接"),children:[n.jsx(Pn,{type:"tertiary",style:{display:"block",marginBottom:16},children:i("添加自定义菜单链接,将在顶部导航栏和侧边栏中显示,点击后跳转到指定地址")}),_.map((e,t)=>n.jsx(r,{style:{marginBottom:16},title:`${i("链接")} ${t+1}`,headerExtraContent:n.jsx(d,{type:"danger",theme:"borderless",icon:n.jsx(He,{size:16}),onClick:()=>(e=>{const t=[..._];t.splice(e,1),S(t)})(t),children:i("删除")}),children:n.jsxs(o,{gutter:16,children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx(Pn,{strong:!0,children:i("名称")}),n.jsx(Pn,{type:"tertiary",style:{marginLeft:8},children:i("显示在菜单中的名称")})]}),n.jsx(k,{value:e.name,onChange:e=>v(t,"name",e),placeholder:i("例如:帮助中心"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx(Pn,{strong:!0,children:i("链接地址")}),n.jsx(Pn,{type:"tertiary",style:{marginLeft:8},children:i("点击后跳转的URL")})]}),n.jsx(k,{value:e.url,onChange:e=>v(t,"url",e),placeholder:i("例如:https://help.example.com"),style:{width:"100%"}})]})]})},t)),n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>{S([..._,{name:"",url:""}])},style:{marginBottom:16},children:i("添加链接")}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:T,children:i("保存自定义菜单链接")})})]})]})}),n.jsx(x,{title:i("警告"),visible:u,onOk:()=>p(!1),onCancel:()=>p(!1),closeOnEsc:!0,width:500,children:n.jsx(h,{type:"warning",description:i("此设置用于系统内部计算,默认值500000是为了精确到6位小数点设计,不推荐修改。"),bordered:!0,fullMode:!1,closeIcon:null})})]})}function Nn(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({CheckSensitiveEnabled:!1,CheckSensitiveOnPromptEnabled:!1,SensitiveWords:"",SensitiveCheckWhitelistUserIds:"",ChannelSpecifyWhitelistEnabled:!1,ChannelSpecifyWhitelistUserIds:""}),p=t.useRef(),[h,x]=t.useState(r);return t.useEffect(()=>{const t={};for(let n in r)t[n]=void 0!==e.options[n]?e.options[n]:r[n];u(t),x(structuredClone(t)),p.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("屏蔽词过滤设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"CheckSensitiveEnabled",label:i("启用屏蔽词过滤功能"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{u({...r,CheckSensitiveEnabled:e})}})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"CheckSensitiveOnPromptEnabled",label:i("启用 Prompt 检查"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>u({...r,CheckSensitiveOnPromptEnabled:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"ChannelSpecifyWhitelistEnabled",label:i("启用指定渠道ID白名单"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>u({...r,ChannelSpecifyWhitelistEnabled:e})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.TextArea,{label:i("屏蔽词列表"),extraText:i("一行一个屏蔽词,不需要符号分割"),placeholder:i("一行一个屏蔽词,不需要符号分割"),field:"SensitiveWords",onChange:e=>u({...r,SensitiveWords:e}),style:{fontFamily:"JetBrains Mono, Consolas"},autosize:{minRows:6,maxRows:12}}
1)}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.TextArea,{label:i("白名单用户ID列表"),extraText:i("一行一个用户ID,这些用户将跳过敏感词检测"),placeholder:i("一行一个用户ID"),field:"SensitiveCheckWhitelistUserIds",onChange:e=>u({...r,SensitiveCheckWhitelistUserIds:e}),style:{fontFamily:"JetBrains Mono, Consolas"},autosize:{minRows:6,maxRows:12}})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.TextArea,{label:i("指定渠道ID白名单用户列表"),extraText:i("一行一个用户ID,这些用户可使用指定渠道ID功能"),placeholder:i("一行一个用户ID"),field:"ChannelSpecifyWhitelistUserIds",onChange:e=>u({...r,ChannelSpecifyWhitelistUserIds:e}),style:{fontFamily:"JetBrains Mono, Consolas"},autosize:{minRows:6,maxRows:12}})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof r[e.key]?String(r[e.key]):r[e.key],ye.put(Se(),{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存屏蔽词过滤设置")})})]})})})})}function An(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState(!1),[p,h]=t.useState({LogConsumeEnabled:!1,LogFailureEnabled:!1,historyTimestamp:At().subtract(1,"month").toDate()}),x=t.useRef(),[g,y]=t.useState(p);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(p).includes(n)&&(t[n]=e.options[n]);t.historyTimestamp=p.historyTimestamp,h(Object.assign(p,t)),y(structuredClone(t)),x.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:p,getFormApi:e=>x.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("日志设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"LogConsumeEnabled",label:i("启用额度消费日志记录"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{h({...p,LogConsumeEnabled:e})}})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"LogFailureEnabled",label:i("启用失败日志记录"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{h({...p,LogFailureEnabled:e})}})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsxs(m,{spinning:r,children:[n.jsx(a.DatePicker,{label:i("日志记录时间"),field:"historyTimestamp",type:"dateTime",inputReadOnly:!0,onChange:e=>{h({...p,historyTimestamp:e})}}),n.jsx(d,{size:"default",onClick:async function(){try{if(u(!0),!p.historyTimestamp)throw new Error(i("请选择日志记录时间"));const e=await ye.delete("/api/log/?target_timestamp="+Date.parse(p.historyTimestamp)/1e3),{success:t,message:n,data:s}=e.data;if(t)return void be(i("{{count}} 条日志已清理!",{count:s}));throw new Error(i("日志清理失败:{{message}}",{message:n}))}catch(e){je(e.message)}finally{u(!1)}},children:i("清除历史日志")})]})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(p,g).filter(e=>"historyTimestamp"!==e.key);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof p[e.key]?String(p[e.key]):p[e.key],ye.put(Se(),{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存日志设置")})})]})})})})}function Mn(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({ChannelDisableThreshold:"",QuotaRemindThreshold:"",AutomaticDisableChannelEnabled:!1,AutomaticEnableChannelEnabled:!1}),p=t.useRef(),[h,x]=t.useState(r);return t.useEffect(()=>{if(!e.options||0===Object.keys(e.options).length)return;const t={},n=Object.keys(r);for(let i in e.options)n.includes(i)&&(t[i]=e.options[i]);
1n.forEach(e=>{e in t||(t[e]=r[e])}),u(t),x(structuredClone(t)),p.current&&p.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("监控设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("测试所有渠道的最长响应时间"),step:1,min:0,suffix:i("秒"),extraText:i("当运行通道全部测试时,超过此时间将自动禁用通道"),placeholder:"",field:"ChannelDisableThreshold",onChange:e=>u({...r,ChannelDisableThreshold:String(e)})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("额度提醒阈值"),step:1,min:0,suffix:"Token",extraText:i("低于此额度时将发送邮件提醒用户"),placeholder:"",field:"QuotaRemindThreshold",onChange:e=>u({...r,QuotaRemindThreshold:String(e)})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"AutomaticDisableChannelEnabled",label:i("失败时自动禁用通道"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{u({...r,AutomaticDisableChannelEnabled:e})}})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"AutomaticEnableChannelEnabled",label:i("成功时自动启用通道"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>u({...r,AutomaticEnableChannelEnabled:e})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof r[e.key]?String(r[e.key]):r[e.key],ye.put(Se(),{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存监控设置")})})]})})})})}function On(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({QuotaForNewUser:"",PreConsumedQuota:"",QuotaForInviter:"",QuotaForInvitee:""}),p=t.useRef(),[h,x]=t.useState(r);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(r).includes(n)&&(t[n]=e.options[n]);u(t),x(structuredClone(t)),p.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("额度设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("新用户初始额度"),field:"QuotaForNewUser",step:1,min:0,suffix:"Token",placeholder:"",onChange:e=>u({...r,QuotaForNewUser:String(e)})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("请求预扣费额度"),field:"PreConsumedQuota",step:1,min:0,suffix:"Token",extraText:i("请求结束后多退少补"),placeholder:"",onChange:e=>u({...r,PreConsumedQuota:String(e)})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("邀请新用户奖励额度"),field:"QuotaForInviter",step:1,min:0,suffix:"Token",extraText:"",placeholder:i("例如:2000"),onChange:e=>u({...r,QuotaForInviter:String(e)})})})]}),n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:6,children:n.jsx(a.InputNumber,{label:i("新用户使用邀请码奖励额度"),field:"QuotaForInvitee",step:1,min:0,suffix:"Token",extraText:"",placeholder:i("例如:1000"),onChange:e=>u({...r,QuotaForInvitee:String(e)})})})}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof r[e.key]?String(r[e.key]):r[e.key],ye.put(Se(),{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存额度设置")})})]})})})})}function Dn(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,p]=t.useState({"checkin_setting.enabled":!1,"checkin_setting.min_quota":1e3,"checkin_setting.max_quota":1e4}),h=t.useRef(),[x,g]=t.useState({"checkin_setting.enabled":!1,"checkin_setting.min_quota":1e3,"checkin_setting.max_quota":1e4}),[y,j]=t.useState(!1);function f(e){return t=>{p(n=>({...n,[e]:t}))}}return t.useEffect(()=>{if(!e.options)return;const t={"checkin_setting.enabled":!1,"checkin_setting.min_quota":1e3,"checkin_setting.max_quota":1e4},n="checkin_setting.enabled"in e.options||"checkin_setting.min_quota"in e.options||"checkin_setting.max_quota"in e.options;if(j(n),"checkin_setting.enabled"in e.options&&(t["checkin_setting.enabled"]=e.options["checkin_setting.enabled"]),"checkin_setting.min_quota"in e.options){const n=e.options["checkin_setting.min_quota"];t["checkin_setting.min_quota"]="number"==typeof n?n:parseInt(n)||1e3}if("checkin_setting.max_quota"in e.options){const n=e.options["checkin_setting.max_quota"];t["checkin_setting.max_quota"]="number"==typeof n?n:parseInt(n)||1e4}p(t),g(structuredClone(t)),h.current&&h.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>h.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("签到设置"),children:[n.jsx(u.Text,{type:"tertiary",style:{marginBottom:16,display:"block"},children:i("签到功能允许用户每日签到获取随机额度奖励")}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"checkin_setting.enabled",label:i("启用签到功能"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:f("checkin_setting.enabled")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"checkin_setting.min_quota",label:i("签到最小额度"),placeholder:i("签到奖励的最小额度"),onChange:f("checkin_setting.min_quota"),min:0,disabled:!r["checkin_setting.enabled"]})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"checkin_setting.max_quota",label:i("签到最大额度"),placeholder:i("签到奖励的最大额度"),onChange:f("checkin_setting.max_quota"),min:0,disabled:!r["checkin_setting.enabled"]})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,x);if(!t.length&&y)return ve(i("你似乎并没有修改什么"));const n=(y?t.map(e=>e.key):Object.keys(r)).map(e=>{let t="";return r[e],t=String(r[e]),ye.put(Se(),{key:e,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存签到设置")})})]})})})})}const Ln={"withdraw_setting.min_quota":"","withdraw_setting.max_quota":"","withdraw_setting.bound_invoice_max_per_tx_rmb":"5000","withdraw_setting.personal_daily_cap_rmb":"500","withdraw_setting.strict_payee_match":!0,"withdraw_setting.our_company_name":"","withdraw_setting.our_company_tax_no":"","aliyun_setting.invoice_ocr_app_code":"","aliyun_setting.invoice_verify_app_code":"","aliyun_setting.invoice_ocr_endpoint":"","aliyun_setting.invoice_verify_endpoint":""},Bn=new Set(["withdraw_setting.strict_payee_match"]);function Fn(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState(Ln),p=t.useRef(),[x,g]=t.useState(r);function y(){const t=ke(r,x);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof r[e.key]?String(r[e.key]):r[e.key],ye.put(Se(),{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})}return t.useEffect(()=>{const t={...Ln};for(let n in e.options)if(Object.keys(Ln).includes(n)){const i=e.options[n];Bn.has(n)?t[n]=!0===i||"true"===i||"1"===i||1===i:t[n]=i??""}u(t),g(structuredClone(t)),p.current&&p.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsxs(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:i("提现额度限制"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("最低提现额度"),field:"withdraw_setting.min_quota",step:1,min:0,suffix:"元",extraText:i("用户单次提现的最低金额,设置为0则不限制"),onChange:e=>u({...r,"withdraw_setting.min_quota":String(e??0)})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("最高提现额度"),field:"withdraw_setting.max_quota",step:1,min:0,suffix:"元",extraText:i("用户单次提现的最高金额,设置为0则不限制"),onChange:e=>u({...r,"withdraw_setting.max_quota":String(e??0)})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:y,children:i("保存提现额度限制")})})]}),n.jsxs(a.Section,{text:i("提现绑定开票"),children:[n.jsx(h,{type:"info",fullMode:!1,closeIcon:null,description:i("所有用户提现均走「提现绑定开票」流程:对私走支付宝(ä»
1…每日累计上限,免发票),对公需在提现时上传等额发票并通过审核后放款。下列字段为全局策略。"),style:{marginBottom:12}}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.InputNumber,{label:i("单笔总上限"),field:"withdraw_setting.bound_invoice_max_per_tx_rmb",step:1,min:0,suffix:"元",extraText:i("对私+对公共用的单笔上限,默认 5000(含等于)"),onChange:e=>u({...r,"withdraw_setting.bound_invoice_max_per_tx_rmb":String(e??0)})})}),n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.InputNumber,{label:i("对私每日累计上限"),field:"withdraw_setting.personal_daily_cap_rmb",step:100,min:0,suffix:"元",extraText:i("默认 500。同一用户当日对私提现累计不得超过该值,超出需走对公线"),onChange:e=>u({...r,"withdraw_setting.personal_daily_cap_rmb":String(e??0)})})}),n.jsx(c,{xs:24,sm:12,md:8,children:n.jsxs(a.Slot,{label:i("严格比对税号"),children:[n.jsx(E,{checked:!!r["withdraw_setting.strict_payee_match"],onChange:e=>u({...r,"withdraw_setting.strict_payee_match":!!e})}),n.jsx("span",{style:{marginLeft:8,color:"var(--semi-color-text-2)",fontSize:12},children:i("默认开启:发票销方公司名 + 统一信用代码 必须与对公账户完全一致")})]})})]}),n.jsx(h,{type:"warning",fullMode:!1,closeIcon:null,description:i('购方校验:填入我方公司全名与统一信用代码后,发票受票方必须完全一致才能自动通过。强烈建议生产环境必填,否则代理理论上可拿任何"已真实开具的发票"核销。留空时跳过该校验。'),style:{marginBottom:12,marginTop:8}}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,md:12,children:n.jsx(a.Input,{label:i("我方公司全名(购方校验)"),field:"withdraw_setting.our_company_name",placeholder:"示例:重庆云之雾网络科技有限公司",extraText:i("需与营业执照完全一致;留空时跳过此硬规则"),onChange:e=>u({...r,"withdraw_setting.our_company_name":e})})}),n.jsx(c,{xs:24,md:12,children:n.jsx(a.Input,{label:i("我方统一信用代码(购方校验,strict 模式生效)"),field:"withdraw_setting.our_company_tax_no",placeholder:"18 位统一社会信用代码,例如 91500105MACDM4LEXT",extraText:i('仅当上方"严格比对税号"开启时生效;留空时跳过税号校验'),onChange:e=>u({...r,"withdraw_setting.our_company_tax_no":e})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",theme:"solid",type:"primary",onClick:y,children:i("保存提现绑定开票设置")})})]}),n.jsxs(a.Section,{text:i("阿里云发票核验"),children:[n.jsx(h,{type:"info",fullMode:!1,closeIcon:null,description:i("从阿里云市场购买「发票 OCR」和「发票核验」两个 API 商品,分别拿到 AppCode 填入对应栏,并填入商品的接口地址。工商核验已在实名时完成,无需重复购买。"),style:{marginBottom:12}}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,md:12,children:n.jsx(a.Input,{label:i("发票 OCR AppCode"),field:"aliyun_setting.invoice_ocr_app_code",placeholder:"阿里云市场「我的服务」中 OCR 商品的 AppCode",onChange:e=>u({...r,"aliyun_setting.invoice_ocr_app_code":e})})}),n.jsx(c,{xs:24,md:12,children:n.jsx(a.Input,{label:i("发票核验 AppCode"),field:"aliyun_setting.invoice_verify_app_code",placeholder:"阿里云市场「我的服务」中发票核验商品的 AppCode",onChange:e=>u({...r,"aliyun_setting.invoice_verify_app_code":e})})}),n.jsx(c,{span:24,children:n.jsx(a.Input,{label:i("发票 OCR 接口地址"),field:"aliyun_setting.invoice_ocr_endpoint",placeholder:"https://dgfp.market.alicloudapi.com/ocrservice/invoice",extraText:i("推荐:阿里官方 OCR:https://dgfp.market.alicloudapi.com/ocrservice/invoice(留空时使用此默认值)"),onChange:e=>u({...r,"aliyun_setting.invoice_ocr_endpoint":e})})}),n.jsx(c,{span:24,children:n.jsx(a.Input,{label:i("发票核验接口地址"),field:"aliyun_setting.invoice_verify_endpoint",placeholder:"https://invoicech1.market.alicloudapi.com/s/api/ocr/invoiceCheck",extraText:i("推荐:快瞳 五要素核验,
1完整地址 https://invoicech1.market.alicloudapi.com/s/api/ocr/invoiceCheck (注意 host 是 invoicech1 而不是 invocheck1;路径前缀含 /s/api 不是 /api)。代码已自动用 form-urlencoded 提交,并兼容多家字段名:invoicingDate/invoiceDate、totalAmount/invoiceAmount/pretaxAmount、electronicMark/electronMark。"),onChange:e=>u({...r,"aliyun_setting.invoice_verify_endpoint":e})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:y,children:i("保存阿里云配置")})})]})]})})})}function Wn(e){const{t:i}=ge(),[s,l]=t.useState(!1),r={CostDailyAggEnabled:!1,CostDailyAggScheduleMode:"interval",CostDailyAggIntervalHours:6,CostDailyAggFixedHour:2,CostDailyAggBatchSize:1e3,CostDailyAggBacklogDays:3,CostDailyAggMinDateKey:0},[u,p]=t.useState({...r}),x=["CostDailyAggIntervalHours","CostDailyAggFixedHour","CostDailyAggBatchSize","CostDailyAggBacklogDays","CostDailyAggMinDateKey"],g=t.useRef(),[y,f]=t.useState(u),[b,_]=t.useState([]),[S,k]=t.useState(!1);function C(){k(!0),ye.get("/api/admin/cost-statistics/daily-agg-states?limit=30").then(e=>{e?.data?.success&&_(e.data.data||[])}).catch(()=>{}).finally(()=>{k(!1)})}t.useEffect(()=>{C()},[]);const w={finished:"green",running:"blue",failed:"red",skipped:"orange"},T=[{title:i("日期"),dataIndex:"date_key",width:100},{title:i("状态"),dataIndex:"status",width:100,render:e=>n.jsx(j,{color:w[e]||"grey",children:e||"-"})},{title:i("扫描行数"),dataIndex:"scanned_rows",width:110},{title:i("用户行数"),dataIndex:"user_rows",width:100},{title:i("汇总行数"),dataIndex:"summary_rows",width:100},{title:i("未配笔数"),dataIndex:"unconf_count",width:100},{title:i("重试次数"),dataIndex:"retry_count",width:90},{title:i("完成时间"),dataIndex:"finished_at",width:170,render:e=>e>0?Ie(e):"-"},{title:i("信息"),dataIndex:"message",ellipsis:!0}];return t.useEffect(()=>{if(!e.options)return;const t={...r};for(let n in r)if(n in e.options){let i=e.options[n];x.includes(n)?(i=parseInt(i),Number.isNaN(i)&&(i=r[n])):"CostDailyAggEnabled"===n&&(i="boolean"==typeof i?i:"true"===i),t[n]=i}p(t),f(structuredClone(t)),g.current&&g.current.setValues(t)},[e.options]),n.jsx(m,{spinning:s,children:n.jsxs(a,{values:u,getFormApi:e=>g.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:i("每日成本聚合"),children:[n.jsx(h,{type:"info",description:i("后台线程每天聚合昨天的使用日志、反推成本,写入成本统计(渠道/模型/时间 + 用户维度)。默认关闭;多节点部署时自动只在一个节点执行。"),style:{marginBottom:10}}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"CostDailyAggEnabled",label:i("启用每日成本聚合"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>p({...u,CostDailyAggEnabled:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Select,{field:"CostDailyAggScheduleMode",label:i("调度模式"),style:{width:"100%"},optionList:[{label:i("按间隔检查(每 N 小时)"),value:"interval"},{label:i("每天定点检查"),value:"fixed_time"}],onChange:e=>p({...u,CostDailyAggScheduleMode:e})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"CostDailyAggIntervalHours",label:i("检查间隔(小时,间隔模式)"),min:1,max:24,step:1,style:{width:"100%"},onChange:e=>p({...u,CostDailyAggIntervalHours:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"CostDailyAggFixedHour",label:i("定点小时 0-23(定点模式)"),min:0,max:23,step:1,style:{width:"100%"},onChange:e=>p({...u,CostDailyAggFixedHour:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"CostDailyAggBatchSize",label:i("分批行数(扫描/写库)"),min:100,max:1e4,step:100,style:{width:"100%"},onChange:e=>p({...u,CostDailyAggBatchSize:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"CostDailyAggBacklogDays",label:i("回看天数(须 ≤ ClickHouse 导入历史下界)"),min:1,max:30,step:1,style:{width:"100%"},onChange:e=>p({...u,CostDailyAggBacklogDays:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"CostDailyAggMinDateKey",label:i("最早可聚合日期 YYYYMMDD(0=不限,设为 ClickHouse 已导入最大日期+1)"),min:0,max:99991231,step:1,style:{width:"100%"},onChange:e=>p({...u,CostDailyAggMinDateKey:e})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(u,
1y);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>ye.put("/api/option/",{key:e.key,value:String(u[e.key])}));l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存成本聚合设置")})})]}),n.jsxs(a.Section,{text:i("聚合运行状态"),children:[n.jsx(h,{type:"info",description:i("每日成本聚合后台线程最近的运行记录(只读)。状态:finished 成功 / running 运行中 / failed 失败重试中 / skipped 连续失败已放弃(需线下补聚合)。"),style:{marginBottom:10}}),n.jsx(o,{style:{marginBottom:10},children:n.jsx(d,{size:"default",onClick:C,loading:S,children:i("刷新状态")})}),n.jsx(v,{columns:T,dataSource:b,loading:S,rowKey:"date_key",pagination:!1,size:"small"})]})]})})}const Jn=()=>{const{t:e}=ge();let[i,s]=t.useState({QuotaForNewUser:0,PreConsumedQuota:0,QuotaForInviter:0,QuotaForInvitee:0,TopUpLink:"","general_setting.docs_link":"",QuotaPerUnit:0,USDExchangeRate:0,RetryTimes:0,DisplayInCurrencyEnabled:!1,DisplayTokenStatEnabled:!1,DefaultCollapseSidebar:!1,DemoSiteEnabled:!1,SelfUseModeEnabled:!1,CustomMenuLinks:"",CheckSensitiveEnabled:!1,CheckSensitiveOnPromptEnabled:!1,SensitiveWords:"",LogConsumeEnabled:!1,ErrorLogWhitelist:"",ChannelDisableThreshold:0,QuotaRemindThreshold:0,AutomaticDisableChannelEnabled:!1,AutomaticEnableChannelEnabled:!1,AutomaticDisableKeywords:"","checkin_setting.enabled":!1,"checkin_setting.min_quota":1e3,"checkin_setting.max_quota":1e4,"withdraw_setting.min_quota":0,"withdraw_setting.max_quota":0,"withdraw_setting.bound_invoice_buffer_rmb":5e3,"withdraw_setting.bound_invoice_max_per_tx_rmb":5e3,"withdraw_setting.personal_daily_cap_rmb":500,"withdraw_setting.hard_lock_enabled":!1,"withdraw_setting.hard_lock_threshold_rmb":5e3,"withdraw_setting.strict_payee_match":!0,"withdraw_setting.our_company_name":"","withdraw_setting.our_company_tax_no":"","aliyun_setting.invoice_ocr_app_code":"","aliyun_setting.invoice_verify_app_code":"","aliyun_setting.invoice_ocr_endpoint":"","aliyun_setting.invoice_verify_endpoint":"","translation_setting.enabled":!1,"translation_setting.base_url":"","translation_setting.model":""}),[l,a]=t.useState(!1);async function o(){try{a(!0),await(async()=>{const e=await ye.get(Se()),{success:t,message:n,data:i}=e.data;if(t){let e={};i.forEach(t=>{t.key.endsWith("Enabled")||["DefaultCollapseSidebar"].includes(t.key)||"checkin_setting.enabled"===t.key||"translation_setting.enabled"===t.key?e[t.key]=an(t.value):"checkin_setting.min_quota"===t.key||"checkin_setting.max_quota"===t.key?e[t.key]=parseInt(t.value)||0:"withdraw_setting.min_quota"===t.key||"withdraw_setting.max_quota"===t.key?e[t.key]=parseFloat(t.value)||0:"withdraw_setting.hard_lock_enabled"===t.key||"withdraw_setting.strict_payee_match"===t.key?e[t.key]=an(t.value):"withdraw_setting.bound_invoice_buffer_rmb"===t.key||"withdraw_setting.bound_invoice_max_per_tx_rmb"===t.key||"withdraw_setting.personal_daily_cap_rmb"===t.key||"withdraw_setting.hard_lock_threshold_rmb"===t.key?e[t.key]=parseFloat(t.value)||0:e[t.key]=t.value}),s(e)}else je(n)})()}catch(t){je(e("刷新失败"))}finally{a(!1)}}return t.useEffect(()=>{o()},[]),n.jsx(n.Fragment,{children:n.jsxs(m,{spinning:l,size:"large",children:[n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(zn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Nn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(An,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Mn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(On,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Dn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Fn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(cn,{options:i,refresh:o})}),Ee()&&n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Wn,{options:i,refresh:o})})]})})};function Un(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({ModelRequestRateLimitEnabled:!1,ModelRequestRateLimitCount:-1,ModelRequestRateLimitSuccessCount:1e3,ModelRequestRateLimitDurationMinutes:1,ModelRequestRateLimitGroup:""}),p=t.useRef(),[h,x]=t.useState(r);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(r).includes(n)&&(t[n]=e.options[n]);u(t),x(structuredClone(t)),p.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("模型请求速率限制"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"ModelRequestRateLimitEnabled",label:i("启用用户模型请求速率限制(可能会影响高并发性能)"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{u({...r,ModelRequestRateLimitEnabled:e})}})})}),n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("限制周期"),step:1,min:0,suffix:i("分钟"),extraText:i("频率限制的周期(分钟)"),field:"ModelRequestRateLimitDurationMinutes",onChange:e=>u({...r,ModelRequestRateLimitDurationMinutes:String(e)})})})}),n.jsxs(o,{children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("用户每周期最多请求次数"),step:1,min:0,suffix:i("次"),extraText:i("包括失败请求的次数,0代表不限制"),field:"ModelRequestRateLimitCount",onChange:e=>u({...r,ModelRequestRateLimitCount:String(e)})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("用户每周期最多请求完成次数"),step:1,min:1,suffix:i("次"),extraText:i("只包括请求成功的次数"),field:"ModelRequestRateLimitSuccessCount",onChange:e=>u({...r,ModelRequestRateLimitSuccessCount:String(e)})})})]}
1),n.jsx(o,{children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:i("分组速率限制"),placeholder:i('{\n  "default": [200, 100],\n  "vip": [0, 1000]\n}'),field:"ModelRequestRateLimitGroup",autosize:{minRows:5,maxRows:15},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}],extraText:n.jsxs("div",{children:[n.jsx("p",{children:i("说明")+":"}),n.jsxs("ul",{children:[n.jsx("li",{children:i('使用 JSON 对象格式,格式为:{"组名": [最多请求次数, 最多请求完成次数]}')}),n.jsx("li",{children:i('示例:{"default": [200, 100], "vip": [0, 1000]}。')}),n.jsx("li",{children:i("[最多请求次数]必须大于等于0,[最多请求完成次数]必须大于等于1。")}),n.jsx("li",{children:i("分组速率配置优先级高于全局速率限制。")}),n.jsx("li",{children:i("限制周期统一使用上方配置的“限制周期”值。")})]})]}),onChange:e=>{u({...r,ModelRequestRateLimitGroup:e})}})})}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof r[e.key]?String(r[e.key]):r[e.key],ye.put("/api/option/",{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));for(let e=0;e<t.length;e++)if(!t[e].data.success)return je(t[e].data.message);be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存模型速率限制")})})]})})})})}const Vn=()=>{const{t:e}=ge();let[i,s]=t.useState({ModelRequestRateLimitEnabled:!1,ModelRequestRateLimitCount:0,ModelRequestRateLimitSuccessCount:1e3,ModelRequestRateLimitDurationMinutes:1,ModelErrorRequestRateLimitEnabled:!1,ModelErrorRequestRateLimitDurationMinutes:0,ModelErrorRequestRateLimitCount:0,ResponseReorderEnabled:!1,ModelRequestRateLimitGroup:""}),[l,a]=t.useState(!1);async function o(){try{a(!0),await(async()=>{const e=await ye.get("/api/option/"),{success:t,message:n,data:i}=e.data;if(t){let e={};i.forEach(t=>{"ModelRequestRateLimitGroup"===t.key&&(t.value=JSON.stringify(JSON.parse(t.value),null,2)),t.key.endsWith("Enabled")?e[t.ke
1y]=an(t.value):e[t.key]=t.value}),s(e)}else je(n)})()}catch(t){je(e("刷新失败"))}finally{a(!1)}}return t.useEffect(()=>{o()},[]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:l,size:"large",children:n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Un,{options:i,refresh:o})})})})},Kn={default:"OFF",HARM_CATEGORY_CIVIC_INTEGRITY:"BLOCK_NONE"},Gn={default:"v1beta"};function qn(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({"gemini.safety_settings":"","gemini.version_settings":"","gemini.supported_imagine_models":"","gemini.thinking_adapter_enabled":!1,"gemini.thinking_adapter_budget_tokens_percentage":.6}),p=t.useRef(),[h,x]=t.useState(r);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(r).includes(n)&&(t[n]=e.options[n]);u(t),x(structuredClone(t)),p.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsxs(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:i("Gemini设置"),children:[n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.TextArea,{label:i("Gemini安全设置"),placeholder:i("为一个 JSON 文本,例如:")+"\n"+JSON.stringify(Kn,null,2),field:"gemini.safety_settings",extraText:i("default为默认设置,可单独设置每个分类的安全等级"),autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,"gemini.safety_settings":e})})})}),n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.TextArea,{label:i("Gemini版本设置"),placeholder:i("为一个 JSON 文本,例如:")+"\n"+JSON.stringify(Gn,null,2),field:"gemini.version_settings",extraText:i("default为默认设置,可单独设置每个模型的版本"),autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,"gemini.version_settings":e})})})}),n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.TextArea,{field:"gemini.supported_imagine_models",label:i("支持的图像模型"),placeholder:i("例如:")+"\n"+JSON.stringify(["gemini-2.0-flash-exp-image-generation"],null,2),onChange:e=>u({...r,"gemini.supported_imagine_models":e}),trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}]})})})]}),n.jsxs(a.Section,{text:i("Gemini思考适配设置"),children:[n.jsx(o,{children:n.jsx(c,{span:16,children:n.jsx(P,{children:i("gemini_thinking_description")})})}),n.jsx(o,{children:n.jsx(c,{span:16,children:n.jsx(a.Switch,{label:i("启用Gemini思考后缀适配"),field:"gemini.thinking_adapter_enabled",extraText:i("适配 -thinking、-thinking-预算数字 和 -nothinking 后缀"),onChange:e=>u({...r,"gemini.thinking_adapter_enabled":e})})})}),n.jsx(o,{children:n.jsx(c,{span:16,children:n.jsx(P,{children:i("Gemini思考适配 BudgetTokens = MaxTokens * BudgetTokens 百分比")})})}),n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("思考预算占比"),field:"gemini.thinking_adapter_budget_tokens_percentage",initValue:"",extraText:i("0.002-1之间的小数"),min:.002,max:1,onChange:e=>u({...r,"gemini.thinking_adapter_budget_tokens_percentage":e})})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:async function(){await p.current.validate().then(()=>{const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t=String(r[e.key]);return ye.put("/api/option/",{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})}).catch(e=>{console.error("Validation failed:",e),je(i("请检查输入"))})},children:i("保存")})})]})})})}const $n={"claude-3-7-sonnet-20250219-thinking":{"anthropic-beta":["output-128k-2025-02-19","token-efficient-tools-2025-02-19"]}},Hn={default:8192,"claude-3-haiku-20240307":4096,"claude-3-opus-20240229":4096,"claude-3-7-sonnet-20250219-thinking":8192};function Qn(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({"claude.model_headers_settings":"","claude.thinking_adapter_enabled":!0,"claude.default_max_tokens":"","claude.thinking_adapter_budget_tokens_percentage":.8}),p=t.useRef(),[h,x]=t.useState(r);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(r).includes(n)&&(t[n]=e.options[n]);u(t),x(structuredClone(t)),p.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("Claude设置"),children:[n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.TextArea,{label:i("Claude请求头覆盖"),field:"claude.model_headers_settings",placeholder:i("为一个 JSON 文本,例如:")+"\n"+JSON.stringify($n,null,2),extraText:i("示例")+"\n"+JSON.stringify($n,null,2),autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>
1Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,"claude.model_headers_settings":e})})})}),n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.TextArea,{label:i("缺省 MaxTokens"),field:"claude.default_max_tokens",placeholder:i("为一个 JSON 文本,例如:")+"\n"+JSON.stringify(Hn,null,2),extraText:i("示例")+"\n"+JSON.stringify(Hn,null,2),autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,"claude.default_max_tokens":e})})})}),n.jsx(o,{children:n.jsx(c,{span:16,children:n.jsx(a.Switch,{label:i("启用Claude思考适配(-thinking后缀)"),field:"claude.thinking_adapter_enabled",onChange:e=>u({...r,"claude.thinking_adapter_enabled":e})})})}),n.jsx(o,{children:n.jsx(c,{span:16,children:n.jsx(P,{children:i("Claude思考适配 BudgetTokens = MaxTokens * BudgetTokens 百分比")})})}),n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("思考适配 BudgetTokens 百分比"),field:"claude.thinking_adapter_budget_tokens_percentage",initValue:"",extraText:i("0.1-1之间的小数"),min:.1,max:1,onChange:e=>u({...r,"claude.thinking_adapter_budget_tokens_percentage":e})})})}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t=String(r[e.key]);return ye.put("/api/option/",{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存")})})]})})})})}function Xn(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({"grok.violation_deduction_enabled":!1,"grok.violation_deduction_amount":.05}),p=t.useRef(),[h,x]=t.useState(r);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(r).includes(n)&&(t[n]=e.options[n]);u(t),x(structuredClone(t)),p.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("Grok 设置"),children:[n.jsx(o,{children:n.jsx(c,{span:16,children:n.jsx(a.Switch,{label:i("启用违规扣费"),field:"grok.violation_deduction_enabled",extraText:i("开启后,当上游 Grok 返回内容安全违规(如 CSAM 检查)时,在正常退费之后额外扣一笔违规费。默认关闭,确认命中准确后再开启。"),onChange:e=>u({...r,"grok.violation_deduction_enabled":e})})})}),n.jsx(o,{children:n.jsx(c,{span:16,children:n.jsx(P,{children:i("实际扣费额度 = 违规扣费金额 × 分组倍率(单位:美元)")})})}),n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("违规扣费金额(美元)"),field:"grok.violation_deduction_amount",extraText:i("大于 0 的小数,例如 0.05"),min:0,step:.01,onChange:e=>u({...r,"grok.violation_deduction_amount":e})})})}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t=String(r[e.key]);return ye.put("/api/option/",{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存")})})]})})})})}function Yn(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({"global.pass_through_request_enabled":!1,"general_setting.ping_interval_enabled":!1,"general_setting.ping_interval_seconds":60}),p=t.useRef(),[x,g]=t.useState(r);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(r).includes(n)&&(t[n]=e.options[n]);u(t),g(structuredClone(t)),p.current.setValues(t)},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("全局设置"),children:[n.jsx(o,{children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{label:i("启用请求透传"),field:"global.pass_through_request_enabled",onChange:e=>u({...r,"global.pass_through_request_enabled":e}),extraText:i("pass_through_request_extra")})})}),n.jsxs(a.Section,{text:i("连接保活设置"),children:[n.jsx(o,{style:{marginTop:10},children:n.jsx(c,{span:24,children:n.jsx(h,{type:"warning",description:i("ping_interval_warning")})})}),n.jsxs(o,{children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{label:i("启用Ping间隔"),field:"general_setting.ping_interval_enabled",onChange:e=>u({...r,"general_setting.ping_interval_enabled":e}),extraText:i("ping_interval_extra")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("Ping间隔(秒)"),field:"general_setting.ping_interval_seconds",onChange:e=>u({...r,"general_setting.ping_interval_seconds":e}),min:1,disabled:!r["general_setting.ping_interval_enabled"]})})]})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,x);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t=String(r[e.key]);return ye.put("/api/option/",{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存")})})]})})})})}const Zn=e=>({operations:[{mode:"pass_headers",value:[...e],keep_origin:!0}]}),ei={codexCli:{name:"codex cli trace",model_regex:["^gpt-.*$"],path_regex:["/v1/responses"],key_sources:[{t
1ype:"gjson",path:"prompt_cache_key"}],param_override_template:Zn(["Originator","Session_id","User-Agent","X-Codex-Beta-Features","X-Codex-Turn-Metadata"]),value_regex:"",ttl_seconds:0,skip_retry_on_failure:!1,include_using_group:!0,include_rule_name:!0},claudeCli:{name:"claude cli trace",model_regex:["^claude-.*$"],path_regex:["/v1/messages"],key_sources:[{type:"gjson",path:"metadata.user_id"}],param_override_template:Zn(["X-Stainless-Arch","X-Stainless-Lang","X-Stainless-Os","X-Stainless-Package-Version","X-Stainless-Retry-Count","X-Stainless-Runtime","X-Stainless-Runtime-Version","X-Stainless-Timeout","User-Agent","X-App","Anthropic-Beta","Anthropic-Dangerous-Direct-Browser-Access","Anthropic-Version"]),value_regex:"",ttl_seconds:0,skip_retry_on_failure:!1,include_using_group:!0,include_rule_name:!0}},ti="channel_affinity_setting.enabled",ni="channel_affinity_setting.switch_on_success",ii="channel_affinity_setting.max_entries",si="channel_affinity_setting.default_ttl_seconds",li="channel_affinity_setting.rules",ai=[{label:"context_int",value:"context_int"},{label:"context_string",value:"context_string"},{label:"gjson",value:"gjson"}],ri=[{key:"id",label:"id(用户 ID)"},{key:"token_id",label:"token_id"},{key:"token_key",label:"token_key"},{key:"token_group",label:"token_group"},{key:"group",label:"group(using_group)"},{key:"username",label:"username"},{key:"user_group",label:"user_group"},{key:"user_email",label:"user_email"},{key:"specific_channel_id",label:"specific_channel_id"}],oi=e=>e?e.split("\n").map(e=>e.trim()).filter(e=>e.length>0):[],ci=e=>JSON.stringify(e,null,2),di=e=>{try{const t=JSON.parse(e||"[]");return Array.isArray(t)?t.map((e,t)=>({id:t,...e||{}})):[]}catch(t){return[]}},ui=e=>{const t=(e||[]).map(e=>{const{id:t,...n}=e||{};return n});return ci(t)},pi=e=>{const t=(e?.type||"").trim(),n=(e?.key||"").trim(),i=(e?.path||"").trim();return"gjson"===t?{type:t,key:"",path:i}:{type:t,key:n,path:""}};function hi(e){const{t:i}=ge(),{Text:s}=u,[l,r]=t.useState(!1),[p,y]=t.useState(!1),[f,b]=t.useState({enabled:!1,total:0,unknown:0,by_rule_name:{},cache_capacity:0,cache_algo:""}),[_,S]=t.useState({[ti]:!1,[ni]:!0,[ii]:1e5,[si]:3600,[li]:"[]"}),C=t.useRef(),[w,T]=t.useState(_),[E,R]=t.useState("visual"),P=t.useRef(E),[z,M]=t.useState([]),[O,D]=t.useState(!1),[L,B]=t.useState(null),[F,W]=t.useState(!1),J=t.useRef(),[U,V]=t.useState(null),[K,G]=t.useState(0),[q,$]=t.useState([]),[H,Q]=t.useState(""),X=Number(_?.[si]||0)>0?Number(_?.[si]||0):3600,Y=e=>{const t=e||{};return{name:t.name||"",model_regex_text:(t.model_regex||[]).join("\n"),path_regex_text:(t.path_regex||[]).join("\n"),user_agent_include_text:(t.user_agent_include||[]).join("\n"),value_regex:t.value_regex||"",ttl_seconds:Number(t.ttl_seconds||0),skip_retry_on_failure:!!t.skip_retry_on_failure,include_using_group:t.include_using_group??!0,include_model_name:!!t.include_model_name,include_rule_name:t.include_rule_name??!0,param_override_template_json:t.param_override_template?ci(t.param_override_template):""}},Z=t.useMemo(()=>{const e=(H||"").trim();if(!e)return{tagLabel:i("未设置"),tagColor:"grey",preview:i("当前规则未设置参数覆盖模板")};if(!Re(e))return{tagLabel:i("JSON 无效"),tagColor:"red",preview:e};try{return{tagLabel:i("已设置"),tagColor:"orange",preview:JSON.stringify(JSON.parse(e),null,2)}}catch(t){return{tagLabel:i("JSON 无效"),tagColor:"red",preview:e}}},[H,i]),ee=e=>{const t="string"==typeof e?e:"";Q(t),J.current&&J.current.setValue("param_override_template_json",t)},te=async()=>{try{y(!0);const e=await ye.get("/api/option/channel_affinity_cache",{disableDuplicate:!0}),{success:t,message:n,data:s}=e.data;if(!t)return je(i(n));b(s||{})}catch(e){je(i("刷新缓存统计失败"))}finally{y(!1)}},ne=e=>{M(e);const t=ui(e);S(e=>({...e,[li]:t})),C.current&&"json"===E&&C.current.setValue(li,t)},ie=[{title:i("名称"),dataIndex:"name",render:e=>n.jsx(s,{children:e||"-"})},{title:i("模型正则"),dataIndex:"model_regex",render:e=>(e||[]).length>0?(e||[]).slice(0,3).map((e,t)=>n.jsx(j,{style:{marginRight:4},children:e},`${e}-${t}`)):"-"},{title:i("路径正则"),dataIndex:"path_regex",render:e=>(e||[]).length>0?(e||[]).slice(0,2).map((e,t)=>n.jsx(j,{style:{marginRight:4},children:e},`${e}-${t}`)):"-"},{title:i("Key 来源"),dataIndex:"key_sources",render:e=>{const t=e||[];return 0===t.length?"-":t.slice(0,3).map((e,t)=>
1{const i=pi(e),s="gjson"===i.type?i.path:i.key;return n.jsxs(j,{style:{marginRight:4},children:[i.type,":",s]},`${i.type}-${t}`)})}},{title:i("TTL(秒)"),dataIndex:"ttl_seconds",render:e=>n.jsx(s,{children:Number(e||0)||"-"})},{title:i("失败后是否重试"),dataIndex:"skip_retry_on_failure",render:e=>n.jsx(j,{color:e?"orange":"green",style:{marginRight:4},children:i(e?"不重试":"重试")})},{title:i("覆盖模板"),render:(e,t)=>t?.param_override_template?n.jsx(d,{size:"small",icon:n.jsx(st,{size:16}),type:"tertiary",onClick:()=>(e=>{const t=e?.param_override_template;t&&"object"==typeof t?x.info({title:i("参数覆盖模板预览"),content:n.jsx("div",{style:{marginTop:6,paddingBottom:10},children:n.jsx("pre",{style:{margin:0,maxHeight:420,overflow:"auto",fontSize:12,lineHeight:1.6,padding:10,borderRadius:8,background:"hsl(var(--foreground) / 0.02)",border:"1px solid hsl(var(--border))",whiteSpace:"pre-wrap",wordBreak:"break-all"},children:ci(t)})}),footer:null,width:760}):ve(i("该规则未设置参数覆盖模板"))})(t),children:i("预览模板")}):n.jsx(s,{type:"tertiary",children:"-"})},{title:i("缓存条目数"),render:(e,t)=>{const i=(t?.name||"").trim();if(!i||!t?.include_rule_name)return n.jsx(s,{type:"tertiary",children:"N/A"});const l=Number(f?.by_rule_name?.[i]||0);return n.jsx(s,{children:l})}},{title:i("作用域"),render:(e,t)=>{const s=[];return t?.include_using_group&&s.push(i("分组")),t?.include_model_name&&s.push(i("模型")),t?.include_rule_name&&s.push(i("规则")),0===s.length?"-":s.map(e=>n.jsx(j,{style:{marginRight:4},children:e},e))}},{title:i("操作"),render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(lt,{size:16}),theme:"borderless",type:"warning",disabled:!t?.include_rule_name,title:i("清空该规则缓存"),"aria-label":i("清空该规则缓存"),onClick:()=>(e=>{const t=(e?.name||"").trim();t&&(e?.include_rule_name?x.confirm({title:i("确认清空该规则缓存"),content:n.jsxs("div",{style:{lineHeight:"1.6"},children:[n.jsxs(s,{children:[i("规则"),":"]})," ",n.jsx(s,{strong:!0,children:t})]}),onOk:async()=>{const e=await ye.delete("/api/option/channel_affinity_cache",{params:{rule_name:t}}),{success:n,message:s}=e.data;n?(be(i("已清空")),await te()):je(i(s))}}):ve(i('该规则未启用"作用域:包含规则名称",无法按规则清空缓存。')))})(t)}),n.jsx(d,{icon:n.jsx(at,{size:16}),theme:"borderless",title:i("编辑规则"),"aria-label":i("编辑规则"),onClick:()=>se(t)}),n.jsx(d,{icon:n.jsx(He,{size:16}),theme:"borderless",type:"danger",title:i("删除规则"),"aria-label":i("删除规则"),onClick:()=>le(t.id)})]})}],se=e=>{const t=e||{},n={...t,user_agent_include:Array.isArray(t.user_agent_include)?t.user_agent_include:[],key_sources:(t.key_sources||[]).map(pi)};B(n),W(!0),J.current=null;const i=Y(n);V(i),Q(i.param_override_template_json||""),$([]),G(e=>e+1),D(!0)},le=e=>{const t=(z||[]).filter(t=>t.id!==e);ne(t.map((e,t)=>({...e,id:t}))),be(i("删除成功"))},ae=(e,t)=>{const n=[...L?.key_sources||[]];n[e]=pi({...n[e]||{},...t||{}}),B(e=>({...e||{},key_sources:n}))};t.useEffect(()=>{const t={..._};for(let i in e.options)if([ti,ni,ii,si,li].includes(i))if(i===ti)t[i]=an(e.options[i]);else if(i===ni)t[i]=an(e.options[i]);else if(i===ii)t[i]=Number(e.options[i]||0)||0;else if(i===si)t[i]=Number(e.options[i]||0)||0;else if(i===li)try{const n=JSON.parse(e.options[i]||"[]");t[i]=ci(n)}catch(n){t[i]=e.options[i]||"[]"}S(t),T(structuredClone(t)),C.current&&C.current.setValues(t),M(di(t[li])),te()},[e.options]),t.useEffect(()=>{const e=P.current;P.current=E,e!==E&&"json"===E&&C.current&&C.current.setValue(li,_[li]||"[]")},[E,_]),t.useEffect(()=>{"visual"===E&&M(di(_[li]))},[_[li],E]);const re=n.jsx(h,{fullMode:!1,type:"info",description:i("渠道亲和性会基于从请求上下文或 JSON Body 提取的 Key,优先复用上一次成功的渠道。")});return n.jsxs(n.Fragment,{children:[n.jsx(m,{spinning:l,children:n.jsx(a,{values:_,getFormApi:e=>C.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("渠道亲和性"),children:[re,n.jsx(I,{style:{marginTop:12,marginBottom:12}}),n.jsxs(o,{gutter:16,children:[n.jsxs(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:[n.jsx(a.Switch,{field:ti,label:i("启用"),checkedText:"|",uncheckedText:"O",onChange:e=>S({..._,[ti]:e})}),n.jsx(s,{type:"tertiary",size:14,children:i("启用后将优先复用上一次成功的渠道(粘滞选路)。")})]}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:ii,label:i("最大条目数"),min:0,placeholder:"ä¾
1‹å¦‚ 100000…",extraText:n.jsx(s,{type:"tertiary",size:14,children:i("内存缓存最大条目数。0 表示使用后端默认容量:100000。")}),onChange:e=>S({..._,[ii]:Number(e||0)})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:si,label:i("默认 TTL(秒)"),min:0,placeholder:"例如 3600…",extraText:n.jsx(s,{type:"tertiary",size:14,children:i("规则 ttl_seconds 为 0 时使用。0 表示使用后端默认 TTL:3600 秒。")}),onChange:e=>S({..._,[si]:Number(e||0)})})})]}),n.jsx(o,{gutter:16,style:{marginTop:12},children:n.jsxs(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:[n.jsx(a.Switch,{field:ni,label:i("成功后切换亲和"),checkedText:"|",uncheckedText:"O",onChange:e=>S({..._,[ni]:e})}),n.jsx(s,{type:"tertiary",size:14,children:i("如果亲和到的渠道失败,重试到其他渠道成功后,将亲和更新到成功的渠道。")})]})}),n.jsx(I,{style:{marginTop:12,marginBottom:12}}),n.jsxs(g,{style:{marginBottom:10},children:[n.jsx(d,{type:"visual"===E?"primary":"tertiary",onClick:()=>{const e=(e=>{const t=e;
1if(!Re(t))return{ok:!1,message:"Rules JSON is invalid"};try{const e=JSON.parse(t);return Array.isArray(e)?{ok:!0,value:e}:{ok:!1,message:"Rules JSON must be an array"}}catch(n){return{ok:!1,message:"Rules JSON is invalid"}}})(_[li]||"[]");e.ok?R("visual"):je(i(e.message))},children:i("可视化")}),n.jsx(d,{type:"json"===E?"primary":"tertiary",onClick:()=>{const e=ui(z);S(t=>({...t||{},[li]:e})),R("json")},children:i("JSON 模式")}),n.jsx(d,{onClick:()=>{const e=()=>{const e=new Set((z||[]).map(e=>(e?.name||"").trim()).filter(e=>e.length>0)),t=[ei.codexCli,ei.claudeCli].map(t=>{const n=(i=t,JSON.parse(JSON.stringify(i||{})));var i;const s=((e,t)=>{const n=(t||"").trim()||"rule";if(!e.has(n))return n;for(let i=2;i<1e3;i++){const t=`${n}-${i}`;if(!e.has(t))return t}return`${n}-${Date.now()}`})(e,t.name);return e.add(s),{...n,name:s}}),n=[...z||[],...t].map((e,t)=>({...e||{},id:t}));ne(n),be(i("已填充模版"))};0!==(z||[]).length?x.confirm({title:i("填充 Codex CLI / Claude CLI 模版"),content:n.jsx("div",{style:{lineHeight:"1.6"},children:n.jsx(s,{type:"tertiary",children:i("将追加 2 条规则到现有规则列表。")})}),onOk:e}):e()},children:i("填充 Codex CLI / Claude CLI 模版")}),n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>{const e={name:"",model_regex:[],path_regex:[],user_agent_include:[],key_sources:[{type:"gjson",path:""}],value_regex:"",ttl_seconds:0,skip_retry_on_failure:!1,include_using_group:!0,include_model_name:!1,include_rule_name:!0};B(e),W(!1),J.current=null;const t=Y(e);V(t),Q(t.param_override_template_json||""),$([]),G(e=>e+1),D(!0)},children:i("新增规则")}),n.jsx(d,{theme:"solid",onClick:async function(){const t=ke(_,w);if(!t.length)return ve(i("你似乎并没有修改什么"));if(!Re(_[li]||"[]"))return je(i("规则 JSON 格式不正确"));let n;try{s=JSON.parse(_[li]||"[]"),n=JSON.stringify(s)}catch(a){return je(i("规则 JSON 格式不正确"))}var s;const l=t.map(e=>{let t="";return t=e.key===li?n:"boolean"==typeof _[e.key]?String(_[e.key]):String(_[e.key]??""),ye.put("/api/option/",{key:e.key,value:t})});r(!0),Promise.all(l).then(t=>{if(1===l.length){if(t.includes(void 0))return}else if(l.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>je(i("保存失败,请重试"))).finally(()=>r(!1))},children:i("保存")}),n.jsx(d,{icon:n.jsx(et,{size:16}),loading:p,onClick:te,children:i("刷新缓存统计")}),n.jsx(d,{type:"danger",onClick:()=>{x.confirm({title:i("确认清空全部渠道亲和性缓存"),content:n.jsx("div",{style:{lineHeight:"1.6"},children:n.jsx(s,{children:i("将删除所有仍在内存中的渠道亲和性缓存条目。")})}),onOk:async()=>{const e=await ye.delete("/api/option/channel_affinity_cache",{params:{all:!0}}),{success:t,message:n}=e.data;t?(be(i("已清空")),await te()):je(i(n))}})},children:i("清空全部缓存")})]}),"visual"===E?n.jsx(v,{columns:ie,dataSource:z,rowKey:"id",pagination:!1,size:"small"}):n.jsx(a.TextArea,{field:li,label:i("规则 JSON"),extraText:i("规则为 JSON 数组;可视化与 JSON 模式共用同一份数据。"),placeholder:'[\n  {\n    "name": "prefer-by-conversation-id",\n    "model_regex": ["^gpt-.*$"],\n    "path_regex": ["/v1/chat/completions"],\n    "user_agent_include": ["curl", "PostmanRuntime"],\n    "key_sources": [\n      { "type": "gjson", "path": "metadata.conversation_id" },\n      { "type": "context_string", "key": "conversation_id" }\n    ],\n    "value_regex": "^[-0-9A-Za-z._:]{1,128}$",\n    "ttl_seconds": 600,\n    "param_override_template": {\n      "operations": [\n        { "path": "temperature", "mode": "set", "value": 0.2 }\n      ]\n    },\n    "skip_retry_on_failure": false,\n    "include_using_group": true,\n    "include_model_name": false,\n    "include_rule_name": true\n  }\n]',style:{width:"100%"},autosize:{minRows:10,maxRows:28},rules:[{validator:(e,t)=>Re(t||"[]")}],onChange:e=>S({..._,[li]:e})})]})})}),n.jsx(x,{title:i(F?"编辑规则":"新增规则"),visible:O,onCancel:()=>{D(!1),B(null),V(null),$([]),Q("")},onOk:async()=>{try{const e=await J.current.validate(),t=oi(e.model_regex_text);if(0===t.length)return je(i("模型正则不能为空"));const n=(e=>{const t=(e||[]).map(pi).filter(e=>e.type);if(0===t.length)return{ok:!1,message:"Key 来源不能为空"};
1for(const n of t)if("context_int"===n.type||"context_string"===n.type){if(!n.key)return{ok:!1,message:"Key 不能为空"}}else{if("gjson"!==n.type)return{ok:!1,message:"Key 来源类型不合法"};if(!n.path)return{ok:!1,message:"Path 不能为空"}}return{ok:!0,value:t}})(L?.key_sources);if(!n.ok)return je(i(n.message));const s=oi(e.user_agent_include_text),l=((e,t)=>{const n=(e||"").trim();if(!n)return{ok:!0,value:null};if(!Re(n))return{ok:!1,message:`${t} JSON 格式不正确`};try{const e=JSON.parse(n);return!e||"object"!=typeof e||Array.isArray(e)?{ok:!1,message:`${t} 必须是 JSON 对象`}:{ok:!0,value:e}}catch(i){return{ok:!1,message:`${t} JSON 格式不正确`}}})(H,"参数覆盖模板");if(!l.ok)return je(i(l.message));const a={id:F?L.id:z.length,name:(e.name||"").trim(),model_regex:t,path_regex:oi(e.path_regex_text),key_sources:n.value,value_regex:(e.value_regex||"").trim(),ttl_seconds:Number(e.ttl_seconds||0),include_using_group:!!e.include_using_group,include_model_name:!!e.include_model_name,include_rule_name:!!e.include_rule_name,skip_retry_on_failure:!!e.skip_retry_on_failure,...s.length>0?{user_agent_include:s}:{},...l.value?{param_override_template:l.value}:{}};if(!a.name)return je(i("名称不能为空"));const r=[...z||[]];if(F){let e=r.findIndex(e=>e.id===L?.id);if(e<0&&L?.name&&(e=r.findIndex(e=>(e?.name||"").trim()===(L?.name||"").trim())),e<0)return je(i("规则未找到,请刷新后重试"));r[e]=a}else r.push(a);ne(r.map((e,t)=>({...e,id:t}))),D(!1),B(null),V(null),Q(""),be(i("保存成功"))}catch(e){je(i("请检查输入"))}},okText:i("保存"),cancelText:i("取消"),width:720,children:n.jsxs(a,{initValues:U||{},getFormApi:e=>{J.current=e},children:[n.jsx(a.Input,{field:"name",label:i("名称"),extraText:i("规则名称(可读性更好,也会出现在管理侧日志中)。"),placeholder:"例如 prefer-by-conversation-id…",rules:[{required:!0}],onChange:e=>B(t=>({...t||{},name:e}))}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,children:n.jsx(a.TextArea,{field:"model_regex_text",label:i("模型正则(每行一个)"),extraText:i("必填。对请求的 model 名称进行匹配,任意一条匹配即命中该规则。"),placeholder:"^gpt-4o.*$\n^claude-3.*$…",autosize:{minRows:4,maxRows:10},rules:[{required:!0}]})}),n.jsx(c,{xs:24,sm:12,children:n.jsx(a.TextArea,{field:"path_regex_text",label:i("路径正则(每行一个)"),extraText:i("可选。对请求路径进行匹配;不填表示匹配所有路径。"),placeholder:"/v1/chat/completions\n/v1/responses…",autosize:{minRows:4,maxRows:10}})})]}),n.jsx(o,{gutter:16,style:{marginTop:12},children:n.jsxs(c,{xs:24,sm:12,children:[n.jsx(a.Switch,{field:"skip_retry_on_failure",label:i("失败后不重试")}),n.jsx(s,{type:"tertiary",size:14,children:i("开启后,若该规则命中且请求失败,将不会切换渠道重试。")})]})}),n.jsx(A,{keepDOM:!0,activeKey:q,onChange:e=>{const t=Array.isArray(e)?e:[e];$(t.filter(Boolean))},children:n.jsxs(A.Panel,{header:i("高级设置"),itemKey:"advanced",children:[n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,children:n.jsx(a.TextArea,{field:"user_agent_include_text",label:i("User-Agent include(每行一个,可不写)"),extraText:n.jsx(s,{type:"tertiary",size:14,children:i("可选。匹配入口请求的 User-Agent;任意一行作为子串匹配(忽略大小写)即命中。")}),placeholder:"curl\nPostmanRuntime\nMyApp/…",autosize:{minRows:3,maxRows:8}})})}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,children:n.jsx(a.Input,{field:"value_regex",label:i("Value 正则"),placeholder:"^[-0-9A-Za-z._:]{1,128}$",extraText:i("可选。对提取到的亲和 Key 做正则校验;不填表示不校验。")})}),n.jsx(c,{xs:24,sm:12,children:n.jsx(a.InputNumber,{field:"ttl_seconds",label:i("TTL(秒,0 表示默认)"),placeholder:"例如 600…",min:0,extraText:n.jsxs(s,{type:"tertiary",size:14,children:[i("该规则的缓存保留时长;0 表示使用默认 TTL:"),X,i("秒")]})})})]}),n.jsx(o,{gutter:16,children:n.jsxs(c,{xs:24,children:[n.jsx("div",{style:{marginBottom:8},children:n.jsx(s,{strong:!0,children:i("参数覆盖模板")})}),n.jsx(s,{type:"tertiary",size:14,children:i("命中该亲和规则后,会把此模板合并到渠道参数覆盖中(同名键由模板覆盖)。")}),n.jsxs("div",{style:{marginTop:8,borderRadius:10,padding:10,background:"hsl(var(--foreground) / 0.02)",border:"1px solid hsl(var(--border))"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:8,gap:8,flexWrap:"wrap"},children:[n.jsx(j,{color:Z.tagColor,children:Z.tagLabel}),n.jsxs(g,{children:[n.jsx(d,{size:"small",onClick:()=>{const e=(H||"").trim();if(e)if(Re(e))try{ee(JSON.stringify(JSON.parse(e),null,2))}catch(t){je(i("参数覆盖模板 JSON 格式不正确"))}else je(i("参数覆盖模板 JSON 格式不正确"))},children:i("格式化")}),n.jsx(d,{size:"small",type:"tertiary",onClick:()=>ee(""),children:i("清空")})]})]}),n.jsx(a.TextArea,{field:"param_override_template_json",noLabel:!0,placeholder:'{"operations": [...]}',autosize:{minRows:3,maxRows:12},onChange:e=>Q(e||"")})]})]})}),n.jsxs(o,{gutter:16,children:[n.jsxs(c,{xs:24,sm:8,children:[n.jsx(a.Switch,{field:"include_using_group",label:i("作用域:包含分组")}
1),n.jsx(s,{type:"tertiary",size:14,children:i("开启后,using_group 会参与 cache key(不同分组隔离)。")})]}),n.jsxs(c,{xs:24,sm:8,children:[n.jsx(a.Switch,{field:"include_model_name",label:i("作用域:包含模型名称")}),n.jsx(s,{type:"tertiary",size:14,children:i("开启后,模型名称会参与 cache key(不同模型隔离)。")})]}),n.jsxs(c,{xs:24,sm:8,children:[n.jsx(a.Switch,{field:"include_rule_name",label:i("作用域:包含规则名称")}),n.jsx(s,{type:"tertiary",size:14,children:i("开启后,规则名称会参与 cache key(不同规则隔离)。")})]})]})]})}),n.jsx(I,{style:{marginTop:12,marginBottom:12}}),n.jsxs(g,{style:{marginBottom:10},children:[n.jsx(s,{children:i("Key 来源")}),n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>{const e=[...L?.key_sources||[]];e.push({type:"gjson",path:""}),B(t=>({...t||{},key_sources:e}))},children:i("新增 Key 来源")})]}),n.jsx(s,{type:"tertiary",size:14,children:i("context_int/context_string 从请求上下文读取;gjson 从入口请求的 JSON body 按 gjson path 读取。")}),n.jsxs("div",{style:{marginTop:8,marginBottom:8},children:[n.jsxs(s,{type:"tertiary",size:14,children:[i("常用上下文 Key(用于 context_*)"),":"]}),n.jsx("div",{style:{marginTop:6},children:(ri||[]).map(e=>n.jsx(j,{style:{marginRight:6,marginBottom:6},children:e.label},e.key))})]}),n.jsx(v,{columns:[{title:i("类型"),render:(e,t,s)=>n.jsx(N,{style:{width:160},optionList:ai,value:(L?.key_sources?.[s]?.type||"gjson").trim(),"aria-label":i("Key 来源类型"),onChange:e=>ae(s,{type:e})})},{title:i("Key 或 Path"),render:(e,t,s)=>{const l=pi(L?.key_sources?.[s]),a="gjson"===l.type;return n.jsx(k,{placeholder:a?"metadata.conversation_id":"user_id","aria-label":i("Key 或 Path"),value:a?l.path:l.key,onChange:e=>ae(s,a?{path:e}:{key:e})})}},{title:i("操作"),width:90,render:(e,t,s)=>n.jsx(d,{icon:n.jsx(He,{size:16}),theme:"borderless",type:"danger",title:i("删除 Key 来源"),"aria-label":i("删除 Key 来源"),onClick:()=>(e=>{const t=[...L?.key_sources||[]].filter((t,n)=>n!==e);B(e=>({...e||{},key_sources:t}))})(s)})}],dataSource:(L?.key_sources||[]).map((e,t)=>({id:t,...e})),rowKey:"id",pagination:!1,size:"small"})]},`channel-affinity-rule-form-${K}`)})]})}const xi=()=>{const{t:e}=ge();let[i,s]=t.useState({"gemini.safety_settings":"","gemini.version_settings":"","gemini.supported_imagine_models":"","claude.model_headers_settings":"","claude.thinking_adapter_enabled":!0,"claude.default_max_tokens":"","claude.thinking_adapter_budget_tokens_percentage":.8,"global.pass_through_request_enabled":!1,"general_setting.ping_interval_enabled":!1,"general_setting.ping_interval_seconds":60,"gemini.thinking_adapter_enabled":!1,"gemini.thinking_adapter_budget_tokens_percentage":.6,"grok.violation_deduction_enabled":!1,"grok.violation_deduction_amount":.05}),[l,a]=t.useState(!1);async function o(){try{a(!0),await(async()=>{const e=await ye.get("/api/option/"),{success:t,message:n,data:i}=e.data;if(t){let e={};i.forEach(t=>{"gemini.safety_settings"!==t.key&&"gemini.version_settings"!==t.key&&"claude.model_headers_settings"!==t.key&&"claude.default_max_tokens"!==t.key&&"gemini.supported_imagine_models"!==t.key||""!==t.value&&(t.value=JSON.stringify(JSON.parse(t.value),null,2)),t.key.endsWith("Enabled")||t.key.endsWith("enabled")?e[t.ke
1y]=an(t.value):e[t.key]=t.value}),s(e)}else je(n)})()}catch(t){je(e("刷新失败")),console.error(t)}finally{a(!1)}}return t.useEffect(()=>{o()},[]),n.jsx(n.Fragment,{children:n.jsxs(m,{spinning:l,size:"large",children:[n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Yn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(qn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Qn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Xn,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(hi,{options:i,refresh:o})})]})})},{Text:mi}=u,gi=["description","route"],yi=[{key:"route",label:"线路描述",type:"input",maxLength:50},{key:"description",label:"说明",type:"input",maxLength:200}],ji=({options:e,refresh:i})=>{const{t:s}=ge(),[l,r]=t.useState([]),[o,c]=t.useState(!1),[u,p]=t.useState(!1),[h,m]=t.useState(null),[y,f]=t.useState(null),[b,_]=t.useState(!1),[S,k]=t.useState(!1),[P,z]=t.useState(!1),[N,A]=t.useState({url:"",description:"",route:"",color:"blue"}),[M,O]=t.useState(1),[D,L]=t.useState(10),[B,F]=t.useState([]),[W,J]=t.useState(!0),[U,V]=t.useState(null),K=an(e?.["translation_setting.enabled"]);t.useEffect(()=>{const t=e["console_setting.api_info"]??e.ApiInfo;void 0!==t&&(e=>{if(e)try{const t=JSON.parse(e);r(Array.isArray(t)?t:[])}catch(t){console.error("解析API信息失败:",t),r([])}else r([])})(t)},[e["console_setting.api_info"],e.ApiInfo]),t.useEffect(()=>{const t=e["console_setting.api_info_enabled"];J(void 0===t||"true"===t||!0===t)},[e["console_setting.api_info_enabled"]]);const G=[{title:"ID",dataIndex:"id"},{title:s("API地址"),dataIndex:"url",render:(e,t)=>n.jsx(j,{color:t.color,shape:"circle",style:{maxWidth:"280px"},children:e})},{title:s("线路描述"),dataIndex:"route",render:(e,t)=>n.jsx(j,{shape:"circle",children:e})},{title:s("说明"),dataIndex:"description",ellipsis:!0,render:(e,t)=>n.jsx(j,{shape:"circle",children:e||"-"})},{title:s("颜色"),dataIndex:"color",render:e=>n.jsx(R,{size:"extra-extra-small",color:e})},{title:s("翻译"),key:"translation_status",width:110,render:(e,t)=>n.jsx(hn,{item:t,fields:gi,onClick:()=>V(t)})},{title:s("操作"),fixed:"right",width:220,render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(Ge,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>V(t),children:s("译文")}),n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>{return f(e=t),A({url:e.url,description:e.description,route:e.route,color:e.color}),void c(!0);var e},children:s("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",onClick:()=>(m(t),void p(!0)),children:s("删除")})]})}],q={selectedRowKeys:B,onChange:(e,t)=>
1{F(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsxs("div",{className:"mb-2",children:[n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(it,{size:16,className:"mr-2"}),n.jsx(mi,{children:s("API信息管理,可以配置多个API地址用于状态展示和负载均衡(最多50个)")})]}),K&&n.jsxs("div",{className:"flex items-center text-amber-500 mt-1",children:[n.jsx(Ge,{size:14,className:"mr-2"}),n.jsx(mi,{type:"warning",size:"small",children:"t('已开启自动翻译:保存设置时会对未翻译/原文已修改的条目自动翻译为 6 种语言')"})]})]}),n.jsx(I,{margin:"12px"}),n.jsxs("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:[n.jsxs("div",{className:"flex gap-2 w-full md:w-auto order-2 md:order-1",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"w-full md:w-auto",onClick:()=>{f(null),A({url:"",description:"",route:"",color:"blue"}),c(!0)},children:s("添加API")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===B.length)return void je(s("请先选择要删除的API信息"));const e=l.filter(e=>!B.includes(e.id));r(e),F([]),z(!0),be(s('已删除 {{count}} 个API信息,请及时点击"保存设置"进行保存',{count:B.length}))},disabled:0===B.length,className:"w-full md:w-auto",children:[s("批量删除")," ",B.length>0&&`(${B.length})`]}),n.jsx(d,{icon:n.jsx(Ze,{size:14}),onClick:async()=>{try{k(!0);let e=l;const t=JSON.stringify(e);await(async(e,t)=>{const n=await ye.put("/api/option/",{key:"console_setting.api_info",value:t}),{success:l,message:a}=n.data;l?(be(s("API信息已更新")),i&&i()):je(a)})(0,t),z(!1)}catch(e){console.error("API信息更新失败",e),je(s("API信息更新失败"))}finally{k(!1)}},loading:S,disabled:!P,type:"secondary",className:"w-full md:w-auto",children:s("保存设置")})]}),n.jsxs("div",{className:"order-1 md:order-2 flex items-center gap-2",children:[n.jsx(E,{checked:W,onChange:async e=>{const t=e?"true":"false";try{const n=await ye.put("/api/option/",{key:"console_setting.api_info_enabled",value:t});n.data.success?(J(e),be(s("设置已保存")),i?.()):je(n.data.message)}catch(n){je(n.message)}}}),n.jsx(mi,{children:s(W?"已启用":"已禁用")})]})]})]}),children:n.jsx(v,{columns:G,dataSource:(()=>{const e=(M-1)*D,t=e+D;return l.slice(e,t)})(),rowSelection:q,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:M,pageSize:D,total:l.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:e=>s("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:l.length}),pageSizeOptions:["5","10","20","50"],onChange:(e,t)=>
1{O(e),L(t)},onShowSizeChange:(e,t)=>{O(1),L(t)}},size:"middle",loading:S,empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:s("暂无API信息"),style:{padding:30}}),className:"overflow-hidden"})}),n.jsx(x,{title:s(y?"编辑API":"添加API"),visible:o,onOk:async()=>{if(N.url&&N.route&&N.description)try{let e;if(_(!0),y)e=l.map(e=>e.id===y.id?{...e,...N}:e);else{const t={id:Math.max(...l.map(e=>e.id),0)+1,...N};e=[...l,t]}r(e),z(!0),c(!1),be(s(y?'API信息已更新,请及时点击"保存设置"进行保存':'API信息已添加,请及时点击"保存设置"进行保存'))}catch(e){je(s("操作失败")+": "+e.message)}finally{_(!1)}else je(s("请填写完整的API信息"))},onCancel:()=>c(!1),okText:s("保存"),cancelText:s("取消"),confirmLoading:b,children:n.jsxs(a,{layout:"vertical",initValues:N,children:[n.jsx(a.Input,{field:"url",label:s("API地址"),placeholder:"https://api.example.com",rules:[{required:!0,message:s("请输入API地址")}],onChange:e=>A({...N,url:e})}),n.jsx(a.Input,{field:"route",label:s("线路描述"),placeholder:s("如:香港线路"),rules:[{required:!0,message:s("请输入线路描述")}],onChange:e=>A({...N,route:e})}),n.jsx(a.Input,{field:"description",label:s("说明"),placeholder:s("如:大带宽批量分析图片推荐"),rules:[{required:!0,message:s("请输入说明")}],onChange:e=>A({...N,description:e})}),n.jsx(a.Select,{field:"color",label:s("标识颜色"),optionList:[{value:"blue",label:"blue"},{value:"green",label:"green"},{value:"cyan",label:"cyan"},{value:"purple",label:"purple"},{value:"pink",label:"pink"},{value:"red",label:"red"},{value:"orange",label:"orange"},{value:"amber",label:"amber"},{value:"yellow",label:"yellow"},{value:"lime",label:"lime"},{value:"light-green",label:"light-green"},{value:"teal",label:"teal"},{value:"light-blue",label:"light-blue"},{value:"indigo",label:"indigo"},{value:"violet",label:"violet"},{value:"grey",label:"grey"}],onChange:e=>A({...N,color:e}),render:e=>n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[n.jsx(R,{size:"extra-extra-small",color:e.value}),e.label]})})]},y?y.id:"new")}),n.jsx(x,{title:s("确认删除"),visible:u,onOk:()=>{if(h){const e=l.filter(e=>e.id!==h.id);r(e),z(!0),be(s("API信息已删除,请及时点击“保存设置”进行保存"))}p(!1),m(null)},onCancel:()=>{p(!1),m(null)},okText:s("确认删除"),cancelText:s("取消"),type:"warning",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(mi,{children:s("确定要删除此API信息吗?")})}),n.jsx(xn,{visible:!!U,onClose:()=>V(null),item:U||{},fields:yi.map(e=>({...e,label:s(e.label)})),translationEnabled:K,onApply:e=>{if(!U)return;const t=l.map(t=>t.id===U.id?{...t,...e}:t);r(t),z(!0)}})]})},fi=["content","extra"],bi=[{key:"content",label:"内容",type:"textarea",rows:4,maxCount:500},{key:"extra",label:"说明",type:"input",maxLength:200}],{Text:_i}=u,Si=({options:e,refresh:i})=>{const{t:s}=ge(),[l,r]=t.useState([]),[o,c]=t.useState(!1),[u,p]=t.useState(!1),[h,m]=t.useState(!1),[y,b]=t.useState(null),[_,k]=t.useState(null),[R,P]=t.useState(!1),[z,N]=t.useState(!1),[A,M]=t.useState(!1),[O,D]=t.useState({content:"",publishDate:new Date,type:"default",extra:""}),[L,B]=t.useState(1),[F,W]=t.useState(10),[J,U]=t.useState([]),[V,K]=t.useState(!0),[G,q]=t.useState(null),$=an(e?.["translation_setting.enabled"]),H=t.useRef(null),Q=[{value:"default",label:s("默认")},{value:"ongoing",label:s("进行中")},{value:"success",label:s("成功")},{value:"warning",label:s("警告")},{value:"error",label:s("错误")}],X=e=>({default:"grey",ongoing:"blue",success:"green",warning:"orange",error:"red"}[e]||"grey"),Y=[{title:s("内容"),dataIndex:"content",key:"content",render:e=>n.jsx(f,{content:e,position:"topLeft",showArrow:!0,children:n.jsx("div",{style:{maxWidth:"300px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e})})},{title:s("发布时间"),dataIndex:"publishDate",key:"publishDate",width:180,render:e=>n.jsxs("div",{children:[n.jsx("div",{style:{fontWeight:"bold"},children:Ce(e)}),n.jsx("div",{style:{fontSize:"12px",color:"hsl(var(--muted-foreground))",marginTop:"2px"},children:e?we(new Date(e)):"-"})]})},{title:s("类型"),dataIndex:"type",key:"type",width:100,render:e=>n.jsx(j,{color:X(e),shape:"circle",children:Q.find(t=>t.value===e)?.label||e})},{title:s("说明"),dataIndex:"extra",key:"extra",render:e=>n.jsx(f,{content:e||"-",showArrow:!0,children:n.jsx("div",{style:{maxWidth:"200px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"hsl(var(--muted-foreground))"},children:e||"-"})})},{title:s("翻译"),key:"translation_status",width:110,render:(e,t)=>n.jsx(hn,{item:t,fields:fi,onClick:()=>q(t)})},{title:s("操作"),key:"action",fixed:"right",width:220,render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(Ge,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>q(t),children:s("译文")}),n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>Z(t),children:s("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",onClick:()=>ee(t),children:s("删除")})]})}],Z=e=>{k(e),D({content:e.content,publishDate:e.publishDate?new Date(e.publishDate):new Date,type:e.type||"default",extra:e.extra||""}),c(!0)},ee=e=>{b(e),p(!0)};t.useEffect(()=>{const t=e["console_setting.announcements"]??e.Announcements;void 0!==t&&(e=>{if(e)try{const t=JSON.parse(e),n=(Array.isArray(t)?t:[]).map((e,t)=>({...e,id:e.id||t+1}));r(n)}catch(t){console.error("解析系统公告失败:",t),r([])}else r([])})(t)},[e["console_setting.announcements"],e.Announcements]),t.useEffect(()=>{const t=e["console_setting.announcements_enabled"];K(void 0===t||"true"===t||!0===t)},[e["console_setting.announcements_enabled"]]);const te={selectedRowKeys:J,onChange:(e,t)=>
1{U(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsxs("div",{className:"mb-2",children:[n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(Xe,{size:16,className:"mr-2"}),n.jsx(_i,{children:s("系统公告管理,可以发布系统通知和重要消息(最多100个,前端显示最新20条)")})]}),$&&n.jsxs("div",{className:"flex items-center text-amber-500 mt-1",children:[n.jsx(Ge,{size:14,className:"mr-2"}),n.jsx(_i,{type:"warning",size:"small",children:s("已开启自动翻译:保存设置时由后端并发翻译为 6 种语言(耗时取决于条目数与模型,通常 30 秒~2 分钟)")})]})]}),n.jsx(I,{margin:"12px"}),n.jsxs("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:[n.jsxs("div",{className:"flex gap-2 w-full md:w-auto order-2 md:order-1",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"w-full md:w-auto",onClick:()=>{k(null),D({content:"",publishDate:new Date,type:"default",extra:""}),c(!0)},children:s("添加公告")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===J.length)return void je(s("请先选择要删除的系统公告"));const e=l.filter(e=>!J.includes(e.id));r(e),U([]),M(!0),be(s('已删除 {{count}} 个系统公告,请及时点击"保存设置"进行保存',{count:J.length}))},disabled:0===J.length,className:"w-full md:w-auto",children:[s("批量删除")," ",J.length>0&&`(${J.length})`]}),n.jsx(d,{icon:n.jsx(Ze,{size:14}),onClick:async()=>{try{N(!0);const e=JSON.stringify(l);await(async(e,t)=>{const n=await ye.put("/api/option/",{key:"console_setting.announcements",value:t}),{success:l,message:a}=n.data;l?(be(s("系统公告已更新")),i&&i()):je(a)})(0,e),M(!1)}catch(e){console.error("系统公告更新失败",e),je(s("系统公告更新失败"))}finally{N(!1)}},loading:z,disabled:!A,type:"secondary",className:"w-full md:w-auto",children:s("保存设置")})]}),n.jsxs("div",{className:"order-1 md:order-2 flex items-center gap-2",children:[n.jsx(E,{checked:V,onChange:async e=>{const t=e?"true":"false";try{const n=await ye.put("/api/option/",{key:"console_setting.announcements_enabled",value:t});n.data.success?(K(e),be(s("设置已保存")),i?.()):je(n.data.message)}catch(n){je(n.message)}}}),n.jsx(_i,{children:s(V?"已启用":"已禁用")})]})]})]}),children:n.jsx(v,{columns:Y,dataSource:(()=>{const e=[...l].sort((e,t)=>{const n=new Date(e.publishDate).getTime();return new Date(t.publishDate).getTime()-n}),t=(L-1)*F,n=t+F;return e.slice(t,n)})(),rowSelection:te,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:L,pageSize:F,total:l.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:e=>s("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:l.length}),pageSizeOptions:["5","10","20","50"],onChange:(e,t)=>
1{B(e),W(t)},onShowSizeChange:(e,t)=>{B(1),W(t)}},size:"middle",loading:z,empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:s("暂无系统公告"),style:{padding:30}}),className:"overflow-hidden"})}),n.jsx(x,{title:s(_?"编辑公告":"添加公告"),visible:o,onOk:async()=>{if(O.content&&O.publishDate)try{P(!0);const e={...O,publishDate:O.publishDate.toISOString()};let t;if(_)t=l.map(t=>t.id===_.id?{...t,...e}:t);else{const n={id:Math.max(...l.map(e=>e.id),0)+1,...e};t=[...l,n]}r(t),M(!0),c(!1),be(s(_?"公告已更新,请及时点击“保存设置”进行保存":"公告已添加,请及时点击“保存设置”进行保存"))}catch(e){je(s("操作失败")+": "+e.message)}finally{P(!1)}else je(s("请填写完整的公告信息"))},onCancel:()=>c(!1),okText:s("保存"),cancelText:s("取消"),confirmLoading:R,children:n.jsxs(a,{layout:"vertical",initValues:O,getFormApi:e=>H.current=e,children:[n.jsx(a.TextArea,{field:"content",label:s("公告内容"),placeholder:s("请输入公告内容(支持 Markdown/HTML)"),maxCount:500,rows:3,rules:[{required:!0,message:s("请输入公告内容")}],onChange:e=>D({...O,content:e})}),n.jsx(d,{theme:"light",type:"tertiary",size:"small",icon:n.jsx(Qe,{size:14}),style:{marginBottom:16},onClick:()=>m(!0),children:s("放大编辑")}),n.jsx(a.DatePicker,{field:"publishDate",label:s("发布日期"),type:"dateTime",rules:[{required:!0,message:s("请选择发布日期")}],onChange:e=>D({...O,publishDate:e})}),n.jsx(a.Select,{field:"type",label:s("公告类型"),optionList:Q,onChange:e=>D({...O,type:e})}),n.jsx(a.Input,{field:"extra",label:s("说明信息"),placeholder:s("可选,公告的补充说明"),onChange:e=>D({...O,extra:e})})]},_?_.id:"new")}),n.jsx(x,{title:s("确认删除"),visible:u,onOk:()=>{if(y){const e=l.filter(e=>e.id!==y.id);r(e),M(!0),be(s("公告已删除,请及时点击“保存设置”进行保存"))}p(!1),b(null)},onCancel:()=>{p(!1),b(null)},okText:s("确认删除"),cancelText:s("取消"),type:"warning",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(_i,{children:s("确定要删除此公告吗?")})}),n.jsx(xn,{visible:!!G,onClose:()=>q(null),item:G||{},fields:bi.map(e=>({...e,label:s(e.label)})),translationEnabled:$,onApply:e=>{if(!G)return;const t=l.map(t=>t.id===G.id?{...t,...e}:t);r(t),M(!0)}}),n.jsx(x,{title:s("编辑公告内容"),visible:h,onOk:()=>{H.current&&H.current.setValue("content",O.content),m(!1)},onCancel:()=>m(!1),okText:s("确定"),cancelText:s("取消"),width:800,children:n.jsx(S,{value:O.content,placeholder:s("请输入公告内容(支持 Markdown/HTML)"),maxCount:500,rows:15,style:{width:"100%"},onChange:e=>D({...O,content:e})})})]})},{Text:ki}=u,vi=["question","answer"],Ci=[{key:"question",label:"问题标题",type:"input",maxLength:200},{key:"answer",label:"回答内容",type:"textarea",rows:6,maxCount:1e3}],wi=({options:e,refresh:i})=>{const{t:s}=ge(),[l,r]=t.useState([]),[o,c]=t.useState(!1),[u,p]=t.useState(!1),[h,m]=t.useState(null),[y,j]=t.useState(null),[b,_]=t.useState(!1),[S,k]=t.useState(!1),[R,P]=t.useState(!1),[z,N]=t.useState({question:"",answer:""}),[A,M]=t.useState(1),[O,D]=t.useState(10),[L,B]=t.useState([]),[F,W]=t.useState(!0),[J,U]=t.useState(null),V=an(e?.["translation_setting.enabled"]),K=[{title:s("问题标题"),dataIndex:"question",key:"question",render:e=>n.jsx(f,{content:e,showArrow:!0,children:n.jsx("div",{style:{maxWidth:"300px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontWeight:"bold"},children:e})})},{title:s("回答内容"),dataIndex:"answer",key:"answer",render:e=>n.jsx(f,{content:e,showArrow:!0,children:n.jsx("div",{style:{maxWidth:"400px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"hsl(var(--foreground) / 0.80)"},children:e})})},{title:s("翻译"),key:"translation_status",width:110,render:(e,t)=>n.jsx(hn,{item:t,fields:vi,onClick:()=>U(t)})},{title:s("操作"),key:"action",fixed:"right",width:220,render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(Ge,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>U(t),children:s("译文")}),n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>G(t),children:s("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",onClick:()=>q(t),children:s("删除")})]})}],G=e=>{j(e),N({question:e.question,answer:e.answer}),c(!0)},q=e=>{m(e),p(!0)};t.useEffect(()=>{void 0!==e["console_setting.faq"]&&(e=>{if(e)try{const t=JSON.parse(e),n=(Array.isArray(t)?t:[]).map((e,t)=>({...e,id:e.id||t+1}));r(n)}catch(t){console.error("解析常见问答失败:",t),r([])}else r([])})(e["console_setting.faq"])},[e["console_setting.faq"]]),t.useEffect(()=>{const t=e["console_setting.faq_enabled"];W(void 0===t||"true"===t||!0===t)},[e["console_setting.faq_enabled"]]);const $={selectedRowKeys:L,onChange:(e,t)=>
1{B(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsxs("div",{className:"mb-2",children:[n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(tt,{size:16,className:"mr-2"}),n.jsx(ki,{children:s("常见问答管理,为用户提供常见问题的答案(最多50个,前端显示最新20条)")})]}),V&&n.jsxs("div",{className:"flex items-center text-amber-500 mt-1",children:[n.jsx(Ge,{size:14,className:"mr-2"}),n.jsx(ki,{type:"warning",size:"small",children:"t('已开启自动翻译:保存设置时会对未翻译/原文已修改的条目自动翻译为 6 种语言')"})]})]}),n.jsx(I,{margin:"12px"}),n.jsxs("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:[n.jsxs("div",{className:"flex gap-2 w-full md:w-auto order-2 md:order-1",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"w-full md:w-auto",onClick:()=>{j(null),N({question:"",answer:""}),c(!0)},children:s("添加问答")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===L.length)return void je(s("请先选择要删除的常见问答"));const e=l.filter(e=>!L.includes(e.id));r(e),B([]),P(!0),be(s('已删除 {{count}} 个常见问答,请及时点击"保存设置"进行保存',{count:L.length}))},disabled:0===L.length,className:"w-full md:w-auto",children:[s("批量删除")," ",L.length>0&&`(${L.length})`]}),n.jsx(d,{icon:n.jsx(Ze,{size:14}),onClick:async()=>{try{k(!0);let e=l;const t=JSON.stringify(e);await(async(e,t)=>{const n=await ye.put("/api/option/",{key:"console_setting.faq",value:t}),{success:l,message:a}=n.data;l?(be(s("常见问答已更新")),i&&i()):je(a)})(0,t),P(!1)}catch(e){console.error("常见问答更新失败",e),je(s("常见问答更新失败"))}finally{k(!1)}},loading:S,disabled:!R,type:"secondary",className:"w-full md:w-auto",children:s("保存设置")})]}),n.jsxs("div",{className:"order-1 md:order-2 flex items-center gap-2",children:[n.jsx(E,{checked:F,onChange:async e=>{const t=e?"true":"false";try{const n=await ye.put("/api/option/",{key:"console_setting.faq_enabled",value:t});n.data.success?(W(e),be(s("设置已保存")),i?.()):je(n.data.message)}catch(n){je(n.message)}}}),n.jsx(ki,{children:s(F?"已启用":"已禁用")})]})]})]}),children:n.jsx(v,{columns:K,dataSource:(()=>{const e=(A-1)*O,t=e+O;return l.slice(e,t)})(),rowSelection:$,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:A,pageSize:O,total:l.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:e=>s("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:l.length}),pageSizeOptions:["5","10","20","50"],onChange:(e,t)=>
1{M(e),D(t)},onShowSizeChange:(e,t)=>{M(1),D(t)}},size:"middle",loading:S,empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:s("暂无常见问答"),style:{padding:30}}),className:"overflow-hidden"})}),n.jsx(x,{title:s(y?"编辑问答":"添加问答"),visible:o,onOk:async()=>{if(z.question&&z.answer)try{let e;if(_(!0),y)e=l.map(e=>e.id===y.id?{...e,...z}:e);else{const t={id:Math.max(...l.map(e=>e.id),0)+1,...z};e=[...l,t]}r(e),P(!0),c(!1),be(s(y?"问答已更新,请及时点击“保存设置”进行保存":"问答已添加,请及时点击“保存设置”进行保存"))}catch(e){je(s("操作失败")+": "+e.message)}finally{_(!1)}else je(s("请填写完整的问答信息"))},onCancel:()=>c(!1),okText:s("保存"),cancelText:s("取消"),confirmLoading:b,width:800,children:n.jsxs(a,{layout:"vertical",initValues:z,children:[n.jsx(a.Input,{field:"question",label:s("问题标题"),placeholder:s("请输入问题标题"),maxLength:200,rules:[{required:!0,message:s("请输入问题标题")}],onChange:e=>N({...z,question:e})}),n.jsx(a.TextArea,{field:"answer",label:s("回答内容"),placeholder:s("请输入回答内容(支持 Markdown/HTML)"),maxCount:1e3,rows:6,rules:[{required:!0,message:s("请输入回答内容")}],onChange:e=>N({...z,answer:e})})]},y?y.id:"new")}),n.jsx(x,{title:s("确认删除"),visible:u,onOk:()=>{if(h){const e=l.filter(e=>e.id!==h.id);r(e),P(!0),be(s("问答已删除,请及时点击“保存设置”进行保存"))}p(!1),m(null)},onCancel:()=>{p(!1),m(null)},okText:s("确认删除"),cancelText:s("取消"),type:"warning",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(ki,{children:s("确定要删除此问答吗?")})}),n.jsx(xn,{visible:!!J,onClose:()=>U(null),item:J||{},fields:Ci.map(e=>({...e,label:s(e.label)})),translationEnabled:V,onApply:e=>{if(!J)return;const t=l.map(t=>t.id===J.id?{...t,...e}:t);r(t),P(!0)}})]})},{Text:Ti}=u,Ii=({options:e,refresh:i})=>{const{t:s}=ge(),[l,r]=t.useState([]),[o,c]=t.useState(!1),[u,p]=t.useState(!1),[h,m]=t.useState(null),[y,j]=t.useState(null),[f,b]=t.useState(!1),[_,S]=t.useState(!1),[k,R]=t.useState(!1),[P,z]=t.useState({categoryName:"",url:"",slug:""}),[N,A]=t.useState(1),[M,O]=t.useState(10),[D,L]=t.useState([]),[B,F]=t.useState(!0),W=[{title:s("分类名称"),dataIndex:"categoryName",key:"categoryName",render:e=>n.jsx("div",{style:{fontWeight:"bold",color:"hsl(var(--foreground))"},children:e})},{title:s("Uptime Kuma地址"),dataIndex:"url",key:"url",render:e=>n.jsx("div",{style:{maxWidth:"300px",wordBreak:"break-all",fontFamily:"monospace",color:"hsl(var(--primary))"},children:e})},{title:s("状态页面Slug"),dataIndex:"slug",key:"slug",render:e=>n.jsx("div",{style:{fontFamily:"monospace",color:"hsl(var(--foreground) / 0.80)"},children:e})},{title:s("操作"),key:"action",fixed:"right",width:150,render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",onClick:()=>J(t),children:s("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",onClick:()=>U(t),children:s("删除")})]})}],J=e=>{j(e),z({categoryName:e.categoryName,url:e.url,slug:e.slug}),c(!0)},U=e=>{m(e),p(!0)};t.useEffect(()=>{const t=e["console_setting.uptime_kuma_groups"];void 0!==t&&(e=>{if(e)try{const t=JSON.parse(e),n=(Array.isArray(t)?t:[]).map((e,t)=>({...e,id:e.id||t+1}));r(n)}catch(t){console.error("解析Uptime Kuma配置失败:",t),r([])}else r([])})(t)},[e["console_setting.uptime_kuma_groups"]]),t.useEffect(()=>{const t=e["console_setting.uptime_kuma_enabled"];F(void 0===t||"true"===t||!0===t)},[e["console_setting.uptime_kuma_enabled"]]);const V={selectedRowKeys:D,onChange:(e,t)=>
1{L(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsx("div",{className:"mb-2",children:n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(nt,{size:16,className:"mr-2"}),n.jsx(Ti,{children:s("Uptime Kuma监控分类管理,可以配置多个监控分类用于服务状态展示(最多20个)")})]})}),n.jsx(I,{margin:"12px"}),n.jsxs("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:[n.jsxs("div",{className:"flex gap-2 w-full md:w-auto order-2 md:order-1",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"w-full md:w-auto",onClick:()=>{j(null),z({categoryName:"",url:"",slug:""}),c(!0)},children:s("添加分类")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===D.length)return void je(s("请先选择要删除的分类"));const e=l.filter(e=>!D.includes(e.id));r(e),L([]),R(!0),be(s('已删除 {{count}} 个分类,请及时点击"保存设置"进行保存',{count:D.length}))},disabled:0===D.length,className:"w-full md:w-auto",children:[s("批量删除")," ",D.length>0&&`(${D.length})`]}),n.jsx(d,{icon:n.jsx(Ze,{size:14}),onClick:async()=>{try{S(!0);const e=JSON.stringify(l);await(async(e,t)=>{const n=await ye.put("/api/option/",{key:"console_setting.uptime_kuma_groups",value:t}),{success:l,message:a}=n.data;l?(be(s("Uptime Kuma配置已更新")),i&&i()):je(a)})(0,e),R(!1)}catch(e){console.error("Uptime Kuma配置更新失败",e),je(s("Uptime Kuma配置更新失败"))}finally{S(!1)}},loading:_,disabled:!k,type:"secondary",className:"w-full md:w-auto",children:s("保存设置")})]}),n.jsxs("div",{className:"order-1 md:order-2 flex items-center gap-2",children:[n.jsx(E,{checked:B,onChange:async e=>{const t=e?"true":"false";try{const n=await ye.put("/api/option/",{key:"console_setting.uptime_kuma_enabled",value:t});n.data.success?(F(e),be(s("设置已保存")),i?.()):je(n.data.message)}catch(n){je(n.message)}}}),n.jsx(Ti,{children:s(B?"已启用":"已禁用")})]})]})]}),children:n.jsx(v,{columns:W,dataSource:(()=>{const e=(N-1)*M,t=e+M;return l.slice(e,t)})(),rowSelection:V,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:N,pageSize:M,total:l.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:e=>s("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:l.length}),pageSizeOptions:["5","10","20","50"],onChange:(e,t)=>
1{A(e),O(t)},onShowSizeChange:(e,t)=>{A(1),O(t)}},size:"middle",loading:_,empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:s("暂无监控数据"),style:{padding:30}}),className:"overflow-hidden"})}),n.jsx(x,{title:s(y?"编辑分类":"添加分类"),visible:o,onOk:async()=>{if(P.categoryName&&P.url&&P.slug){try{new URL(P.url)}catch(e){return void je(s("请输入有效的URL地址"))}if(/^[a-zA-Z0-9_-]+$/.test(P.slug))try{let e;if(b(!0),y)e=l.map(e=>e.id===y.id?{...e,...P}:e);else{const t={id:Math.max(...l.map(e=>e.id),0)+1,...P};e=[...l,t]}r(e),R(!0),c(!1),be(s(y?"分类已更新,请及时点击“保存设置”进行保存":"分类已添加,请及时点击“保存设置”进行保存"))}catch(e){je(s("操作失败")+": "+e.message)}finally{b(!1)}else je(s("Slug只能包含字母、数字、下划线和连字符"))}else je(s("请填写完整的分类信息"))},onCancel:()=>c(!1),okText:s("保存"),cancelText:s("取消"),confirmLoading:f,width:600,children:n.jsxs(a,{layout:"vertical",initValues:P,children:[n.jsx(a.Input,{field:"categoryName",label:s("分类名称"),placeholder:s("请输入分类名称,如:OpenAI、Claude等"),maxLength:50,rules:[{required:!0,message:s("请输入分类名称")}],onChange:e=>z({...P,categoryName:e})}),n.jsx(a.Input,{field:"url",label:s("Uptime Kuma地址"),placeholder:s("请输入Uptime Kuma服务地址,如:https://status.example.com"),maxLength:500,rules:[{required:!0,message:s("请输入Uptime Kuma地址")}],onChange:e=>z({...P,url:e})}),n.jsx(a.Input,{field:"slug",label:s("状态页面Slug"),placeholder:s("请输入状态页面的Slug,如:my-status"),maxLength:100,rules:[{required:!0,message:s("请输入状态页面Slug")}],onChange:e=>z({...P,slug:e})})]},y?y.id:"new")}),n.jsx(x,{title:s("确认删除"),visible:u,onOk:()=>{if(h){const e=l.filter(e=>e.id!==h.id);r(e),R(!0),be(s("分类已删除,请及时点击“保存设置”进行保存"))}p(!1),m(null)},onCancel:()=>{p(!1),m(null)},okText:s("确认删除"),cancelText:s("取消"),type:"warning",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(Ti,{children:s("确定要删除此分类吗?")})})]})};function Ei(e){const{t:i}=ge(),s=[{key:"hour",label:i("小时"),value:"hour"},{key:"day",label:i("天"),value:"day"},{key:"week",label:i("周"),value:"week"},{key:"month",label:i("月"),value:"month"}],[l,r]=t.useState(!1),[u,p]=t.useState({DataExportEnabled:!1,DataExportInterval:"",DataExportDefaultTime:""}),h=t.useRef(),[x,g]=t.useState(u);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(u).includes(n)&&(t[n]=e.options[n]);p(t),g(structuredClone(t)),h.current.setValues(t),localStorage.setItem("data_export_default_time",String(u.DataExportDefaultTime))},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:l,children:n.jsx(a,{values:u,getFormApi:e=>h.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("数据看板设置"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"DataExportEnabled",label:i("启用数据看板(实验性)"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{p({...u,DataExportEnabled:e})}})})}),n.jsxs(o,{children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{label:i("数据看板更新间隔"),step:1,min:1,suffix:i("分钟"),extraText:i("设置过短会影响数据库性能"),placeholder:i("数据看板更新间隔"),field:"DataExportInterval",onChange:e=>p({...u,DataExportInterval:String(e)})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Select,{label:i("数据看板默认时间粒度"),optionList:s,field:"DataExportDefaultTime",extraText:i("仅修改展示粒度,统计精确到小时"),placeholder:i("数据看板默认时间粒度"),style:{width:180},onChange:e=>p({...u,DataExportDefaultTime:String(e)})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(u,x);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof u[e.key]?String(u[e.key]):u[e.key],ye.put("/api/option/",{key:e.key,value:t})});r(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{r(!1)})},children:i("保存数据看板设置")})})]})})})})}const Ri=()=>{const{t:e}=ge();let[i,s]=t.useState({"console_setting.api_info":"","console_setting.announcements":"","console_setting.faq":"","console_setting.uptime_kuma_groups":"","console_setting.api_info_enabled":"","console_setting.announcements_enabled":"","console_setting.faq_enabled":"","console_setting.uptime_kuma_enabled":"","translation_setting.enabled":!1,ApiInfo:"",Announcements:"",FAQ:"",UptimeKumaUrl:"",UptimeKumaSlug:"",DataExportEnabled:!1,DataExportDefaultTime:"hour",DataExportInterval:5}),[l,a]=t.useState(!1);const[o,c]=t.useState(!1);async function d(){try{a(!0),await(async()=>{const e=await ye.get("/api/option/"),{success:t,message:n,data:l}=e.data;if(t){let e={};l.forEach(t=>{t.key in i&&(e[t.key]=t.value),t.key.endsWith("Enabled")&&"DataExportEnabled"===t.key&&(e[t.key]=an(t.value)),"translation_setting.enabled"===t.key&&(e[t.key]=an(t.value))}),s(e)}else je(n)})()}catch(t){je(e("刷新失败")),console.error(t)}finally{a(!1)}}t.useEffect(()=>{d()},[]);const u=t.useMemo(()=>["ApiInfo","Announcements","FAQ","UptimeKumaUrl","UptimeKumaSlug"].some(e=>i[e]),[i]);return t.useEffect(()=>{u&&c(!0)},[u]),n.jsx(n.Fragment,{children:n.jsxs(m,{spinning:l,size:"large",children:[n.jsxs(x,{title:e("配置迁移确认"),visible:o,onOk:async()=>{try{a(!0),await ye.post("/api/option/migrate_console_setting"),be(e("旧配置迁移完成")),await d(),c(!1)}catch(t){console.error(t),je(e("迁移失败: ")+(t.message||e("未知错误")))}finally{a(!1)}},onCancel:()=>c(!1),confirmLoading:l,okText:e("确认迁移"),cancelText:e("取消"),children:[n.jsx("p",{children:e("检测到旧版本的配置数据,是å
1¦è¦è¿ç§»åˆ°æ–°çš„配置格式?")}),n.jsxs("p",{style:{color:"hsl(var(--warning))",marginTop:"10px"},children:[n.jsx("strong",{children:e("注意:")}),e("迁移过程中会自动处理数据格式转换,迁移完成后旧配置将被清除,请在迁移前在数据库中备份好旧配置。")]})]}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Ei,{options:i,refresh:d})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Si,{options:i,refresh:d})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(ji,{options:i,refresh:d})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(wi,{options:i,refresh:d})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Ii,{options:i,refresh:d})})]})})};function Pi(e){const{t:i}=ge(),[s,l]=t.useState([]),[r,o]=t.useState(!1),[c,u]=t.useState(null),[p,h]=t.useState(""),[m,y]=t.useState(1),[j,f]=t.useState(!1);t.useEffect(()=>{try{const t=JSON.parse(e.options.GroupRatio||"{}"),n=JSON.parse(e.options.UserUsableGroups||"{}"),i=new Set([...Object.keys(t),...Object.keys(n)]),s=Array.from(i).map(e=>({name:e,ratio:void 0===t[e]?"":t[e],description:void 0===n[e]||null===n[e]?"":String(n[e])}));l(s)}catch(t){console.error("JSON解析错误:",t)}},[e.options]);const b=s.filter(e=>!p||e.name.toLowerCase().includes(p.toLowerCase())),_=((e,t)=>{const n=10*(t-1),i=n+10;return e.slice(n,i)})(b,m),S=[{title:i("分组名称"),dataIndex:"name",key:"name"},{title:i("分组倍率"),dataIndex:"ratio",key:"ratio",render:(e,t)=>n.jsx(k,{value:e,placeholder:i("输入倍率"),onChange:e=>C(t.name,"ratio",e)})},{title:i("分组描述"),dataIndex:"description",key:"description",render:(e,t)=>n.jsx(k,{value:e,placeholder:i("输入描述"),onChange:e=>C(t.name,"description",e)})},{title:i("操作"),key:"action",render:(e,t)=>n.jsx(d,{icon:n.jsx(He,{size:16}),type:"danger",onClick:()=>w(t.name)})}],C=(e,t,n)=>{"ratio"===t&&isNaN(n)?je(i("请输入数字")):l(i=>i.map(i=>i.name===e?{...i,[t]:n}:i))},w=e=>{l(t=>t.filter(t=>t.name!==e))};return n.jsxs(n.Fragment,{children:[n.jsxs(g,{vertical:!0,align:"start",style:{width:"100%"},children:[n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>o(!0),children:i("添加分组")}),n.jsx(d,{type:"primary",icon:n.jsx(Ze,{size:16}),onClick:async()=>{f(!0);const t={GroupRatio:{},UserUsableGroups:{}};try{s.forEach(e=>{""===e.ratio||isNaN(parseFloat(e.ratio))||(t.GroupRatio[e.name]=parseFloat(e.ratio)),""!==e.description&&null!==e.description&&void 0!==e.description&&(t.UserUsableGroups[e.name]=String(e.description))});const n={GroupRatio:JSON.stringify(t.GroupRatio,null,2),UserUsableGroups:JSON.stringify(t.UserUsableGroups,null,2)},l=Ee()?"/api/option/":"/api/option/admin",a=Object.entries(n).map(([e,t])=>ye.put(l,{key:e,value:t})),r=await Promise.all(a);if(r.includes(void 0))return je(i("部分保存失败,请重试"));for(const e of r)if(!e.data.success)return je(e.data.message);be(i("保存成功")),e.refresh()}catch(n){console.error("保存失败:",n),je(i("保存失败,请重试"))}finally{f(!1)}},children:i("应用更改")}),n.jsx(k,{prefix:n.jsx(st,{size:16}),placeholder:i("搜索分组名称"),value:p,onChange:e=>{h(e),y(1)},style:{width:200}})]}),n.jsx(v,{columns:S,dataSource:_,pagination:{currentPage:m,pageSize:10,total:b.length,onPageChange:e=>y(e),showTotal:!0,showSizeChanger:!1}})]}),n.jsx(x,{title:i("添加分组"),visible:r,onCancel:()=>o(!1),onOk:()=>{var e;c&&(e=c,s.some(t=>t.name===e.name)?je(i("分组名称已存在")):(l(t=>[{name:e.name,ratio:e.ratio||"",description:e.description||""},...t]),o(!1),be(i("添加成功"))))},children:n.jsxs(a,{children:[n.jsx(a.Input,{field:"name",label:i("分组名称"),required:!0,onChange:e=>u(t=>({...t,name:e}))}),n.jsx(a.Input,{field:"ratio",label:i("分组倍率"),onChange:e=>u(t=>({...t,ratio:e}))}),n.jsx(a.Input,{field:"description",label:i("分组描述"),onChange:e=>u(t=>({...t,description:e}))})]})})]})}function zi(e){const{t:i}=ge(),[s,l]=t.useState([]),[r,o]=t.useState(!1),[c,u]=t.useState(null),[p,h]=t.useState([]),[m,y]=t.useState(!1),[j,f]=t.useState(1),[b,_]=t.useState(10);t.useEffect(()=>{try{const t=JSON.parse(e.options.GroupPermissions||"{}"),n=JSON.parse(e.options.UserUsableGroups||"{}");h(Object.keys(n));const i=Object.entries(t).map(([e,t])=>({group:e,allowedGroups:t,description:n[e]||""}));l(i)}catch(t){console.error("JSON解析错误:",t)}},[e.options]);const S=((e,t,n)=>{const i=(t-1)*n,s=i+n;return e.slice(i,s)})(s,j,b),k=[{title:i("用户组"),dataIndex:"group",key:"group"},{title:i("可用令牌组"),dataIndex:"allowedGroups",key:"allowedGroups",render:(e,t)=>n.jsx(N,{multiple:!0,value:t.allowedGroups,onChange:e=>C(t.group,e),style:{width:"100%"},children:p.map(e=>n.jsx(N.Option,{value:e,children:e},e))})},{title:i("操作"),key:"action",render:(e,t)=>n.jsx(d,{icon:n.jsx(He,{size:16}),type:"danger",onClick:()=>w(t.group)})}],C=(e,t)=>{l(n=>n.map(n=>n.group===e?{...n,allowedGroups:t}:n))},w=e=>{l(t=>t.filter(t=>t.group!==e))};return n.jsxs(n.Fragment,{children:[n.jsxs(g,{vertical:!0,align:"start",style:{width:"100%"},children:[n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>o(!0),children:i("添加新的用户组")}),n.jsx(d,{type:"primary",icon:n.jsx(Ze,{size:16}),onClick:async()=>{y(!0);try{const t={};
1s.forEach(e=>{t[e.group]=e.allowedGroups});const n=Ee()?"/api/option/":"/api/option/admin",l=await ye.put(n,{key:"GroupPermissions",value:JSON.stringify(t,null,2)});if(!l.data.success)return je(l.data.message);be(i("保存成功")),e.refresh()}catch(t){console.error("保存失败:",t),je(i("保存失败,请重试"))}finally{y(!1)}},children:i("应用更改")})]}),n.jsx(v,{columns:k,dataSource:S,pagination:{currentPage:j,pageSize:b,total:s.length,onPageChange:e=>f(e)}})]}),n.jsx(x,{title:i("添加新的用户组"),visible:r,onCancel:()=>o(!1),onOk:()=>{var e;c&&(e=c,s.some(t=>t.group===e.group)?je(i("分组已存在")):(l(t=>[{group:e.group,allowedGroups:e.allowedGroups||[],description:e.description||""},...t]),o(!1),be(i("添加成功"))))},children:n.jsxs(a,{children:[n.jsx(a.Input,{field:"group",label:i("用户组名称"),required:!0,onChange:e=>u(t=>({...t,group:e}))}),n.jsx(a.Select,{field:"allowedGroups",label:i("可用分组"),multiple:!0,onChange:e=>u(t=>({...t,allowedGroups:e})),children:p.map(e=>n.jsx(a.Select.Option,{value:e,children:e},e))})]})})]})}const Ni=({options:e,refresh:i})=>{const{t:s}=ge(),[l,a]=t.useState([]),[r,o]=t.useState(!1);t.useEffect(()=>{if(e.BulkTopUpDiscounts)try{const t=JSON.parse(e.BulkTopUpDiscounts),n=Object.entries(t).map(([e,t])=>({amount:Number(e),ratio:Number(t)}));a(n)}catch(t){console.error("解析折扣数据失败:",t),a([])}},[e.BulkTopUpDiscounts]);const c=(e,t,n)=>{const i=[...l];i[e][t]=n,a(i)},u=[{title:s("充值金额(单位: 刀)"),dataIndex:"amount",render:(e,t,i)=>n.jsx(M,{value:e,onChange:e=>c(i,"amount",e),min:0,style:{width:"100%"}})},{title:s("折扣比例(0-1 0.5 表示50%折扣)"),dataIndex:"ratio",render:(e,t,i)=>n.jsx(M,{value:e,onChange:e=>c(i,"ratio",e),min:0,max:1,step:.1,style:{width:"100%"}})},{title:s("操作"),dataIndex:"operation",render:(e,t,i)=>n.jsx(O,{title:s("确定要删除吗?"),onConfirm:()=>(e=>{const t=l.filter((t,n)=>n!==e);a(t)})(i),children:n.jsx(d,{icon:n.jsx(rt,{size:16}),type:"danger",theme:"borderless"})})}];return n.jsxs("div",{children:[n.jsx(v,{columns:u,dataSource:l,pagination:!1,loading:r}),n.jsxs("div",{style:{marginTop:16,display:"flex",gap:8},children:[n.jsx(d,{icon:n.jsx(ot,{size:16}),onClick:()=>{a([...l,{amount:0,ratio:1}])},children:s("添加折扣")}),n.jsx(d,{type:"primary",onClick:async()=>{try{o(!0);const e={};l.forEach(({amount:t,ratio:n})=>{e[t]=n});const t=Ee()?"/api/option/":"/api/option/admin",n=await ye.put(t,{key:"BulkTopUpDiscounts",value:JSON.stringify(e)});n.data.success?(be(s("保存成功")),i()):je(s("保存失败")+":"+n.data.message)}catch(e){je(s("保存失败")+":"+e.message)}finally{o(!1)}},children:s("保存")})]})]})},Ai=({options:e,refresh:i})=>{const{t:s}=ge(),[l,a]=t.useState([]),[r,o]=t.useState(!1),c=Pe();t.useEffect(()=>{if(e.TopupStarLevels)try{const t=JSON.parse(e.TopupStarLevels),n=Object.entries(t).map(([e,t])=>({name:String(e),price:Number(t)}));a(n)}catch(t){console.error("解析星级数据失败:",t),a([])}else a([])},[e.TopupStarLevels]);const u=(e,t,n)=>{const i=[...l];i[e][t]=n,a(i)},p=[{title:s("星级名称"),dataIndex:"name",render:(e,t,i)=>n.jsx(k,{value:e,onChange:e=>u(i,"name",e),placeholder:s("如:1星 / 老客户"),style:{width:"100%"}})},{title:s("充值单价(元/额度)"),dataIndex:"price",render:(e,t,i)=>n.jsx(M,{value:e,onChange:e=>u(i,"price",e),min:0,step:.001,precision:4,style:{width:"100%"}})},{title:s("操作"),dataIndex:"operation",render:(e,t,i)=>n.jsx(O,{title:s("确定要删除吗?"),onConfirm:()=>(e=>{a(l.filter((t,n)=>n!==e))})(i),children:n.jsx(d,{icon:n.jsx(rt,{size:16}),type:"danger",theme:"borderless"})})}];return c?n.jsxs("div",{children:[n.jsx(v,{columns:p,dataSource:l,pagination:!1,loading:r}),n.jsxs("div",{style:{marginTop:16,display:"flex",gap:8},children:[n.jsx(d,{icon:n.jsx(ot,{size:16}),onClick:()=>{a([...l,{name:"",price:0}])},children:s("添加星级")}),n.jsx(d,{type:"primary",onClick:async()=>{if(c)try{const e={};for(const{name:n,price:i}of l){const t=(n||"").trim();if(!t)return void je(s("星级名称不能为空"));if(Object.prototype.hasOwnProperty.call(e,t))return void je(s("星级名称不能重复")+":"+t);if(!(Number(i)>0))return void je(s("充值单价必须大于 0")+":"+t);e[t]=Number(i)}o(!0);const t=await ye.put("/api/option/admin",{key:"TopupStarLevels",value:JSON.stringify(e)});t.data.success?(be(s("保存成功")),i()):je(s("保存失败")+":"+t.data.message)}catch(e){je(s("保存失败")+":"+e.message)}finally{o(!1)}},children:s("保存")})]})]}):null};function Mi(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({GroupRatio:"",UserUsableGroups:"",GroupPermissions:"",BulkTopUpDiscounts:"",TopupStarLevels:"",GroupGroupRatio:"",GroupModelRatio:"",AutoGroups:"",DefaultUseAutoGroup:!1}),p=t.useRef(),[h,x]=t.useState(r);return t.useEffect(()=>{const t={GroupRatio:"",UserUsableGroups:"",GroupPermissions:"",BulkTopUpDiscounts:"",TopupStarLevels:"",GroupGroupRatio:"",GroupModelRatio:"",AutoGroups:"",DefaultUseAutoGroup:!1};for(let n in e.options)n in t&&(t[n]=e.options[n]);u(t),x(structuredClone(t)),p.current.setValues(t)},[e.options]),n.jsx(m,{spinning:s,children:n.jsxs(b,{type:"line",children:[n.jsx(b.TabPane,{tab:i("可视化编辑令牌组"),itemKey:"visual",children:n.jsx(Pi,{options:r,refresh:e.refresh})}),n.jsx(b.TabPane,{tab:i("用户分组权限设置"),itemKey:"permissions",children:n.jsx(zi,{options:r,refresh:e.refresh})}),n.jsx(b.TabPane,{tab:i("充值折扣设置"),itemKey:"discount",children:n.jsx(Ni,{options:r,refresh:e.refresh})}),Pe()&&n.jsx(b.TabPane,{tab:i("用户星级单价设置"),itemKey:"starLevel",children:n.jsx(Ai,{options:r,refresh:e.refresh})}),n.jsxs(b.TabPane,{tab:i("文本编辑模式"),itemKey:"text",children:[n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("分组设置"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,
1children:n.jsx(a.TextArea,{label:i("分组倍率"),placeholder:i("为一个 JSON 文本,键为分组名称,值为倍率"),extraText:i("group_ratio_hint_002"),field:"GroupRatio",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,GroupRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:i("用户可选分组"),placeholder:i("为一个 JSON 文本,键为分组名称,值为分组描述"),extraText:i("group_ratio_hint_003"),field:"UserUsableGroups",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,UserUsableGroups:e})})})}),n.jsx(o,{gutter:16,children:n.jsxs(c,{xs:24,sm:16,children:[n.jsx(a.TextArea,{label:i("分组权限配置"),placeholder:i("为一个 JSON 文本,键为用户分组,值为该分组可以使用的分组列表"),field:"GroupPermissions",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,GroupPermissions:e})}),n.jsx("div",{style:{marginTop:8,color:"hsl(var(--foreground))"},children:i("group_ratio_hint_004")})]})}),n.jsx(o,{gutter:16,children:n.jsxs(c,{xs:24,sm:16,children:[n.jsx(a.TextArea,{label:i("充值折扣价"),placeholder:i("为一个 JSON 文本,键为充值金额,值为折扣比例"),field:"BulkTopUpDiscounts",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,BulkTopUpDiscounts:e})}),n.jsx("div",{style:{marginTop:8,color:"hsl(var(--foreground))"},children:i('示例: {"100": 0.9, "200": 0.8, "500": 0.7}')})]})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:i("分组特殊倍率"),placeholder:i("为一个 JSON 文本"),extraText:i("group_ratio_hint_005"),field:"GroupGroupRatio",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,GroupGroupRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsxs(c,{xs:24,sm:16,children:[n.jsx(a.TextArea,{label:i("分组模型倍率"),placeholder:i("为一个 JSON 文本,键为分组名称,值为模型倍率映射"),extraText:i("group_ratio_hint_001"),field:"GroupModelRatio",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>u({...r,GroupModelRatio:e})}),n.jsx("div",{style:{marginTop:8,color:"hsl(var(--foreground))"},children:i('示例: {"default": {"kling-*": 0.65, "vidu*": 0.55, "aigc-image-qwen": 0.85}}')})]})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:i("自动分组auto,从第一个开始选择"),placeholder:i("为一个 JSON 文本"),field:"AutoGroups",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>{if(!t||""===t.trim())return!0;try{const e=JSON.parse(t);return!!Array.isArray(e)&&e.every(e=>"string"==typeof e)}catch(n){return!1}},message:i('必须是有效的 JSON 字符串数组,例如:["g1","g2"]')}],onChange:e=>u({...r,AutoGroups:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:16,children:n.jsx(a.Switch,{label:i("创建令牌默认选择auto分组,初始令牌也将设为auto(否则留空,为用户默认分组)"),field:"DefaultUseAutoGroup",onChange:e=>u({...r,DefaultUseAutoGroup:e})})})})]})}),n.jsx(d,{onClick:async function(){try{await p.current.validate().then(()=>{const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=Ee()?"/api/option/":"/api/option/admin",s=t.map(e=>{const t="boolean"==typeof r[e.key]?String(r[e.key]):r[e.key];return ye.put(n,{key:e.key,value:t})});l(!0),Promise.all(s).then(t=>{if(t.includes(void 0))return je(s.length>1?i("部分保存失败,请重试"):i("保存失败"));for(let e=0;e<t.length;e++)if(!t[e].data.success)return je(t[e].data.message);be(i("保存成功")),e.refresh()}).catch(e=>{console.error("Unexpected error:",e),je(i("保存失败,请重试"))}).finally(()=>{l(!1)})}).catch(()=>{je(i("请检查输入"))})}catch(t){je(i("请检查输入")),console.error(t)}},children:i("保存分组设置")})]})]})})}function Oi(e){const[i,s]=t.useState(!1),[l,r]=t.useState({ModelPrice:"",ModelRatio:"",CacheRatio:"",ServiceTierRatio:"",CacheCreation5mRatio:"",CacheCreation1hRatio:"",CompletionRatio:"",ModelStepRatio:"",ModelPixelPrice:"",ModelVideoTokenPrice:"",ModelVideoDurationPrice:"",ModelVideoDurationAudioPrice:"",AudioRatio:"",AudioCompletionRatio:"",ExposeRatioEnabled:!1}),u=t.useRef(),[p,h]=t.useState(l),{t:y}=ge(),[j,f]=t.useState(!1);return t.useEffect(()=>{const t={};for(let n in l)t[n]="ExposeRatioEnabled"===n?void 0!==e.options[n]&&e.options[n]:void 0!==e.options[n]?e.options[n]:"";r(t),h(structuredClone(t)),u.current.setValues(t)},[e.options]),n.jsxs(m,{spinning:i,children:[n.jsxs(a,{values:l,getFormApi:e=>u.current=e,style:{marginBottom:15}
1,children:[n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("模型固定价格"),extraText:y("一次调用消耗多少刀,优先级大于模型倍率"),placeholder:y('为一个 JSON 文本,键为模型名称,值为一次调用消耗多少刀,比如 "gpt-4-gizmo-*": 0.1,一次消耗0.1刀'),field:"ModelPrice",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,ModelPrice:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("模型倍率"),placeholder:y("为一个 JSON 文本,键为模型名称,值为倍率"),field:"ModelRatio",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,ModelRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("提示缓存倍率"),placeholder:y("为一个 JSON 文本,键为模型名称,值为倍率"),field:"CacheRatio",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,CacheRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("服务层级倍率(service_tier)"),extraText:y('键为 service_tier 层级名(如 priority、flex),值为计费倍率。仅当渠道开启「允许 service_tier 透传」且请求带该字段时生效;未配置的层级按 1.0 计费。例如 {"priority": 2, "flex": 0.5}'),placeholder:y('为一个 JSON 文本,键为 service_tier 层级名,值为倍率,如 {"priority": 2, "flex": 0.5}'),field:"ServiceTierRatio",autosize:{minRows:4,maxRows:10},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,ServiceTierRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("缓存写入倍率(5分钟)"),extraText:y("Claude 5分钟缓存写入倍率,留空则使用默认值(通常为 1.25)"),placeholder:y('为一个 JSON 文本,键为模型名称,值为倍率,如 {"claude-sonnet-4-20250514": 1.25}'),field:"CacheCreation5mRatio",autosize:{minRows:4,maxRows:10},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,CacheCreation5mRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("缓存写入倍率(1小时)"),extraText:y("Claude 1小时缓存写入倍率,留空则使用默认值(通常为 2.0,即 5m 倍率 × 1.6)"),placeholder:y('为一个 JSON 文本,键为模型名称,值为倍率,如 {"claude-sonnet-4-20250514": 2.0}'),field:"CacheCreation1hRatio",autosize:{minRows:4,maxRows:10},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,CacheCreation1hRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("模型补全倍率(仅对自定义模型有效)"),extraText:y("仅对自定义模型有效"),placeholder:y("为一个 JSON 文本,键为模型名称,值为倍率"),field:"CompletionRatio",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,CompletionRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:n.jsxs("span",{children:[y("模型阶梯计费倍率"),n.jsx(d,{size:"small",type:"tertiary",onClick:()=>{try{const e={"doubao-seed-1.6-vision":[{step_size:32e3,completion_step_size:-1,prompt_step_ratio:1,completion_step_ratio:1,prompt_thinking_step_ratio:4,completion_thinking_step_ratio:4},{step_size:128e3,completion_step_size:-1,prompt_step_ratio:1.5,completion_step_ratio:2,prompt_thinking_step_ratio:6,completion_thinking_step_ratio:8},{step_size:256e3,completion_step_size:-1,prompt_step_ratio:3,completion_step_ratio:3,prompt_thinking_step_ratio:12,completion_thinking_step_ratio:12}],"doubao-seed-1.6":[{step_size:32e3,completion_step_size:200,prompt_step_ratio:1,completion_step_ratio:1,prompt_thinking_step_ratio:4,completion_thinking_step_ratio:4},{step_size:32e3,completion_step_size:-1,prompt_step_ratio:1,completion_step_ratio:4,prompt_thinking_step_ratio:4,completion_thinking_step_ratio:16},{step_size:128e3,completion_step_size:-1,prompt_step_ratio:1.5,completion_step_ratio:2,prompt_thinking_step_ratio:6,completion_thinking_step_ratio:8},{step_size:256e3,completion_step_size:-1,prompt_step_ratio:3,completion_step_ratio:3,prompt_thinking_step_ratio:12,completion_thinking_step_ratio:12}],"qwen-plus-2025-12-01":[{step_size:12e3,completion_step_size:-1,prompt_step_ratio:.4,completion_step_ratio:2.5,prompt_thinking_step_ratio:.8,completion_thinking_step_ratio:5},{step_size:25e3,completion_step_size:-1,prompt_step_ratio:1.2,completion_step_ratio:8.33,prompt_thinking_step_ratio:2.4,completion_thinking_step_ratio:16.66},{step_size:1e5,completion_step_size:-1,prompt_step_ratio:2.4,completion_step_ratio:11,prompt_thinking_step_ratio:4.8,completion_thinking_step_ratio:22}],"doubao-seed-1.6-lite":[{step_size:32e3,completion_step_size:200,prompt_step_ratio:1,completion_step_ratio:1},{step_size:32e3,completion_step_size:-1,prompt_step_ratio:1,completion_step_ratio:4},{step_size:128e3,completion_step_size:-1,prompt_step_ratio:2,completion_step_ratio:6.667},{step_size:256e3,completion_step_size:-1,prompt_step_ratio:4,completion_step_ratio:20}],"doubao-seed-1.6-flash":[{step_size:32e3,completion_step_size:-1,prompt_step_ratio:1,completion_step_ratio:1},{step_size:128e3,completion_step_size:-1,prompt_step_ratio:2,completion_step_ratio:2},{step_size:256e3,completion_step_size:-1,prompt_step_ratio:4,completion_step_ratio:4}]},t=JSON.stringify(e,null,2),n={...l,ModelStepRatio:t};r(n),u.current&&u.current.setValues(n),be(y("已填入模板,可根据需要修改"))}catch(e){console.error("填入模板失败:",e),je(y("填入模板失败,请稍后重试"))}},style:{marginLeft:"10px"},children:y("填入模板")})]}),extraText:y("根据token使用量分段设置溢价倍率,作为独立的乘数因子应用于配额计算"),placeholder:y("ratio_hint_001"),field:"ModelStepRatio",autosize:{minRows:10,maxRows:20},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>
1{if(!t||""===t.trim())return!0;if(!Re(t))return!1;try{const e=JSON.parse(t);for(const t in e){const n=e[t];if(!Array.isArray(n))throw new Error(`模型 ${t} 的配置必须是数组`);for(let e=0;e<n.length;e++){const i=n[e];if("number"!=typeof i.step_size)throw new Error(`模型 ${t} 第 ${e+1} 个分段的 step_size 必须是数字`);if(void 0!==i.completion_step_size&&"number"!=typeof i.completion_step_size)throw new Error(`模型 ${t} 第 ${e+1} 个分段的 completion_step_size 必须是数字`);if(void 0!==i.prompt_step_ratio&&("number"!=typeof i.prompt_step_ratio||i.prompt_step_ratio<=0))throw new Error(`模型 ${t} 第 ${e+1} 个分段的 prompt_step_ratio 必须是正数`);if(void 0!==i.completion_step_ratio&&("number"!=typeof i.completion_step_ratio||i.completion_step_ratio<=0))throw new Error(`模型 ${t} 第 ${e+1} 个分段的 completion_step_ratio 必须是正数`);if(void 0!==i.prompt_thinking_step_ratio&&("number"!=typeof i.prompt_thinking_step_ratio||i.prompt_thinking_step_ratio<0))throw new Error(`模型 ${t} 第 ${e+1} 个分段的 prompt_thinking_step_ratio 必须是非负数`);if(void 0!==i.completion_thinking_step_ratio&&("number"!=typeof i.completion_thinking_step_ratio||i.completion_thinking_step_ratio<0))throw new Error(`模型 ${t} 第 ${e+1} 个分段的 completion_thinking_step_ratio 必须是非负数`)}}return!0}catch(n){return console.error("JSON validation error:",n),!1}},message:y("JSON格式错误或数据结构不正确")}],onChange:e=>r({...l,ModelStepRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(d,{onClick:()=>f(!0),type:"tertiary",style:{marginTop:"10px",marginBottom:"10px"},children:y("查看配置说明")})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("像素价格"),extraText:y("按百万像素计费,适用于图片生成模型"),placeholder:y('为一个 JSON 文本,键为模型名称,值为每百万像素的价格(美元),如 {"fal-ai/flux-krea-lora/stream": 0.035}'),field:"ModelPixelPrice",autosize:{minRows:4,maxRows:10},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,ModelPixelPrice:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("视频Token价格"),extraText:y("按百万Token计费,适用于视频生成模型"),placeholder:y("为一个 JSON 文本,键为模型名称,值为每百万Token的价格(美元)"),field:"ModelVideoTokenPrice",autosize:{minRows:4,maxRows:10},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,ModelVideoTokenPrice:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("视频时长价格(无音频)"),extraText:y("按秒计费,适用于视频生成模型,不包含音频的价格"),placeholder:y("ratio_hint_003"),field:"ModelVideoDurationPrice",autosize:{minRows:4,maxRows:10},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,ModelVideoDurationPrice:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("视频时长价格(含音频)"),extraText:y("按秒计费,适用于带音频的视频生成模型"),placeholder:y("ratio_hint_004"),field:"ModelVideoDurationAudioPrice",autosize:{minRows:4,maxRows:10},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,ModelVideoDurationAudioPrice:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("音频倍率"),extraText:y("音频输入的倍率,适用于实时音频模型"),placeholder:y("ratio_hint_002"),field:"AudioRatio",autosize:{minRows:4,maxRows:10},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,AudioRatio:e})})})}
1),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:16,children:n.jsx(a.TextArea,{label:y("音频补全倍率"),extraText:y("音频输出的补全倍率,适用于实时音频模型"),placeholder:y('为一个 JSON 文本,键为模型名称,值为倍率,如 {"gpt-4o-realtime": 2, "gpt-4o-mini-realtime": 2}'),field:"AudioCompletionRatio",autosize:{minRows:4,maxRows:10},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>!t||""===t.trim()||Re(t),message:"不是合法的 JSON 字符串"}],onChange:e=>r({...l,AudioCompletionRatio:e})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:16,children:n.jsx(a.Switch,{label:y("暴露倍率接口"),field:"ExposeRatioEnabled",onChange:e=>r({...l,ExposeRatioEnabled:e})})})})]}),n.jsxs(g,{children:[n.jsx(d,{onClick:async function(){try{await u.current.validate().then(()=>{const t=ke(l,p);if(!t.length)return ve(y("你似乎并没有修改什么"));const n=Ee()?"/api/option/":"/api/option/admin",i=t.map(e=>{const t="boolean"==typeof l[e.key]?String(l[e.key]):l[e.key];return ye.put(n,{key:e.key,value:t})});s(!0),Promise.all(i).then(t=>{if(t.includes(void 0))return je(i.length>1?y("部分保存失败,请重试"):y("保存失败"));for(let e=0;e<t.length;e++)if(!t[e].data.success)return je(t[e].data.message);be(y("保存成功")),e.refresh()}).catch(e=>{console.error("Unexpected error:",e),je(y("保存失败,请重试"))}).finally(()=>{s(!1)})}).catch(()=>{je(y("请检查输入"))})}catch(t){je(y("请检查输入")),console.error(t)}},children:y("保存模型倍率设置")}),n.jsx(O,{title:y("确定重置模型倍率吗?"),content:y("此修改将不可逆"),okType:"danger",position:"top",onConfirm:async function(){try{const t=Ee()?"/api/option/rest_model_ratio":"/api/option/admin/rest_model_ratio";let n=await ye.post(t);n.data.success?(be(n.data.message),e.refresh()):je(n.data.message)}catch(t){je(t)}},children:n.jsx(d,{type:"danger",children:y("重置模型倍率")})})]}),n.jsx(x,{title:y("阶梯计费配置说明"),visible:j,onCancel:()=>f(!1),footer:n.jsx(d,{onClick:()=>f(!1),children:y("关闭")}),width:800,bodyStyle:{maxHeight:"70vh",overflow:"auto"},children:n.jsxs("div",{style:{padding:"10px"},children:[n.jsx("h3",{children:y("字段说明")}),n.jsxs("ul",{style:{paddingLeft:"20px",lineHeight:"1.8"},children:[n.jsxs("li",{children:[n.jsx("strong",{children:"step_size"}),": ",y("输入token上限(当前请求输入token≤此值时使用此分段)")]}),n.jsxs("li",{children:[n.jsx("strong",{children:"completion_step_size"}),": ",y("输出token上限(可选,当设置后需同时满足输入和输出条件)")]}),n.jsxs("li",{children:[n.jsx("strong",{children:"prompt_step_ratio"}),": ",y("输入溢价倍率(非思考模式),作为独立的乘数因子应用")]}),n.jsxs("li",{children:[n.jsx("strong",{children:"completion_step_ratio"}),": ",y("输出溢价倍率(非思考模式),作为独立的乘数因子应用")]}),n.jsxs("li",{children:[n.jsx("strong",{children:"prompt_thinking_step_ratio"}),": ",y("输入溢价倍率(思考模式,可选,0或不填表示不启用)")]}),n.jsxs("li",{children:[n.jsx("strong",{children:"completion_thinking_step_ratio"}),": ",y("输出溢价倍率(思考模式,可选,0或不填表示不启用)")]})]}),n.jsx("h3",{children:y("计费规则")}),n.jsxs("ul",{style:{paddingLeft:"20px",lineHeight:"1.8"},children:[n.jsx("li",{children:y("分段按step_size从小到大排序,系统根据实际token使用量自动选择分段")}),n.jsx("li",{children:y("如果超过最大分段,则使用最后一个分段的溢价倍率")})]}),n.jsx("h3",{children:y("配置案例")}),n.jsxs("div",{style:{padding:"15px",background:"#f8f9fa",borderRadius:"4px",marginBottom:"15px"},children:[n.jsx("h4",{style:{marginTop:0},children:y("案例1(仅判断输入)")}),n.jsx("p",{style:{marginBottom:"8px"},children:n.jsx("strong",{children:"doubao-seed-1.6-vision"})}),n.jsxs("p",{style:{marginBottom:"5px"},children:[y("基础价格(≤32k)"),": 输入 0.8元/M tokens,输出 8元/M tokens"]}),n.jsx("p",{style:{marginBottom:"5px"},children:"32k-128k: 输入 1.2元,输出 16元 → prompt_step_ratio=1.5, completion_step_ratio=2"}),n.jsx("p",{style:{marginBottom:"5px"},children:"128k-256k: 输入 2.4元,输出 24元 → prompt_step_ratio=3, completion_step_ratio=3"})]}),n.jsxs("div",{style:{padding:"15px",background:"#fff3cd",borderRadius:"4px",marginBottom:"15px"},children:[n.jsx("h4",{style:{marginTop:0},children:y("案例2(输入输出双重判断)")}),n.jsx("p",{style:{marginBottom:"8px"},children:n.jsx("strong",{children:"doubao-seed-1.6-lite"})}),n.jsxs("p",{style:{marginBottom:"5px"},children:[y("基础价格(输入≤32k 且 输出≤0.2k)"),": 输入 0.3元/M tokens,输出 0.6元/M tokens"]}),n.jsxs("p",{style:{marginBottom:"5px"},children:[y("输入≤32k 但 输出>0.2k"),": 输入 0.3元,输出 2.4元 → completion_step_ratio=4"]}),n.jsxs("p",{style:{marginBottom:"5px",fontSize:"12px",color:"#666"},children:["💡 ",y("注意:这里需要设置 completion_step_size=200(0.2k tokens)来区分两种情况")]})]}),n.jsxs("div",{style:{padding:"15px",background:"#e7f3ff",borderRadius:"4px",border:"1px solid #b3d8ff"},children:[n.jsxs("h4",{style:{marginTop:0},children:["📖 ",y("参考文档")]}),n.jsx("p",{style:{marginBottom:0},children:n.jsxs("a",{href:"https://www.volcengine.com/docs/82379/1544106",target:"_blank",rel:"noopener noreferrer",style:{color:"#0066cc"},children:[y("火山引擎豆包模型官方定价")," ↗"]})})]})]})})]})}function Di(e){const{t:i}=ge(),s=ze(),[l,p]=t.useState([]),[m,y]=t.useState(!1),[f,b]=t.useState(null),[_,S]=t.useState(""),[C,w]=t.useState(1),[T,I]=t.useState(!1),[R,P]=t.useState("per-token"),[z,N]=t.useState("ratio"),[A,M]=t.useState(!1),[O,F]=t.useState(!1),[W,J]=t.useState(!1),U=t.useRef(null),V=s?5:10;Ne(),t.useEffect(()=>{try{const t=JSON.parse(e.options.ModelPrice||"{}"),n=JSON.parse(e.options.ModelRatio||"{}"),i=JSON.parse(e.options.CompletionRatio||"{}"),s=JSON.parse(e.options.ModelPixelPrice||"{}"),l=JSON.parse(e.options.ModelVideoTokenPrice||"{}"),a=JSON.parse(e.options.ModelVideoDurationPrice||"{}"),r=JSON.parse(e.options.CompletionRatioMeta||"{}"),o=JSON.parse(e.options.AudioRatio||"{}"),c=JSON.parse(e.options.AudioCompletionRatio||"{}"),d=JSON.parse(e.options.ImageRatio||"{}"),u=new Set([...Object.keys(t),...Object.keys(n),...Object.keys(i),...Object.keys(s),...Object.keys(l),...Object.keys(a),...Object.keys(o),...Object.keys(c),...Object.keys(d)]),h=Array.from(u).map(e=>
1{const u=void 0===t[e]?"":t[e],p=void 0===n[e]?"":n[e],h=void 0===i[e]?"":i[e],x=void 0===s[e]?"":s[e],m=void 0===l[e]?"":l[e],g=void 0===a[e]?"":a[e],y=r[e]||{},j=void 0===o[e]?"":o[e],f=void 0===c[e]?"":c[e];let b=""!==j?String(j):"",_=""!==f?String(f):"";const S=void 0===d[e]?"":d[e];return{name:e,price:u,ratio:p,completionRatio:h,pixelPrice:x,videoPrice:m,videoDurationPrice:g,audioRatio:b,audioCompletionRatio:_,imageRatio:""!==S?String(S):"",completionRatioLocked:!0===y.locked,lockedCompletionRatio:void 0!==y.ratio?y.ratio:"",hasConflict:(""!==u?1:0)+(""!==p||""!==h?1:0)+(""!==x?1:0)+(""!==m?1:0)+(""!==g?1:0)>1}});p(h)}catch(t){console.error("JSON解析错误:",t)}},[e.options]);const K=l.filter(e=>{const t=!_||e.name.toLowerCase().includes(_.toLowerCase()),n=!A||e.hasConflict;return t&&n}),G=((e,t,n)=>{const i=(t-1)*n,s=i+n;return e.slice(i,s)})(K,C,V),q=[{title:i("模型名称"),dataIndex:"name",key:"name",width:s?120:200,render:(e,t)=>{let s="",l="blue";return"doubao-seedance-2-0-260128"===t.name||"doubao-seedance-2-0-fast-260128"===t.name?(s=i("按量计费"),l="blue"):""!==t.pixelPrice?(s=i("按像素计费"),l="orange"):""!==t.videoPrice?(s=i("按视频尺寸计费"),l="green"):""!==t.videoDurationPrice?(s=i("按视频时长计费"),l="purple"):""!==t.price?(s=i("按次计费"),l="purple"):""===t.ratio&&""===t.completionRatio||(s=i("按量计费"),l="blue"),n.jsxs("div",{className:"space-y-1",children:[n.jsx("div",{className:"text-sm font-medium",children:e}),n.jsxs("div",{className:"flex flex-wrap gap-1",children:[s&&n.jsx(j,{color:l,size:"small",children:s}),t.hasConflict&&n.jsx(j,{color:"red",shape:"circle",size:"small",children:i("矛盾")})]})]})}},{title:i("模型固定价格"),dataIndex:"price",key:"price",width:s?100:150,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("按次计费"),size:s?"small":"default",onChange:e=>$(t.name,"price",e)})},{title:i("像素价格"),dataIndex:"pixelPrice",key:"pixelPrice",width:s?100:150,render:(e,t)=>n.jsx(k,{value:e,placeholder:i(s?"$/1M":"按像素计费($/1M pixels)"),size:s?"small":"default",onChange:e=>$(t.name,"pixelPrice",e)})},{title:i("视频尺寸价格"),dataIndex:"videoPrice",key:"videoPrice",width:s?100:150,render:(e,t)=>n.jsx(k,{value:e,placeholder:i(s?"$/1M":"按视频尺寸计费($/1M tokens)"),size:s?"small":"default",onChange:e=>$(t.name,"videoPrice",e)})},{title:i("视频时长价格"),dataIndex:"videoDurationPrice",key:"videoDurationPrice",width:s?100:150,render:(e,t)=>n.jsx(k,{value:e,placeholder:i(s?"按秒":"按视频时长计费(按秒)"),size:s?"small":"default",onChange:e=>$(t.name,"videoDurationPrice",e)})},{title:i("模型倍率"),dataIndex:"ratio",key:"ratio",width:s?100:150,render:(e,t)=>n.jsx(k,{value:e,placeholder:""!==t.price||""!==t.pixelPrice||""!==t.videoPrice||""!==t.videoDurationPrice?i("模型倍率"):i("默认补全倍率"),disabled:""!==t.price||""!==t.pixelPrice||""!==t.videoPrice||""!==t.videoDurationPrice,size:s?"small":"default",onChange:e=>$(t.name,"ratio",e)})},{title:i("补全倍率"),dataIndex:"completionRatio",key:"completionRatio",width:s?100:150,render:(e,t)=>n.jsx("div",{children:n.jsx(k,{value:t.completionRatioLocked?String(t.lockedCompletionRatio):e,placeholder:""!==t.price||""!==t.pixelPrice||""!==t.videoPrice||""!==t.videoDurationPrice?i("补全倍率"):i("默认补全倍率"),disabled:t.completionRatioLocked||""!==t.price||""!==t.pixelPrice||""!==t.videoPrice||""!==t.videoDurationPrice,size:s?"small":"default",addonAfter:t.completionRatioLocked?n.jsx(j,{size:"small",color:"orange",children:i("锁定")}):null,onChange:e=>$(t.name,"completionRatio",e)})})},{title:i("音频输入价格"),dataIndex:"audioRatio",key:"audioRatio",width:s?100:150,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("音频输入价格"),size:s?"small":"default",onChange:e=>$(t.name,"audioRatio",e)})},{title:i("音频补全价格"),dataIndex:"audioCompletionRatio",key:"audioCompletionRatio",width:s?100:150,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("音频补全价格"),size:s?"small":"default",onChange:e=>$(t.name,"audioCompletionRatio",e)})},{title:i("操作"),key:"action",width:s?80:120,render:(e,t)=>n.jsxs(g,{size:14,children:[n.jsx(d,{type:"primary",icon:n.jsx(at,{size:16}),size:s?"small":"default",onClick:()=>Y(t)}),n.jsx(d,{icon:n.jsx(He,{size:16}),type:"danger",size:s?"small":"default",onClick:()=>H(t.name)})]})}],$=(e,t,n)=>{isNaN(n)?je(i("请输入数字")):p(i=>i.map(i=>{if(i.name!==e)return i;const s={...i,[t]:n};return s.hasConflict=(""!==s.price?1:0)+(""!==s.ratio||""!==s.completionRatio?1:0)+(""!==s.pixelPrice?1:0)+(""!==s.videoPrice?1:0)+(""!==s.videoDurationPrice?1:0)>1,s}))},H=e=>{p(t=>t.filter(t=>t.name!==e))},Q=e=>2*e,X=()=>
1{b(null),P("per-token"),N("ratio"),F(!1),J(!1),U.current&&U.current.reset()},Y=e=>{let t="per-token";t=""!==e.price?"per-request":""!==e.pixelPrice?"per-pixel":""!==e.videoPrice?"per-video":""!==e.videoDurationPrice?"per-video-duration":"per-token",P(t),N("ratio");const n={...e};e.ratio&&(n.tokenPrice=Q(parseFloat(e.ratio)).toString(),e.completionRatio&&(n.completionTokenPrice=(parseFloat(n.tokenPrice)*parseFloat(e.completionRatio)).toString()),e.imageRatio&&(n.imageInputPrice=(parseFloat(n.tokenPrice)*parseFloat(e.imageRatio)).toString())),b(n),F(""!==e.audioRatio&&void 0!==e.audioRatio),J(""!==e.audioCompletionRatio&&void 0!==e.audioCompletionRatio),y(!0),setTimeout(()=>{if(U.current){const e={name:n.name};"per-request"===t?e.priceInput=n.price:"per-pixel"===t?e.pixelPriceInput=n.pixelPrice:"per-video"===t?e.videoPriceInput=n.videoPrice:"per-video-duration"===t?e.videoDurationPriceInput=n.videoDurationPrice:"per-token"===t&&(e.ratioInput=n.ratio,e.completionRatioInput=n.completionRatio,e.modelTokenPrice=n.tokenPrice,e.completionTokenPrice=n.completionTokenPrice,e.imageRatioInput=n.imageRatio||"",e.imageInputPrice=n.imageInputPrice||""),e.audioRatioInput=n.audioRatio||"",e.audioCompletionRatioInput=n.audioCompletionRatio||"",U.current.setValues(e)}},0)};return n.jsxs(n.Fragment,{children:[n.jsxs(g,{vertical:!0,align:"start",style:{width:"100%"},children:[n.jsxs("div",{className:(s?"space-y-2":"flex items-center gap-3")+" w-full",children:[n.jsxs("div",{className:s?"flex flex-wrap gap-2":"flex gap-3",children:[n.jsx(d,{icon:n.jsx(Ye,{size:16}),size:s?"small":"default",onClick:()=>{X(),y(!0)},children:i("添加模型")}),n.jsx(d,{type:"primary",icon:n.jsx(Ze,{size:16}),size:s?"small":"default",loading:T,onClick:async()=>{I(!0);const t={ModelPrice:{},ModelRatio:{},CompletionRatio:{},ModelPixelPrice:{},ModelVideoTokenPrice:{},ModelVideoDurationPrice:{},AudioRatio:{},AudioCompletionRatio:{},ImageRatio:{}};let n="";try{l.forEach(e=>{if(n=e.name,""!==e.price)t.ModelPrice[e.name]=parseFloat(e.price);else if(""!==e.pixelPrice)t.ModelPixelPrice[e.name]=parseFloat(e.pixelPrice);else if(""!==e.videoPrice)t.ModelVideoTokenPrice[e.name]=parseFloat(e.videoPrice);else if(""!==e.videoDurationPrice)t.ModelVideoDurationPrice[e.name]=parseFloat(e.videoDurationPrice);else if(""!==e.ratio&&(t.ModelRatio[e.name]=parseFloat(e.ratio)),""!==e.completionRatio&&(t.CompletionRatio[e.name]=parseFloat(e.completionRatio)),""!==e.imageRatio&&void 0!==e.imageRatio){const n=parseFloat(e.imageRatio);!isNaN(n)&&n>0&&(t.ImageRatio[e.name]=n)}if(""!==e.audioRatio){const n=parseFloat(e.audioRatio);!isNaN(n)&&n>0&&(t.AudioRatio[e.name]=n)}if(""!==e.audioCompletionRatio){const n=parseFloat(e.audioCompletionRatio);!isNaN(n)&&n>0&&(t.AudioCompletionRatio[e.name]=n)}});const s={ModelPrice:JSON.stringify(t.ModelPrice,null,2),ModelRatio:JSON.stringify(t.ModelRatio,null,2),CompletionRatio:JSON.stringify(t.CompletionRatio,null,2),ModelPixelPrice:JSON.stringify(t.ModelPixelPrice,null,2),ModelVideoTokenPrice:JSON.stringify(t.ModelVideoTokenPrice,null,2),ModelVideoDurationPrice:JSON.stringify(t.ModelVideoDurationPrice,null,2),AudioRatio:JSON.stringify(t.AudioRatio,null,2),AudioCompletionRatio:JSON.stringify(t.AudioCompletionRatio,null,2),ImageRatio:JSON.stringify(t.ImageRatio,null,2)},a=Ee()?"/api/option/":"/api/option/admin",r=Object.entries(s).map(([e,t])=>ye.put(a,{key:e,value:t})),o=await Promise.all(r);if(1===r.length){if(o.includes(void 0))return}else if(r.length>1&&o.includes(void 0))return je(i("部分保存失败,请重试"));for(const e of o)if(!e.data.success)return je(e.data.message);be(i("保存成功")),e.refresh()}catch(s){console.error("保存失败:",s),je(i("保存失败,请重试"))}finally{I(!1)}},children:i("应用更改")})]}),n.jsxs("div",{className:s?"flex flex-col gap-2":"flex items-center gap-3",children:[n.jsx(k,{prefix:n.jsx(st,{size:16}),placeholder:i("搜索模型名称"),value:_,onChange:e=>{S(e),w(1)},style:{width:s?"100%":200},size:s?"small":"default",showClear:!0}),n.jsx(D,{checked:A,onChange:e=>{M(e.target.checked),w(1)},className:s?"text-sm":"",children:i("仅显示矛盾倍率")})]})]}),s?n.jsxs("div",{className:"w-full",children:[G.length>0?n.jsx("div",{className:"space-y-3",children:G.map(e=>{let t="",s="blue";return""!==e.pixelPrice?(t=i("按像素计费"),s="orange"):""!==e.videoPrice?(t=i("按è
1§†é¢‘尺寸计费"),s="green"):""!==e.videoDurationPrice?(t=i("按视频时长计费"),s="purple"):""!==e.price?(t=i("按次计费"),s="purple"):""===e.ratio&&""===e.completionRatio||(t=i("按量计费"),s="blue"),n.jsx(r,{className:"mb-3",bodyStyle:{padding:"12px"},children:n.jsxs("div",{className:"space-y-3",children:[n.jsxs("div",{className:"flex items-center justify-between",children:[n.jsxs("div",{className:"flex items-center flex-wrap gap-2",children:[n.jsx(u.Text,{strong:!0,className:"text-sm",children:e.name}),t&&n.jsx(j,{color:s,size:"small",children:t}),e.hasConflict&&n.jsx(j,{color:"red",shape:"circle",children:i("矛盾")})]}),n.jsxs("div",{className:"flex gap-1",children:[n.jsx(d,{type:"primary",icon:n.jsx(at,{size:16}),size:"small",onClick:()=>Y(e)}),n.jsx(d,{icon:n.jsx(He,{size:16}),type:"danger",size:"small",onClick:()=>H(e.name)})]})]}),n.jsxs("div",{className:"space-y-2",children:[n.jsxs(o,{gutter:[8,8],children:[n.jsx(c,{span:12,children:n.jsxs("div",{children:[n.jsx(u.Text,{className:"text-xs text-muted-foreground block mb-1",children:i("固定价格")}),n.jsx(k,{value:e.price,placeholder:i("按次计费"),size:"small",onChange:t=>$(e.name,"price",t)})]})}),n.jsx(c,{span:12,children:n.jsxs("div",{children:[n.jsx(u.Text,{className:"text-xs text-muted-foreground block mb-1",children:i("像素价格")}),n.jsx(k,{value:e.pixelPrice,placeholder:i("$/1M pixels"),size:"small",onChange:t=>$(e.name,"pixelPrice",t)})]})})]}),n.jsxs(o,{gutter:[8,8],children:[n.jsx(c,{span:12,children:n.jsxs("div",{children:[n.jsx(u.Text,{className:"text-xs text-muted-foreground block mb-1",children:i("视频尺寸价格")}),n.jsx(k,{value:e.videoPrice,placeholder:i("$/1M tokens"),size:"small",onChange:t=>$(e.name,"videoPrice",t)})]})}),n.jsx(c,{span:12,children:n.jsxs("div",{children:[n.jsx(u.Text,{className:"text-xs text-muted-foreground block mb-1",children:i("视频时长价格")}),n.jsx(k,{value:e.videoDurationPrice,placeholder:i("按秒"),size:"small",onChange:t=>$(e.name,"videoDurationPrice",t)})]})})]}),n.jsxs(o,{gutter:[8,8],children:[n.jsx(c,{span:12,children:n.jsxs("div",{children:[n.jsx(u.Text,{className:"text-xs text-muted-foreground block mb-1",children:i("模型倍率")}),n.jsx(k,{value:e.ratio,placeholder:""!==e.price||""!==e.pixelPrice||""!==e.videoPrice||""!==e.videoDurationPrice?i("模型倍率"):i("默认补全倍率"),size:"small",disabled:""!==e.price||""!==e.pixelPrice||""!==e.videoPrice||""!==e.videoDurationPrice,onChange:t=>$(e.name,"ratio",t)})]})}),n.jsx(c,{span:12,children:n.jsxs("div",{children:[n.jsxs(u.Text,{className:"text-xs text-muted-foreground block mb-1",children:[i("补全倍率"),e.completionRatioLocked&&n.jsx(j,{size:"small",color:"orange",style:{marginLeft:4},children:i("已锁定")})]}),e.completionRatioLocked&&n.jsx(h,{type:"warning",bordered:!0,fullMode:!1,closeIcon:null,style:{marginBottom:6,padding:"4px 8px"},description:i("该模型补全倍率由后端固定为 {{ratio}},无法修改",{ratio:e.lockedCompletionRatio})}),n.jsx(k,{value:e.completionRatio,placeholder:""!==e.price||""!==e.pixelPrice||""!==e.videoPrice||""!==e.videoDurationPrice?i("补全倍率"):i("默认补全倍率"),size:"small",disabled:e.completionRatioLocked||""!==e.price||""!==e.pixelPrice||""!==e.videoPrice||""!==e.videoDurationPrice,onChange:t=>$(e.name,"completionRatio",t)})]})})]}),n.jsxs(o,{gutter:[8,8],children:[n.jsx(c,{span:12,children:n.jsxs("div",{children:[n.jsx(u.Text,{className:"text-xs text-muted-foreground block mb-1",children:i("音频输入价格")}),n.jsx(k,{value:e.audioRatio,placeholder:i("音频输入价格"),size:"small",onChange:t=>$(e.name,"audioRatio",t)})]})}),n.jsx(c,{span:12,children:n.jsxs("div",{children:[n.jsx(u.Text,{className:"text-xs text-muted-foreground block mb-1",children:i("音频补全价格")}),n.jsx(k,{value:e.audioCompletionRatio,placeholder:i("音频补全价格"),size:"small",onChange:t=>$(e.name,"audioCompletionRatio",t)})]})})]})]})]})},e.name)})}):n.jsx(r,{className:"text-center py-8",children:n.jsx(u.Text,{type:"tertiary",children:i("没有找到匹配的模型")})}),K.length>V&&n.jsx("div",{className:"flex justify-center mt-4",children:n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(d,{size:"small",disabled:1===C,onClick:()=>w(C-1),children:i("上一页")}),n.jsxs(u.Text,{className:"text-sm",children:[C," / ",Math.ceil(K.length/V)]}),n.jsx(d,{size:"small",disabled:C>=Math.ceil(K.length/V),onClick:()=>w(C+1),children:i("下一页")})]})})]}):n.jsx(v,{columns:q,dataSource:G,pagination:{currentPage:C,pageSize:V,total:K.length,onPageChange:e=>w(e),formatPageText:e=>i("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:K.length}),showTotal:!0,showSizeChanger:!1}})]}
1),n.jsx(x,{title:f&&f.name&&l.some(e=>e.name===f.name)?i("编辑模型"):i("添加模型"),visible:m,onCancel:()=>{X(),y(!1)},onOk:()=>{if(f){const t={...f};if("per-token"===R&&"token-price"===z&&f.tokenPrice){const e=parseFloat(f.tokenPrice);if(t.ratio=(e/2).toString(),f.completionTokenPrice&&f.tokenPrice){const e=parseFloat(f.completionTokenPrice),n=parseFloat(f.tokenPrice);n>0&&(t.completionRatio=(e/n).toString())}if(f.imageInputPrice&&f.tokenPrice){const e=parseFloat(f.imageInputPrice),n=parseFloat(f.tokenPrice);n>0&&(t.imageRatio=String(parseFloat((e/n).toFixed(6))))}}"per-token"===R?(t.price="",t.pixelPrice="",t.videoPrice="",t.videoDurationPrice=""):"per-request"===R?(t.ratio="",t.completionRatio="",t.imageRatio="",t.pixelPrice="",t.videoPrice="",t.videoDurationPrice=""):"per-pixel"===R?(t.price="",t.ratio="",t.completionRatio="",t.imageRatio="",t.videoPrice="",t.videoDurationPrice=""):"per-video"===R?(t.price="",t.ratio="",t.completionRatio="",t.imageRatio="",t.pixelPrice="",t.videoDurationPrice=""):"per-video-duration"===R&&(t.price="",t.ratio="",t.completionRatio="",t.imageRatio="",t.pixelPrice="",t.videoPrice=""),e=t,p(t=>{const n=t.findIndex(t=>t.name===e.name);if(n>=0){const i=[...t];return i[n]={...e},i}return[...t,{...e}]}),y(!1),X()}var e},width:s?"95%":600,style:s?{top:20}:{},children:n.jsxs(a,{getFormApi:e=>U.current=e,children:[n.jsx(a.Input,{field:"name",label:i("模型名称"),placeholder:"strawberry",required:!0,disabled:f&&f.name&&l.some(e=>e.name===f.name),onChange:e=>b(t=>({...t,name:e}))}),n.jsx(a.Section,{text:i("定价模式"),children:n.jsx("div",{style:{marginBottom:"16px"},children:n.jsxs(L,{type:"button",value:R,direction:s?"vertical":"horizontal",onChange:e=>{const t=e.target.value;if(P(t),f){const e={...f};if(U.current){const n={name:e.name};"per-request"===t?n.priceInput=e.price||"":"per-pixel"===t?n.pixelPriceInput=e.pixelPrice||"":"per-video"===t?n.videoPriceInput=e.videoPrice||"":"per-video-duration"===t?n.videoDurationPriceInput=e.videoDurationPrice||"":"per-token"===t&&(n.ratioInput=e.ratio||"",n.completionRatioInput=e.completionRatio||"",n.modelTokenPrice=e.tokenPrice||"",n.completionTokenPrice=e.completionTokenPrice||""),n.audioRatioInput=e.audioRatio||"",n.audioCompletionRatioInput=e.audioCompletionRatio||"",U.current.setValues(n)}b(e)}},children:[n.jsx(B,{value:"per-token",children:i("按量计费")}),n.jsx(B,{value:"per-request",children:i("按次计费")}),n.jsx(B,{value:"per-pixel",children:i("按像素计费")}),n.jsx(B,{value:"per-video",children:i("按视频尺寸计费")}),n.jsx(B,{value:"per-video-duration",children:i("按视频时长计费")})]})})}),"per-token"===R&&n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:i("价格设置方式"),children:n.jsx("div",{style:{marginBottom:"16px"},children:n.jsxs(L,{type:"button",value:z,direction:s?"vertical":"horizontal",onChange:e=>{const t=e.target.value,n=z;if(N(t),f){const e={...f};if("ratio"===n&&"token-price"===t&&e.ratio&&(e.tokenPrice=Q(parseFloat(e.ratio)).toString(),e.completionRatio&&(e.completionTokenPrice=(parseFloat(e.tokenPrice)*parseFloat(e.completionRatio)).toString()),e.imageRatio&&(e.imageInputPrice=(parseFloat(e.tokenPrice)*parseFloat(e.imageRatio)).toString())),U.current){const n={};"ratio"===t?(n.ratioInput=e.ratio||"",n.completionRatioInput=e.completionRatio||"",n.imageRatioInput=e.imageRatio||""):"token-price"===t&&(n.modelTokenPrice=e.tokenPrice||"",n.completionTokenPrice=e.completionTokenPrice||"",n.imageInputPrice=e.imageInputPrice||""),n.audioRatioInput=e.audioRatio||"",n.audioCompletionRatioInput=e.audioCompletionRatio||"",U.current.setValues(n)}b(e)}},children:[n.jsx(B,{value:"ratio",children:i("按倍率设置")}),n.jsx(B,{value:"token-price",children:i("按价格设置")})]})})}),"ratio"===z&&n.jsxs(n.Fragment,{children:[n.jsx(a.Input,{field:"ratioInput",label:i("模型倍率"),placeholder:i("输入模型倍率"),onChange:e=>b(t=>({...t||{},ratio:e})),initValue:f?.ratio||""}),n.jsx(a.Input,{field:"completionRatioInput",label:i("补全倍率"),placeholder:i("输入补全倍率"),onChange:e=>b(t=>({...t||{},completionRatio:e})),initValue:f?.completionRatio||""}),n.jsx(a.Input,{field:"imageRatioInput",label:i("图片输入倍率"),placeholder:i("图片输入 token 相对文本输入价的倍率,如 1.6"),onChange:e=>b(t=>({...t||{},imageRatio:e})),initValue:f?.imageRatio||""})]}),"token-price"===z&&n.jsxs(n.Fragment,{children:[n.jsx(a.Input,{field:"modelTokenPrice",label:i("输入价格"),onChange:e=>{(e=>{let t={...f||{},tokenPrice:e,ratio:0};if(!isNaN(e)&&""!==e){const n=parseFloat(e)/2;t.ratio=n}b(t)})(e)},initValue:f?.tokenPrice||"",suffix:i("$/1M tokens")}),n.jsx(a.Input,{field:"completionTokenPrice",label:i("输出价格"),onChange:e=>{(e=>{let t={...f||{},completionTokenPrice:e,completionRatio:0};if(!isNaN(e)&&""!==e&&f?.tokenPrice){const n=parseFloat(e),s=parseFloat(f.tokenPrice);if(s>0){const e=((e,t)=>e&&"0"!==e?t/e:(je(i("模型价格不能为0")),""))(s,n);t.completionRatio=e}}b(t)})(e)},initValue:f?.completionTokenPrice||"",suffix:i("$/1M tokens")}),n.jsx(a.Input,{field:"imageInputPrice",label:i("图片输入价格"),onChange:e=>{(e=>{let t={...f||{},imageInputPrice:e,imageRatio:""};if(!isNaN(e)&&""!==e&&f?.tokenPrice){const n=parseFloat(e),i=parseFloat(f.tokenPrice);i>0&&(t.imageRatio=String(parseFloat((n/i).toFixed(6))))}b(t)})(e)},initValue:f?.imageInputPrice||"",suffix:i("$/1M tokens")})]})]}),"per-request"===R&&n.jsx(a.Input,{field:"priceInput",label:i("固定价格(每次)"),placeholder:i("输入每次价格"),onChange:e=>b(t=>({...t||{},price:e})),initValue:f?.price||""}),"per-pixel"===R&&n.jsx(a.Input,{field:"pixelPriceInput",label:i("每百万像素价格"),placeholder:i("输入每百万像素价格"),onChange:e=>b(t=>({...t||{},pixelPrice:e})),initValue:f?.pixelPrice||"",suffix:i("$/1M pixels")}),"per-video"===R&&n.jsx(a.Input,{field:"videoPriceInput",label:i("视频尺寸价格"),placeholder:i("输入视频尺寸价格"),onChange:e=>b(t=>({...t||{},videoPrice:e})),initValue:f?.videoPrice||"",suffix:i("$/1M tokens")}),"per-video-duration"===R&&n.jsx(a.Input,{field:"videoDurationPriceInput",label:i("视频时长价格"),placeholder:i("输入视频时长价格(按秒)"),onChange:e=>b(t=>({...t||{},videoDurationPrice:e})),initValue:f?.videoDurationPrice||"",suffix:i("$/秒")}),n.jsxs(a.Section,{text:i("扩展价格"),children:[n.jsx("div",{style:{marginBottom:"8px",color:"hsl(var(--muted-foreground))",fontSize:"13px"},children:i("这些价格都是可选项,不填也可以。")}),n.jsxs("div",{style:{marginBottom:"12px"},children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"6px"},children:[n.jsxs("div",{children:[n.jsx("div",{style:{fontSize:"14px",fontWeight:500},children:i("音频输入价格")}),!O&&n.jsx("div",{style:{fontSize:"12px",color:"hsl(var(--muted-foreground))"},children:i("当前未启用,需要时再打开即可。")})]}),n.jsx(E,{checked:O,onChange:e=>{F(e),e||(b(e=>({...e||{},audioRatio:""})),U.current&&U.current.setValue("audioRatioInput",""))}})]}),O&&n.jsx(a.Input,{field:"audioRatioInput",noLabel:!0,placeholder:i("输入音频输入价格"),onChange:e=>b(t=>({...t||{},audioRatio:e})),initValue:f?.audioRatio||"",suffix:i("$/1M tokens")})]}),n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"6px"},children:[n.jsxs("div",{children:[n.jsx("div",{style:{fontSize:"14px",fontWeight:500},children:i("音频补全价格")}),!W&&n.jsx("div",{style:{fontSize:"12px",color:"hsl(var(--muted-foreground))"},children:i("当前未启用,需要时再打开即可。")})]}),n.jsx(E,{checked:W,onChange:e=>{J(e),e||(b(e=>({...e||{},audioCompletionRatio:""})),U.current&&U.current.setValue("audioCompletionRatioInput",""))}})]}),W&&n.jsx(a.Input,{field:"audioCompletionRatioInput",noLabel:!0,placeholder:i("输入音频补全价格"),onChange:e=>b(t=>({...t||{},audioCompletionRatio:e})),initValue:f?.audioCompletionRatio||"",suffix:i("$/1M tokens")})]})]})]})})]})}function Li(e){const{t:i}=ge(),[s,l]=t.useState([]),[r,o]=t.useState(!1),[c,p]=t.useState(!1),[h,m]=t.useState(null),[y,j]=t.useState(""),[f,b]=t.useState(1),[_,S]=t.useState(10),[C,w]=t.useState(!1),[T,I]=t.useState([]),[E,R]=t.useState([]),[P,z]=t.useState("ratio"),[N,A]=t.useState(""),[M,O]=t.useState(""),[D,L]=t.useState(""),[W,J]=t.useState(""),[U,V]=t.useState(""),[K,G]=t.useState(""),[q,$]=t.useState(""),[H,Q]=t.useState(""),[X,Y]=t.useState(""),{Text:Z}=u,ee=async()=>{try{const e=await ye.get("/api/channel/models_enabled"),{success:t,message:n,data:i}=e.data;t?I(i):je(n)}catch(e){console.error(i("获取启用模型失败")+":",e),je(i("获取启用模型失败"))}};t.useEffect(()=>{ee()},[]),t.useEffect(()=>{try{const t=JSON.parse(e.options.ModelPrice||"{}"),n=JSON.parse(e.options.ModelRatio||"{}"),i=JSON.parse(e.options.CompletionRatio||"{}"),s=JSON.parse(e.options.ModelPixelPrice||"{}"),a=JSON.parse(e.options.ModelVideoTokenPrice||"{}"),r=JSON.parse(e.options.ModelVideoDurationPrice||"{}"),o=JSON.parse(e.options.ModelVideoDurationAudioPrice||"{}"),c=JSON.parse(e.options.AudioRatio||"{}"),d=JSON.parse(e.options.AudioCompletionRatio||"{}"),u=T.filter(e=>{const i=void 0!==t[e],l=void 0!==n[e],d=void 0!==s[e],u=void 0!==a[e],p=void 0!==r[e],h=void 0!==o[e],x=void 0!==c[e];return!(i||l||d||u||p||h||x)}).map(e=>({name:e,price:t[e]||"",ratio:n[e]||"",completionRatio:i[e]||"",pixelPrice:s[e]||"",videoTokenPrice:a[e]||"",videoDurationPrice:r[e]||"",videoDurationAudioPrice:o[e]||"",audioRatio:c[e]||"",audioCompletionRatio:d[e]||""}));l(u),R([])}catch(t){console.error(i("JSON解析错误:"),t)}},[e.options,T]);const te=s.filter(e=>!y||e.name.toLowerCase().includes(y.toLowerCase())),ne=((e,t,n)=>{const i=(t-1)*n,s=i+n;return e.slice(i,s)})(te,f,_),ie=[{title:i("模型名称"),dataIndex:"name",key:"name",fixed:"left",width:200},{title:i("固定价格"),dataIndex:"price",key:"price",width:120,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("按次"),onChange:e=>se(t.name,"price",e)})},{title:i("模型倍率"),dataIndex:"ratio",key:"ratio",width:120,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("按量"),disabled:""!==t.price,onChange:e=>se(t.name,"ratio",e)})},{title:i("补全倍率"),dataIndex:"completionRatio",key:"completionRatio",width:120,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("补全"),disabled:""!==t.price,onChange:e=>se(t.name,"completionRatio",e)})},{title:i("像素价格"),dataIndex:"pixelPrice",key:"pixelPrice",width:120,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("按像素"),disabled:""!==t.price,onChange:e=>se(t.name,"pixelPrice",e)})},{title:i("视频Token价格"),dataIndex:"videoTokenPrice",key:"videoTokenPrice",width:140,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("按Token"),disabled:""!==t.price,onChange:e=>se(t.name,"videoTokenPrice",e)})},{title:i("按时长(秒)"),dataIndex:"videoDurationPrice",key:"videoDurationPrice",width:120,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("按秒"),disabled:""!==t.price,onChange:e=>se(t.name,"videoDurationPrice",e)})},{title:i("按时长+音频"),dataIndex:"videoDurationAudioPrice",key:"videoDurationAudioPrice",width:140,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("按秒+音频"),disabled:""!==t.price,onChange:e=>se(t.name,"videoDurationAudioPrice",e)})},{title:i("音频倍率"),dataIndex:"audioRatio",key:"audioRatio",width:120,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("音频"),disabled:""!==t.price,onChange:e=>se(t.name,"audioRatio",e)})},{title:i("音频补全倍率"),dataIndex:"audioCompletionRatio",key:"audioCompletionRatio",width:140,render:(e,t)=>n.jsx(k,{value:e,placeholder:i("音频补全"),disabled:""!==t.price,onChange:e=>se(t.name,"audioCompletionRatio",e)})}],se=(e,t,n)=>{""!==n&&isNaN(n)?je(i("请输入数字")):l(i=>i.map(i=>i.name===e?{...i,[t]:n}:i))},le=e=>{i("Changing batch type to:"),z(e),"bothRatio"!==e?A(""):(O(""),L(""))},ae={selectedRowKeys:E,onChange:e=>{R(e)}};return n.jsxs(n.Fragment,{children:[n.jsxs(g,{vertical:!0,align:"start",style:{width:"100%"},children:[n.jsxs(g,{className:"mt-2",children:[n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>o(!0),children:i("添加模型")}),n.jsxs(d,{icon:n.jsx(ct,{size:16}),type:"secondary",onClick:()=>p(!0),disabled:0===E.length,children:[i("批量设置")," (",E.length,")"]}),n.jsx(d,{type:"primary",icon:n.jsx(Ze,{size:16}),onClick:async()=>{w(!0);const t={ModelPrice:JSON.parse(e.options.ModelPrice||"{}"),ModelRatio:JSON.parse(e.options.ModelRatio||"{}"),CompletionRatio:JSON.parse(e.options.CompletionRatio||"{}"),ModelPixelPrice:JSON.parse(e.options.ModelPixelPrice||"{}"),ModelVideoTokenPrice:JSON.parse(e.options.ModelVideoTokenPrice||"{}"),ModelVideoDurationPrice:JSON.parse(e.options.ModelVideoDurationPrice||"{}"),ModelVideoDurationAudioPrice:JSON.parse(e.options.ModelVideoDurationAudioPrice||"{}"),AudioRatio:JSON.parse(e.options.AudioRatio||"{}"),AudioCompletionRatio:JSON.parse(e.options.AudioCompletionRatio||"{}")};
1try{s.forEach(e=>{""!==e.price?t.ModelPrice[e.name]=parseFloat(e.price):(""!==e.ratio&&(t.ModelRatio[e.name]=parseFloat(e.ratio)),""!==e.completionRatio&&(t.CompletionRatio[e.name]=parseFloat(e.completionRatio)),""!==e.pixelPrice&&(t.ModelPixelPrice[e.name]=parseFloat(e.pixelPrice)),""!==e.videoTokenPrice&&(t.ModelVideoTokenPrice[e.name]=parseFloat(e.videoTokenPrice)),""!==e.videoDurationPrice&&(t.ModelVideoDurationPrice[e.name]=parseFloat(e.videoDurationPrice)),""!==e.videoDurationAudioPrice&&(t.ModelVideoDurationAudioPrice[e.name]=parseFloat(e.videoDurationAudioPrice)),""!==e.audioRatio&&(t.AudioRatio[e.name]=parseFloat(e.audioRatio)),""!==e.audioCompletionRatio&&(t.AudioCompletionRatio[e.name]=parseFloat(e.audioCompletionRatio)))});const n={ModelPrice:JSON.stringify(t.ModelPrice,null,2),ModelRatio:JSON.stringify(t.ModelRatio,null,2),CompletionRatio:JSON.stringify(t.CompletionRatio,null,2),ModelPixelPrice:JSON.stringify(t.ModelPixelPrice,null,2),ModelVideoTokenPrice:JSON.stringify(t.ModelVideoTokenPrice,null,2),ModelVideoDurationPrice:JSON.stringify(t.ModelVideoDurationPrice,null,2),ModelVideoDurationAudioPrice:JSON.stringify(t.ModelVideoDurationAudioPrice,null,2),AudioRatio:JSON.stringify(t.AudioRatio,null,2),AudioCompletionRatio:JSON.stringify(t.AudioCompletionRatio,null,2)},l=Ee()?"/api/option/":"/api/option/admin",a=Object.entries(n).map(([e,t])=>ye.put(l,{key:e,value:t})),r=await Promise.all(a);if(1===a.length){if(r.includes(void 0))return}else if(a.length>1&&r.includes(void 0))return je(i("部分保存失败,请重试"));for(const e of r)if(!e.data.success)return je(e.data.message);be(i("保存成功")),e.refresh(),ee()}catch(n){console.error(i("保存失败")+":",n),je(i("保存失败,请重试"))}finally{w(!1)}},loading:C,children:i("应用更改")}),n.jsx(k,{prefix:n.jsx(st,{size:16}),placeholder:i("搜索模型名称"),value:y,onChange:e=>{j(e),b(1)},style:{width:200}})]}),n.jsx(Z,{children:i("此页面仅显示未设置价格或倍率的模型,设置后将自动从列表中移除")}),n.jsx(v,{columns:ie,dataSource:ne,rowSelection:ae,rowKey:"name",scroll:{x:1600},pagination:{currentPage:f,pageSize:_,total:te.length,onPageChange:e=>b(e),onPageSizeChange:e=>{S(e);const t=Math.ceil(te.length/e);f>t&&b(t||1)},pageSizeOptions:[10,20,50,100],formatPageText:e=>i("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:te.length}),showTotal:!0,showSizeChanger:!0},empty:n.jsx("div",{style:{textAlign:"center",padding:"20px"},children:i("没有未设置的模型")})})]}),n.jsx(x,{title:i("添加模型"),visible:r,onCancel:()=>o(!1),onOk:()=>{var e;h&&(e=h,s.some(t=>t.name===e.name)?je(i("模型名称已存在")):(l(t=>[{name:e.name,price:e.price||"",ratio:e.ratio||"",completionRatio:e.completionRatio||"",pixelPrice:e.pixelPrice||"",videoTokenPrice:e.videoTokenPrice||"",videoDurationPrice:e.videoDurationPrice||"",videoDurationAudioPrice:e.videoDurationAudioPrice||"",audioRatio:e.audioRatio||"",audioCompletionRatio:e.audioCompletionRatio||""},...t]),o(!1),be(i("添加成功"))))},children:n.jsxs(a,{children:[n.jsx(a.Input,{field:"name",label:i("模型名称"),placeholder:"strawberry",required:!0,onChange:e=>m(t=>({...t,name:e}))}),n.jsx(a.Switch,{field:"priceMode",label:n.jsxs(n.Fragment,{children:[i("定价模式"),":",i(h?.priceMode?"固定价格":"倍率模式")]}),onChange:e=>{m(t=>({...t,price:"",ratio:"",completionRatio:"",priceMode:e}))}}),h?.priceMode?n.jsx(a.Input,{field:"price",label:i("固定价格(每次)"),placeholder:i("输入每次价格"),onChange:e=>m(t=>({...t,price:e}))}):n.jsxs(n.Fragment,{children:[n.jsx(a.Input,{field:"ratio",label:i("模型倍率"),placeholder:i("输入模型倍率"),onChange:e=>m(t=>({...t,ratio:e}))}),n.jsx(a.Input,{field:"completionRatio",label:i("补全倍率"),placeholder:i("输入补全价格"),onChange:e=>m(t=>({...t,completionRatio:e}))})]})]})}),n.jsx(x,{title:i("批量设置模型参数"),visible:c,onCancel:()=>p(!1),onOk:()=>{if(0===E.length)return void je(i("请先选择需要批量设置的模型"));if("bothRatio"===P){if(""===M||""===D)return void je(i("请输入模型倍率和补全倍率"));if(isNaN(M)||isNaN(D))return void je(i("请输入有效的数字"))}else{if(""===N)return void je(i("请输入填充值"));if(isNaN(N))return void je(i("请输入有效的数字"))}l(e=>e.map(e=>{if(E.includes(e.name)){const t={...e,price:""};if("price"===P)return{...e,price:N,ratio:"",completionRatio:"",pixelPrice:"",videoTokenPrice:"",videoDurationPrice:"",videoDurationAudioPrice:"",audioRatio:"",audioCompletionRatio:""};if("ratio"===P)return{...t,ratio:N};if("completionRatio"===P)return{...t,completionRatio:N};if("bothRatio"===P)return{...t,ratio:M,completionRatio:D};if("pixelPrice"===P)return{...t,pixelPrice:N};if("videoTokenPrice"===P)return{...t,videoTokenPrice:N};if("videoDurationPrice"===P)return{...t,videoDurationPrice:N};if("videoDurationAudioPrice"===P)return{...t,videoDurationAudioPrice:N};if("audioRatio"===P)return{...t,audioRatio:N};if("audioCompletionRatio"===P)return{...t,audioCompletionRatio:N}}return e})),p(!1);const e={price:i("固定价格"),ratio:i("模型倍率"),completionRatio:i("补全倍率"),bothRatio:i("模型倍率和补全倍率"),pixelPrice:i("像素价格"),videoTokenPrice:i("视频Token价格"),videoDurationPrice:i("按时长(秒)"),videoDurationAudioPrice:i("按时长+音频"),audioRatio:i("音频倍率"),audioCompletionRatio:i("音频补全倍率")};F.success({title:i("批量设置成功"),content:i("已为 {{num}} 个模型设置{{type}}",{num:E.length,type:e[P]||P}),duration:3})},width:600,children:n.jsxs(a,{children:[n.jsx(a.Section,{text:i("设置类型"),children:n.jsx("div",{style:{marginBottom:"16
1px"},children:n.jsxs(g,{vertical:!0,align:"start",children:[n.jsxs(g,{wrap:!0,children:[n.jsx(B,{checked:"price"===P,onChange:()=>le("price"),children:i("固定价格")}),n.jsx(B,{checked:"ratio"===P,onChange:()=>le("ratio"),children:i("模型倍率")}),n.jsx(B,{checked:"completionRatio"===P,onChange:()=>le("completionRatio"),children:i("补全倍率")}),n.jsx(B,{checked:"bothRatio"===P,onChange:()=>le("bothRatio"),children:i("模型+补全倍率")})]}),n.jsxs(g,{wrap:!0,children:[n.jsx(B,{checked:"pixelPrice"===P,onChange:()=>le("pixelPrice"),children:i("按像素计费")}),n.jsx(B,{checked:"videoTokenPrice"===P,onChange:()=>le("videoTokenPrice"),children:i("按视频Token")}),n.jsx(B,{checked:"videoDurationPrice"===P,onChange:()=>le("videoDurationPrice"),children:i("按时长(秒)")}),n.jsx(B,{checked:"videoDurationAudioPrice"===P,onChange:()=>le("videoDurationAudioPrice"),children:i("按时长+音频")})]}),n.jsxs(g,{wrap:!0,children:[n.jsx(B,{checked:"audioRatio"===P,onChange:()=>le("audioRatio"),children:i("音频倍率")}),n.jsx(B,{checked:"audioCompletionRatio"===P,onChange:()=>le("audioCompletionRatio"),children:i("音频补全倍率")})]})]})})}),"bothRatio"===P?n.jsxs(n.Fragment,{children:[n.jsx(a.Input,{field:"batchRatioValue",label:i("模型倍率值"),placeholder:i("请输入模型倍率"),value:M,onChange:e=>O(e)}),n.jsx(a.Input,{field:"batchCompletionRatioValue",label:i("补全倍率值"),placeholder:i("请输入补全倍率"),value:D,onChange:e=>L(e)})]}):n.jsx(a.Input,{field:"batchFillValue",label:i("price"===P?"固定价格值":"ratio"===P?"模型倍率值":"completionRatio"===P?"补全倍率值":"pixelPrice"===P?"像素价格值":"videoTokenPrice"===P?"视频Token价格值":"videoDurationPrice"===P?"时长价格值(每秒)":"videoDurationAudioPrice"===P?"时长+音频价格值(每秒)":"audioRatio"===P?"音频倍率值":"audioCompletionRatio"===P?"音频补全倍率值":"数值"),placeholder:i("请输入数值"),value:N,onChange:e=>A(e)}),n.jsxs(Z,{type:"tertiary",children:[i("将为选中的 ")," ",n.jsx(Z,{strong:!0,children:E.length})," ",i(" 个模型设置相同的值")]}),n.jsx("div",{style:{marginTop:"8px"},children:n.jsxs(Z,{type:"tertiary",children:[i("当前设置类型: ")," ",n.jsx(Z,{strong:!0,children:"price"===P?i("固定价格"):"ratio"===P?i("模型倍率"):"completionRatio"===P?i("补全倍率"):"bothRatio"===P?i("模型倍率和补全倍率"):"pixelPrice"===P?i("按像素计费"):"videoTokenPrice"===P?i("按视频Token"):"videoDurationPrice"===P?i("按时长(秒)"):"videoDurationAudioPrice"===P?i("按时长+音频"):"audioRatio"===P?i("音频倍率"):"audioCompletionRatio"===P?i("音频补全倍率"):P})]})})]})})]})}const Bi=t.forwardRef(({visible:e,onCancel:i,onOk:s,allChannels:l,selectedChannelIds:a,setSelectedChannelIds:o,channelEndpoints:c,updateChannelEndpoint:d,t:u},p)=>{const[h,m]=t.useState(""),[y,f]=t.useState(1),[b,_]=t.useState(10),S=ze(),[C,w]=t.useState([]);t.useImperativeHandle(p,()=>({resetPagination:()=>{f(1),m("")}})),t.useEffect(()=>{if(!l)return;const e=h.trim().toLowerCase(),t=e?l.filter(t=>{const n=(t.label||"").toLowerCase(),i=(t._originalData?.base_url||"").toLowerCase();return n.includes(e)||i.includes(e)}):l;w(t)},[l,h]);const T=C.length,I=C.slice((y-1)*b,y*b),E=(e,t)=>{"function"==typeof d&&d(e,t)},R=e=>"/api/ratio_config"===e?"ratio_config":"/api/pricing"===e?"pricing":"custom",P=e=>{switch(e){case 1:return n.jsx(j,{color:"green",shape:"circle",size:"small",prefixIcon:n.jsx(pt,{size:14}),children:u("已启用")});case 2:return n.jsx(j,{color:"red",shape:"circle",size:"small",prefixIcon:n.jsx(ut,{size:14}),children:u("已禁用")});case 3:return n.jsx(j,{color:"yellow",shape:"circle",size:"small",prefixIcon:n.jsx(dt,{size:14}),children:u("自动禁用")});default:return n.jsx(j,{color:"grey",shape:"circle",size:"small",prefixIcon:n.jsx(tt,{size:14}),children:u("未知状态")})}},z=[{title:u("名称"),dataIndex:"label",render:e=>n.jsx(W,{sourceString:e,searchWords:[h]})},{title:u("源地址"),dataIndex:"_originalData.base_url",render:(e,t)=>{return i=t._originalData?.base_url||"",n.jsx(W,{sourceString:i,searchWords:[h]});var i}},{title:u("状态"),dataIndex:"_originalData.status",render:(e,t)=>P(t._originalData?.status||0)},{title:u("同步接口"),dataIndex:"endpoint",fixed:"right",render:(e,t)=>{const i=t.key||t.value,s=c[i]||"",l=R(s);return n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8}
1,children:[n.jsx(N,{size:"small",value:l,onChange:e=>{"ratio_config"===e?E(i,"/api/ratio_config"):"pricing"===e?E(i,"/api/pricing"):"custom"!==l&&E(i,"")},style:{width:120},optionList:[{label:"ratio_config",value:"ratio_config"},{label:"pricing",value:"pricing"},{label:"custom",value:"custom"}]}),"custom"===l&&n.jsx(k,{size:"small",value:s,onChange:e=>E(i,e),placeholder:"/your/endpoint",style:{width:160,fontSize:12}})]})}}],A={selectedRowKeys:a,onChange:e=>o(e)},M=()=>n.jsxs("div",{className:"px-2 pt-2",children:[n.jsx("div",{className:"grid grid-cols-1 gap-2",children:I.map((e,t)=>{const i=e.key||e.value,s=c[i]||"",l=R(s),d=a.includes(i);return n.jsxs(r,{className:"!rounded-2xl border shadow-sm w-full",bodyStyle:{padding:12},children:[n.jsxs("div",{className:"flex items-start justify-between",children:[n.jsx("div",{className:"text-xs",style:{color:"hsl(var(--muted-foreground))"},children:u("名称")}),n.jsx("div",{className:"flex-1 ml-3 text-sm font-semibold truncate text-right",children:n.jsx(W,{sourceString:e.label,searchWords:[h]})}),n.jsx("div",{className:"ml-3 flex items-center",children:n.jsx(D,{checked:d,onChange:e=>((e,t)=>{const n=new Set(a);t?n.add(e):n.delete(e),o(Array.from(n))})(i,e.target.checked)})})]}),n.jsxs("div",{className:"flex items-center justify-between mt-1",children:[n.jsx("div",{className:"text-xs",style:{color:"hsl(var(--muted-foreground))"},children:u("源地址")}),n.jsx("div",{className:"flex-1 ml-3 text-xs line-clamp-1 text-right",style:{color:"hsl(var(--muted-foreground))",wordBreak:"break-all"},children:n.jsx(W,{sourceString:e._originalData?.base_url||"",searchWords:[h]})})]}),n.jsxs("div",{className:"flex items-center justify-between mt-1",children:[n.jsx("div",{className:"text-xs",style:{color:"hsl(var(--muted-foreground))"},children:u("状态")}),n.jsx("div",{className:"ml-3",children:P(e._originalData?.status||0)})]}),n.jsxs("div",{className:"flex items-center justify-between mt-2",children:[n.jsx("div",{className:"text-xs",style:{color:"hsl(var(--muted-foreground))"},children:u("同步接口")}),n.jsx("div",{className:"ml-3 flex-1 flex justify-end",children:n.jsx(N,{size:"small",value:l,onChange:e=>{"ratio_config"===e?E(i,"/api/ratio_config"):"pricing"===e?E(i,"/api/pricing"):"custom"!==l&&E(i,"")},style:{width:140,minWidth:0},optionList:[{label:"ratio_config",value:"ratio_config"},{label:"pricing",value:"pricing"},{label:"custom",value:"custom"}]})})]}),"custom"===l&&n.jsxs("div",{className:"flex items-center justify-between mt-2",children:[n.jsx("div",{className:"text-xs",style:{color:"hsl(var(--muted-foreground))"},children:u("自定义")}),n.jsx("div",{className:"ml-3 flex-1 flex justify-end",children:n.jsx(k,{size:"small",value:s,onChange:e=>E(i,e),placeholder:"/your/endpoint",style:{width:"100%",maxWidth:220,fontSize:12,minWidth:0}})})]})]},i||t)})}),T>0&&n.jsx("div",{className:"flex justify-center mt-4",children:n.jsx(J,{currentPage:y,pageSize:b,total:T,showSizeChanger:!0,showQuickJumper:!0,size:"small",pageSizeOptions:[10,20,50,100],onPageChange:e=>f(e),onPageSizeChange:e=>{_(e),f(1)}})})]});return n.jsx(x,{visible:e,onCancel:i,onOk:s,title:n.jsx("span",{className:"text-lg font-semibold",children:u("选择同步渠道")}),size:S?"full-width":"large",keepDOM:!0,lazyRender:!1,children:n.jsxs(g,{vertical:!0,style:{width:"100%"},children:[n.jsx(k,{prefix:n.jsx(st,{size:14}),placeholder:u("搜索渠道名称或地址"),value:h,onChange:m,showClear:!0}),S?n.jsx(M,{}):n.jsx(v,{columns:z,dataSource:I,rowKey:"key",rowSelection:A,pagination:{currentPage:y,pageSize:b,total:T,showSizeChanger:!0,showQuickJumper:!0,pageSizeOptions:["10","20","50","100"],formatPageText:e=>u("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:T}),onChange:(e,t)=>
1{f(e),_(t)},onShowSizeChange:(e,t)=>{f(1),_(t)}},size:"small"})]})})});function Fi({t:e,visible:t,items:i,onOk:s,onCancel:l}){const a=ze(),r=[{title:e("渠道"),dataIndex:"channel"},{title:e("模型"),dataIndex:"model"},{title:e("当前计费"),dataIndex:"current",render:e=>n.jsx("div",{style:{whiteSpace:"pre-wrap"},children:e})},{title:e("修改为"),dataIndex:"newVal",render:e=>n.jsx("div",{style:{whiteSpace:"pre-wrap"},children:e})}];return n.jsx(x,{title:e("确认冲突项修改"),visible:t,onCancel:l,onOk:s,size:a?"full-width":"large",children:n.jsx(v,{columns:r,dataSource:i,pagination:!1,size:14})})}function Wi(e){const{t:s}=ge(),[l,r]=t.useState(!1),[o,c]=t.useState(!1),[u,p]=t.useState(!1);ze();const[h,x]=t.useState([]),[m,g]=t.useState([]),[y,b]=t.useState({}),[_,S]=t.useState({}),[I,E]=t.useState({}),[R,P]=t.useState(!1),[z,A]=t.useState(1),[M,O]=t.useState(10),[L,B]=t.useState(""),[F,W]=t.useState(""),[J,U]=t.useState(!1),[V,K]=t.useState([]),G=i.useRef(null);t.useEffect(()=>{A(1)},[F,L]);function q(e){return"model_price"===e?"price":"ratio"}const $=t.useCallback((e,t,n)=>{const i=q(t);E(s=>{const l={...s[e]||{}};return Object.keys(l).forEach(e=>{q(e)!==i&&delete l[e]}),l[t]=n,{...s,[e]:l}})},[E]),H=async()=>{const t={ModelRatio:JSON.parse(e.options.ModelRatio||"{}"),CompletionRatio:JSON.parse(e.options.CompletionRatio||"{}"),CacheRatio:JSON.parse(e.options.CacheRatio||"{}"),ModelPrice:JSON.parse(e.options.ModelPrice||"{}")},n=[];if(Object.entries(I).forEach(([e,i])=>{const l=(e=>void 0!==t.ModelPrice[e]?"price":void 0!==t.ModelRatio[e]||void 0!==t.CompletionRatio[e]||void 0!==t.CacheRatio[e]?"ratio":null)(e),a="model_price"in i?"price":"ratio";if(l&&l!==a){const r="price"===l?`${s("固定价格")} : ${t.ModelPrice[e]}`:`${s("模型倍率")} : ${t.ModelRatio[e]??"-"}\n${s("补全倍率")} : ${t.CompletionRatio[e]??"-"}`;let o="";if("price"===a)o=`${s("固定价格")} : ${i.model_price}`;else{const e=i.model_ratio??"-",t=i.completion_ratio??"-";o=`${s("模型倍率")} : ${e}\n${s("补全倍率")} : ${t}`}const c=Object.entries(i).map(([t,n])=>((e,t,n)=>{if(_[e]&&_[e][t]){const i=_[e][t].upstreams||{},s=Object.entries(i).find(([e,t])=>t===n);if(s)return s[0]}return s("未知")})(e,t,n)).filter((e,t,n)=>n.indexOf(e)===t).join(", ");n.push({channel:c,model:e,current:r,newVal:o})}}),n.length>0)return K(n),void U(!0);await Q(t)},Q=t.useCallback(async t=>{const n={ModelRatio:{...t.ModelRatio},CompletionRatio:{...t.CompletionRatio},CacheRatio:{...t.CacheRatio},ModelPrice:{...t.ModelPrice}};Object.entries(I).forEach(([e,t])=>{const i=Object.keys(t),s=i.includes("model_price"),l=i.some(e=>"model_price"!==e);s&&(delete n.ModelRatio[e],delete n.CompletionRatio[e],delete n.CacheRatio[e]),l&&delete n.ModelPrice[e],Object.entries(t).forEach(([t,i])=>{const s=t.split("_").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join("");n[s][e]=parseFloat(i)})}),c(!0);try{const t=Ee()?"/api/option/":"/api/option/admin",i=Object.entries(n).map(([e,n])=>ye.put(t,{key:e,value:JSON.stringify(n,null,2)}));(await Promise.all(i)).every(e=>e.data.success)?(be(s("同步成功")),e.refresh(),S(e=>{const t={...e};return Object.entries(I).forEach(([e,n])=>{Object.keys(n).forEach(n=>{t[e]&&t[e][n]&&(delete t[e][n],0===Object.keys(t[e]).length&&delete t[e])})}),t}),E({})):je(s("部分保存失败"))}catch(i){je(s("保存失败"))}finally{c(!1)}},[I,e.options,e.refresh]),X=e=>{const t=(z-1)*M,n=t+M;return e.slice(t,n)},Y=t.useCallback((e,t)=>{b(n=>({...n,[e]:t}))},[]);return n.jsxs(n.Fragment,{children:[n.jsx(a.Section,{text:n.jsx("div",{className:"flex flex-col w-full",children:n.jsx("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:n.jsxs("div",{className:"flex flex-col md:flex-row gap-2 w-full md:w-auto order-2 md:order-1",children:[n.jsx(d,{icon:n.jsx(qe,{size:14}),className:"w-full md:w-auto mt-2",onClick:()=>{r(!0),0===h.length&&(async()=>{c(!0);try{const e=await ye.get("/api/ratio_sync/channels");if(e.data.success){const t=(e.data.data||[]).map(e=>({key:e.id,label:e.name,value:e.id,disabled:!1,_originalData:e}));x(t),b(e=>{const n={...e};
1return t.forEach(e=>{n[e.key]||(n[e.key]=Ae)}),n})}else je(e.data.message)}catch(e){je(s("获取渠道失败:")+e.message)}finally{c(!1)}})()},children:s("选择同步渠道")}),(()=>{const e=Object.keys(I).length>0;return n.jsx(d,{icon:n.jsx(ht,{size:14}),type:"secondary",onClick:H,disabled:!e,className:"w-full md:w-auto mt-2",children:s("应用同步")})})(),n.jsxs("div",{className:"flex flex-col sm:flex-row gap-2 w-full md:w-auto mt-2",children:[n.jsx(k,{prefix:n.jsx(st,{size:14}),placeholder:s("搜索模型名称"),value:L,onChange:B,className:"w-full sm:w-64",showClear:!0}),n.jsxs(N,{placeholder:s("按倍率类型筛选"),value:F,onChange:W,className:"w-full sm:w-48",showClear:!0,onClear:()=>W(""),children:[n.jsx(N.Option,{value:"model_ratio",children:s("模型倍率")}),n.jsx(N.Option,{value:"completion_ratio",children:s("补全倍率")}),n.jsx(N.Option,{value:"cache_ratio",children:s("缓存倍率")}),n.jsx(N.Option,{value:"model_price",children:s("固定价格")})]})]})]})})}),children:(()=>{const e=t.useMemo(()=>{const e=[];return Object.entries(_).forEach(([t,n])=>{const i="model_price"in n,s=["model_ratio","completion_ratio","cache_ratio"].some(e=>e in n),l=i&&s;Object.entries(n).forEach(([n,i])=>{e.push({key:`${t}_${n}`,model:t,ratioType:n,current:i.current,upstreams:i.upstreams,confidence:i.confidence||{},billingConflict:l})})}),e},[_]),i=t.useMemo(()=>L.trim()||F?e.filter(e=>{const t=!L.trim()||e.model.toLowerCase().includes(L.toLowerCase().trim()),n=!F||e.ratioType===F;return t&&n}):e,[e,L,F]),l=t.useMemo(()=>{const e=new Set;return i.forEach(t=>{Object.keys(t.upstreams||{}).forEach(t=>e.add(t))}),Array.from(e)},[i]);if(0===i.length)return n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:L.trim()?s("未找到匹配的模型"):0===Object.keys(_).length?s(R?"暂无差异化倍率显示":"请先选择同步渠道"):s("请先选择同步渠道"),style:{padding:30}});const a=[{title:s("模型"),dataIndex:"model",fixed:"left"},{title:s("倍率类型"),dataIndex:"ratioType",render:(e,t)=>{const i={model_ratio:s("模型倍率"),completion_ratio:s("补全倍率"),cache_ratio:s("缓存倍率"),model_price:s("固定价格")},l=n.jsx(j,{color:Me(e),shape:"circle",children:i[e]||e});return t?.billingConflict?n.jsxs("div",{className:"flex items-center gap-1",children:[l,n.jsx(f,{position:"top",content:s("该模型存在固定价格与倍率计费方式冲突,请确认选择"),children:n.jsx(xt,{size:14,className:"text-yellow-500"})})]}):l}},{title:s("置信度"),dataIndex:"confidence",render:(e,t)=>{if(Object.values(t.confidence||{}).every(e=>!1!==e))return n.jsx(f,{content:s("所有上游数据均可信"),children:n.jsx(j,{color:"green",shape:"circle",type:"light",prefixIcon:n.jsx(pt,{size:14}),children:s("可信")})});
1{const e=Object.entries(t.confidence||{}).filter(([e,t])=>!1===t).map(([e])=>e).join(", ");return n.jsx(f,{content:s("以下上游数据可能不可信:")+e,children:n.jsx(j,{color:"yellow",shape:"circle",type:"light",prefixIcon:n.jsx(xt,{size:14}),children:s("谨慎")})})}}},{title:s("当前值"),dataIndex:"current",render:e=>n.jsx(j,{color:null!=e?"blue":"default",shape:"circle",children:null!=e?e:s("未设置")})},...l.map(e=>{const t=(()=>{let t=0,n=0;return i.forEach(i=>{const s=i.upstreams?.[e];null!=s&&"same"!==s&&(t++,I[i.model]?.[i.ratioType]===s&&n++)}),{selectableCount:t,selectedCount:n,allSelected:t>0&&n===t,partiallySelected:n>0&&n<t,hasSelectableItems:t>0}})();return{title:t.hasSelectableItems?n.jsx(D,{checked:t.allSelected,indeterminate:t.partiallySelected,onChange:t=>{t.target.checked?i.forEach(t=>{const n=t.upstreams?.[e];null!=n&&"same"!==n&&$(t.model,t.ratioType,n)}):E(e=>{const t={...e};return i.forEach(e=>{t[e.model]&&(delete t[e.model][e.ratioType],0===Object.keys(t[e.model]).length&&delete t[e.model])}),t})},children:e}):n.jsx("span",{children:e}),dataIndex:e,render:(t,i)=>{const l=i.upstreams?.[e],a=!1!==i.confidence?.[e];if(null==l)return n.jsx(j,{color:"default",shape:"circle",children:s("未设置")});if("same"===l)return n.jsx(j,{color:"blue",shape:"circle",children:s("与本地相同")});const r=I[i.model]?.[i.ratioType]===l;return n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(D,{checked:r,onChange:e=>{e.target.checked?$(i.model,i.ratioType,l):E(e=>{const t={...e};return t[i.model]&&(delete t[i.model][i.ratioType],0===Object.keys(t[i.model]).length&&delete t[i.model]),t})},children:l}),!a&&n.jsx(f,{position:"left",content:s("该数据可能不可信,请谨慎使用"),children:n.jsx(xt,{size:16,className:"text-yellow-500"})})]})}}})];return n.jsx(v,{columns:a,dataSource:X(i),pagination:{currentPage:z,pageSize:M,total:i.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:e=>s("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:e.currentStart,end:e.currentEnd,total:i.length}),pageSizeOptions:["5","10","20","50"],onChange:(e,t)=>
1{A(e),O(t)},onShowSizeChange:(e,t)=>{A(1),O(t)}},scroll:{x:"max-content"},size:"middle",loading:o||u})})()}),n.jsx(Bi,{ref:G,t:s,visible:l,onCancel:()=>{r(!1),G.current&&G.current.resetPagination()},onOk:()=>{const e=h.filter(e=>m.includes(e.value)).map(e=>e._originalData);0!==e.length?(r(!1),(async e=>{p(!0);const t={upstreams:e.map(e=>({id:e.id,name:e.name,base_url:e.base_url,endpoint:y[e.id]||Ae})),timeout:10};try{const e=await ye.post("/api/ratio_sync/fetch",t);if(!e.data.success)return je(e.data.message||s("后端请求失败")),void p(!1);const{differences:n={},test_results:i=[]}=e.data.data,l=i.filter(e=>"error"===e.status);l.length>0&&ve(s("部分渠道测试失败:")+l.map(e=>`${e.name}: ${e.error}`).join(", ")),S(n),E({}),P(!0),0===Object.keys(n).length&&be(s("未找到差异化倍率,无需同步"))}catch(n){je(s("请求后端接口失败:")+n.message)}finally{p(!1)}})(e)):ve(s("请至少选择一个渠道"))},allChannels:h,selectedChannelIds:m,setSelectedChannelIds:g,channelEndpoints:y,updateChannelEndpoint:Y}),n.jsx(Fi,{t:s,visible:J,items:V,onOk:async()=>{U(!1);const t={ModelRatio:JSON.parse(e.options.ModelRatio||"{}"),CompletionRatio:JSON.parse(e.options.CompletionRatio||"{}"),CacheRatio:JSON.parse(e.options.CacheRatio||"{}"),ModelPrice:JSON.parse(e.options.ModelPrice||"{}")};await Q(t)},onCancel:()=>U(!1)})]})}const{Text:Ji}=u,Ui="tool_price_setting.prices",Vi={web_search:10,web_search_preview:10,"web_search_preview:gpt-4o*":25,"web_search_preview:gpt-4.1*":25,"web_search_preview:gpt-4o-mini*":25,"web_search_preview:gpt-4.1-mini*":25,file_search:2.5,google_search:14};function Ki(e){const t={};for(const n of e){const e=n.key.trim();e&&(t[e]=Number(n.price)||0)}return t}function Gi(e){return Object.entries(e).map(([e,t],n)=>({id:n,key:e,price:t}))}function qi({options:e,refresh:i}){const{t:s}=ge(),[l,a]=t.useState([]),[r,o]=t.useState("visual"),[c,u]=t.useState(""),[p,x]=t.useState(""),[m,g]=t.useState(!1);t.useEffect(()=>{let t={};try{const n=e?.[Ui];n&&(t="string"==typeof n?JSON.parse(n):n)}catch{t={}}t&&0!==Object.keys(t).length||(t={...Vi}),a(Gi(t)),u(JSON.stringify(t,null,2))},[e]);const y=e=>{a(e),u(JSON.stringify(Ki(e),null,2)),x("")},j=(e,t,n)=>{y(l.map(i=>i.id===e?{...i,[t]:n}:i))},f=()=>{y(Gi(Vi))},b=t.useMemo(()=>Ki(l),[l]),_=[{title:s("工具标识"),dataIndex:"key",render:(e,t)=>n.jsx(k,{value:e,placeholder:"web_search_preview:gpt-4o*",onChange:e=>j(t.id,"key",e),style:{width:"100%"}})},{title:s("价格")+" ($/1K"+s("次")+")",dataIndex:"price",width:160,render:(e,t)=>n.jsx(M,{value:e,min:0,step:.5,onChange:e=>j(t.id,"price",e??0),style:{width:"100%"}})},{title:s("操作"),width:60,render:(e,t)=>n.jsx(d,{icon:n.jsx(U,{}),type:"danger",theme:"borderless",size:"small",onClick:()=>{return e=t.id,void y(l.filter(t=>t.id!==e));var e}})}];return n.jsxs("div",{style:{maxWidth:700},children:[n.jsx(h,{type:"info",description:n.jsxs(n.Fragment,{children:[n.jsx("div",{children:s("配置各工具的调用价格($/1K次调用)。按次计费模型不额外收取工具费用。")}),n.jsxs("div",{style:{marginTop:4},children:[n.jsxs(Ji,{strong:!0,children:[s("格式"),":"]}),n.jsx("code",{children:"web_search_preview"})," ",s("为默认价格"),",",n.jsx("code",{children:"web_search_preview:gpt-4o*"})," ",s("为模型前缀覆盖")]})]}),style:{marginBottom:16}}),n.jsxs(L,{type:"button",size:"small",value:r,onChange:e=>o(e.target.value),style:{marginBottom:12},children:[n.jsx(B,{value:"visual",children:s("可视化")}),n.jsx(B,{value:"json",children:"JSON"})]}),"visual"===r?n.jsxs(n.Fragment,{children:[n.jsx(v,{dataSource:l,columns:_,pagination:!1,size:"small",rowKey:"id"}),n.jsxs("div",{style:{display:"flex",gap:8,marginTop:12},children:[n.jsx(d,{icon:n.jsx(V,{}),onClick:()=>{y([...l,{id:Date.now(),key:"",price:0}])},children:s("添加")}),n.jsx(d,{theme:"borderless",onClick:f,children:s("恢复默认")})]})]}):n.jsxs(n.Fragment,{children:[n.jsx(S,{value:c,onChange:e=>{u(e);try{const t=JSON.parse(e);if("object"!=typeof t||Array.isArray(t)||null===t)return void x(s("JSON 必须是对象"));a(Gi(t)),x("")}catch(t){x(t.message)}},autosize:{minRows:8,maxRows:20},style:{fontFamily:"monospace",fontSize:13}}),p&&n.jsx(Ji,{type:"danger",size:"small",style:{display:"block",marginTop:4},children:p}),n.jsxs("div",{style:{display:"flex",gap:8,marginTop:8},children:[n.jsx(d,{icon:n.jsx(K,{}),size:"small",theme:"borderless",onClick:()=>{Oe(c)},children:s("复制")}),n.jsx(d,{size:"small",theme:"borderless",onClick:f,children:s("恢复默认")})]})]}),n.jsx("div",{style:{display:"flex",justifyContent:"flex-end",marginTop:16},children:n.jsx(d,{theme:"solid",type:"primary",loading:m,disabled:"json"===r&&!!p,onClick:async()=>{g(!0);try{const e=Ee()?"/api/option/":"/api/option/admin",t=await ye.put(e,{key:Ui,value:JSON.stringify(b)});t.data.success?(be(s("保存成功")),i&&i()):je(t.data.message||s("保存失败"))}catch(e){je(e.message)}finally{g(!1)}},children:s("保存")})})]})}const $i=()=>{const{t:e}=ge();let[i,s]=t.useState({ModelPrice:"",ModelRatio:"",CacheRatio:"",CompletionRatio:"",ModelStepRatio:"",GroupRatio:"",GroupGroupRatio:"",AutoGroups:"",DefaultUseAutoGroup:!1,ExposeRatioEnabled:!1,UserUsableGroups:"",GroupPermissions:"",BulkTopUpDiscounts:""});const[l,a]=t.useState(!1),o=async()=>{try{a(!0),await(async()=>{try{const e=Ee()?"/api/option/":"/api/option/admin",t=await ye.get(e),{success:n,message:i,data:l}=t.data;if(n){let e={};l.forEach(t=>{if("ModelRatio"===t.key||"GroupRatio"===t.key||"GroupGroupRatio"===t.key||"AutoGroups"===t.key||"UserUsableGroups"===t.key||"CompletionRatio"===t.key||"ModelPrice"===t.key||"CacheRatio"===t.key||"ModelStepRatio"===t.key||"GroupPermissions"===t.key||"BulkTopUpDiscounts"===t.key)try{t.value=JSON.stringify(JSON.parse(t.value),null,2)}catch(n){}["DefaultUseAutoGroup","ExposeRatioEnabled"].includes(t.key)?e[t.key]=an(t.value):e[t.key]=t.value}),s(e)}else je(i)}catch(t){console.error("获取选项失败:",t),je(e("获取选项失败,请刷新重试")),s({ModelPrice:"",ModelRatio:"",CacheRatio:"",CompletionRatio:"",ModelStepRatio:"",GroupRatio:"",GroupGroupRatio:"",AutoGroups:"",DefaultUseAutoGroup:!1,ExposeRatioEnabled:!1,UserUsableGroups:"",GroupPermissions:"",BulkTopUpDiscounts:""})}})()}catch(t){je(e("刷新失败"))}finally{a(!1)}};return t.useEffect(()=>{o()},[]),n.jsx(m,{spinning:l,size:"large",children:n.jsx(r,{style:{marginTop:"10px"},children:n.jsxs(b,{type:"card",children:[n.jsx(b.TabPane,{tab:e("可视化模型倍率设置"),itemKey:"visual",children:n.jsx(Di,{options:i,refresh:o})}),n.jsx(b.TabPane,{tab:e("模型倍率设置"),itemKey:"model",children:n.jsx(Oi,{options:i,refresh:o})}),n.jsx(b.TabPane,{tab:e("未设置倍率模型"),itemKey:"unset_models",children:n.jsx(Li,{options:i,refresh:o})}),n.jsx(b.TabPane,{tab:e("上游倍率同步"),itemKey:"upstream_sync",children:n.jsx(Wi,{options:i,refresh:o})}),n.jsx(b.TabPane,{tab:e("分组相关设置"),itemKey:"group",children:n.jsx(Mi,{options:i,refresh:o})}),n.jsx(b.TabPane,{tab:e("工具调用定价"),itemKey:"tool_price",children:n.jsx(qi,{options:i,refresh:o})})]})})})};function Hi(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,o]=t.useState({Chats:"[]"}),c=t.useRef(),[u,p]=t.useState(r);return t.useEffect(()=>{const t={};for(let n in e.options)if(Object.keys(r).includes(n))if("Chats"===n){const i=JSON.parse(e.options[n]);t[n]=JSON.stringify(i,null,2)}else t[n]=e.options[n];o(t),p(structuredClone(t)),c.current.setValues(t)},[e.options]),n.jsxs(m,{spinning:s,children:[n.jsx(a,{values:r,getFormApi:e=>c.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("聊天设置"),children:[n.jsx(h,{type:"info",description:n.jsxs("div",{children:[n.jsx("div",{children:i("链接中支持以下占位符自动替换:")}),n.jsxs("div",{style:{marginTop:"8px",fontSize:"13px",lineHeight:"1.6"},children:[n.jsxs("div",{children:["• ",n.jsx("code",{children:"{key}"})," - ",i("替换为 sk-xxxx 格式的令牌")]}),n.jsxs("div",{children:["• ",n.jsx("code",{children:"{address}"})," - ",i("替换为系统设置的服务器地址(末尾不带/和/v1)")]}),n.jsx("div",{style:{marginTop:"6px",fontWeight:"bold"},children:i("Cherry Studio 专用占位符:")}),n.jsxs("div",{children:["• ",n.jsx("code",{children:"{openai_base64}"})," - ",i("OpenAI 配置的 base64 编码")]}),n.jsxs("div",{children:["• ",n.jsx("code",{children:"{openai_response_base64}"})," - ",i("OpenAI Response 配置的 base64 编码")]}),n.jsxs("div",{children:["• ",n.jsx("code",{children:"{anthropic_base64}"})," - ",i("Anthropic 配置的 base64 编码")]}),n.jsxs("div",{children:["• ",n.jsx("code",{children:"{gemini_base64}"})," - ",i("Gemini 配置的 base64 编码")]})]})]})}),n.jsx(a.TextArea,{label:i("聊天配置"),extraText:"",placeholder:i("为一个 JSON 文本"),field:"Chats",autosize:{minRows:6,maxRows:12},trigger:"blur",stopValidateWithError:!0,rules:[{validator:(e,t)=>
1Re(t),message:i("不是合法的 JSON 字符串")}],onChange:e=>o({...r,Chats:e})})]})}),n.jsx(g,{children:n.jsx(d,{onClick:async function(){try{await c.current.validate().then(()=>{const t=ke(r,u);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof r[e.key]?String(r[e.key]):r[e.key],ye.put("/api/option/",{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})}).catch(e=>{console.error("Validation failed:",e),je(i("请检查输入"))})}catch(t){je(i("请检查输入")),console.error(t)}},children:i("保存聊天设置")})})]})}const Qi=()=>{const{t:e}=ge();let[i,s]=t.useState({Chats:"[]"}),[l,a]=t.useState(!1);async function o(){try{a(!0),await(async()=>{const e=await ye.get("/api/option/"),{success:t,message:n,data:i}=e.data;if(t){let e={};i.forEach(t=>{t.key.endsWith("Enabled")||["DefaultCollapseSidebar"].includes(t.key)?e[t.key]=an(t.value):e[t.key]=t.value}),s(e)}else je(n)})()}catch(t){je(e("刷新失败"))}finally{a(!1)}}return t.useEffect(()=>{o()},[]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:l,size:"large",children:n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Hi,{options:i,refresh:o})})})})};function Xi(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({DrawingEnabled:!1,MjNotifyEnabled:!1,MjAccountFilterEnabled:!1,MjForwardUrlEnabled:!1,MjModeClearEnabled:!1,MjActionCheckSuccessEnabled:!1}),p=t.useRef(),[h,x]=t.useState(r);return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(r).includes(n)&&(t[n]=e.options[n]);u(t),x(structuredClone(t)),p.current.setValues(t),localStorage.setItem("mj_notify_enabled",String(r.MjNotifyEnabled))},[e.options]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("绘图设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"DrawingEnabled",label:i("启用绘图功能"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{u({...r,DrawingEnabled:e})}})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"MjNotifyEnabled",label:i("允许回调(会泄露服务器 IP 地址)"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>u({...r,MjNotifyEnabled:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"MjAccountFilterEnabled",label:i("允许 AccountFilter 参数"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>u({...r,MjAccountFilterEnabled:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"MjForwardUrlEnabled",label:i("开启之后将上游地址替换为服务器地址"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>u({...r,MjForwardUrlEnabled:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"MjModeClearEnabled",label:i("开启之后会清除用户提示词中的 --fast、--relax 以及 --turbo 参数"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>u({...r,MjModeClearEnabled:e})})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"MjActionCheckSuccessEnabled",label:i("检测必须等待绘图成功才能进行放大等操作"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>u({...r,MjActionCheckSuccessEnabled:e})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=t.map(e=>{let t="";return t="boolean"==typeof r[e.key]?String(r[e.key]):r[e.key],ye.put("/api/option/",{key:e.key,value:t})});l(!0),Promise.all(n).then(t=>{if(1===n.length){if(t.includes(void 0))return}else if(n.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存绘图设置")})})]})})})})}const Yi=()=>{const{t:e}=ge();let[i,s]=t.useState({DrawingEnabled:!1,MjNotifyEnabled:!1,MjAccountFilterEnabled:!1,MjForwardUrlEnabled:!1,MjModeClearEnabled:!1,MjActionCheckSuccessEnabled:!1}),[l,a]=t.useState(!1);async function o(){try{a(!0),await(async()=>{const e=await ye.get("/api/option/"),{success:t,message:n,data:i}=e.data;if(t){let e={};
1i.forEach(t=>{t.key.endsWith("Enabled")?e[t.key]=an(t.value):e[t.key]=t.value}),s(e)}else je(n)})()}catch(t){je(e("刷新失败"))}finally{a(!1)}}return t.useEffect(()=>{o()},[]),n.jsx(n.Fragment,{children:n.jsx(m,{spinning:l,size:"large",children:n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Xi,{options:i,refresh:o})})})})};function Zi(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,o]=t.useState({ServerAddress:""}),c=t.useRef(null);return t.useEffect(()=>{if(e.options&&c.current){const t={ServerAddress:e.options.ServerAddress||""};o(t),c.current.setValues(t)}},[e.options]),n.jsx(m,{spinning:s,children:n.jsx(a,{initValues:r,onValueChange:e=>{o(e)},getFormApi:e=>c.current=e,children:n.jsxs(a.Section,{text:i("通用设置"),children:[n.jsx(a.Input,{field:"ServerAddress",label:i("服务器地址"),placeholder:"https://yourdomain.com",style:{width:"100%"},extraText:i("该服务器地址将影响支付回调地址以及默认首页展示的地址,请确保正确配置")}),n.jsx(d,{onClick:async()=>{l(!0);try{let t=fe(r.ServerAddress);const n=await ye.put("/api/option/",{key:"ServerAddress",value:t});n.data.success?(be(i("更新成功")),e.refresh&&e.refresh()):je(n.data.message)}catch(t){je(i("更新失败"))}l(!1)},children:i("更新服务器地址")})]})})})}const{Text:es}=u;function ts(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState(!1),[p,x]=t.useState({PayAddress:"",EpayId:"",EpayKey:"",Price:7.3,MinTopUp:1,TopupGroupRatio:"",CustomCallbackAddress:"",PayMethods:"",PayChannelNames:"",SubSiteFollowMainPayment:"true",SubSitePayAddress:"",SubSiteEpayId:"",SubSiteEpayKey:"",ForceHideBepusdt:!1}),[g,y]=t.useState({}),f=t.useRef(null),b={WebkitTextSecurity:"disc"},[_,S]=t.useState([]),[v,w]=t.useState([]),[T,E]=t.useState(!1),[R,P]=t.useState(""),[z,N]=t.useState(!1),A=e=>({value:e.id,label:`${e.username||e.display_name||i("用户")+e.id} (ID: ${e.id})`}),M=async e=>{const t=(e||"").trim();if(t){E(!0);try{const e=await ye.get(`/api/user/search?keyword=${encodeURIComponent(t)}&page_size=20&p=0`);if(e.data.success){const t=e.data.data?.items||[];w(t.map(A))}else w([])}catch{w([])}E(!1)}else w([])};return t.useEffect(()=>{if(e.options&&f.current){const t={PayAddress:e.options.PayAddress||"",EpayId:e.options.EpayId||"",EpayKey:e.options.EpayKey||"",Price:void 0!==e.options.Price?parseFloat(e.options.Price):7.3,MinTopUp:void 0!==e.options.MinTopUp?parseFloat(e.options.MinTopUp):1,TopupGroupRatio:e.options.TopupGroupRatio||"",CustomCallbackAddress:e.options.CustomCallbackAddress||"",PayMethods:e.options.PayMethods||"",PayChannelNames:e.options.PayChannelNames||"",SubSiteFollowMainPayment:"false"!==e.options.SubSiteFollowMainPayment?"true":"false",SubSitePayAddress:e.options.SubSitePayAddress||"",SubSiteEpayId:e.options.SubSiteEpayId||"",SubSiteEpayKey:e.options.SubSiteEpayKey||"",ForceHideBepusdt:!0===e.options.ForceHideBepusdt||"true"===e.options.ForceHideBepusdt};x(t),y({...t}),f.current.setValues(t),(async e=>{const t=e.split(",").map(e=>e.trim()).filter(Boolean);if(0===t.length)return void S([]);const n=await Promise.all(t.map(async e=>{try{const t=await ye.get(`/api/user/search?user_id=${e}&page_size=1&p=0`);if(t.data.success&&t.data.data?.items?.length>0){const e=t.data.data.items[0];return{value:e.id,label:`${e.username||e.display_name||i("用户")+e.id} (ID: ${e.id})`}}}catch{}return{value:parseInt(e),label:`${i("用户")}${e}`}}));S(n)})(e.options.BepusdtHideUserIds||"")}},[e.options]),n.jsx(m,{spinning:s,children:n.jsxs(a,{initValues:p,onValueChange:e=>{x(t=>({...t,...e}))},getFormApi:e=>f.current=e,autoComplete:"off",children:[n.jsxs(a.Section,{text:i("支付设置"),children:[n.jsx(es,{children:i("(当前仅支持易支付接口,默认使用上方服务器地址作为回调地址!)")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"PayAddress",label:i("支付地址"),placeholder:i("例如:https://yourdomain.com")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"EpayId",label:i("易支付商户ID"),placeholder:i("例如:0001"),autoComplete:"off"})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"EpayKey",label:i("易支付商户密钥"),placeholder:i("敏感信息不会发送到前端显示"),autoComplete:"off",style:b,inputStyle:b})})]}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:[n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"CustomCallbackAddress",label:i("回调地址"),placeholder:i("例如:https://yourdomain.com")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"Price",precision:2,label:i("充值价格(x元/美金)"),placeholder:i("例如:7,就是7元/美金")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"MinTopUp",label:i("最低充值美元数量"),placeholder:i("例如:2,就是最低充值2$")})})]}),n.jsx(a.TextArea,{field:"TopupGroupRatio",label:i("充值分组倍率"),placeholder:i("为一个 JSON 文本,键为组名称,值为倍率"),autosize:!0}),n.jsx(a.TextArea,{field:"PayMethods",label:i("充值方式设置"),placeholder:i("为一个 JSON 文本"),autosize:!0}),n.jsx(a.TextArea,{field:"PayChannelNames",label:i("支付渠道名称映射"),placeholder:i('为一个 JSON 对象,键为渠道ID,值为渠道名称。例如:{"1": "支付宝", "2": "微信支付"}'),extraText:i("用于开票记录中显示支付渠道名称(仅财务可见)"),autosize:!0}),n.jsx(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Switch,{field:"ForceHideBepusdt",label:i("强制隐藏虚拟货币支付"),extraText:i("开启后,所有用户(含海外IP)均不会看到虚拟货币支付选项")})})}),n.jsx(I,{style:{margin:"16px 0"}}),n.jsxs("div",{style:{padding:16,borderRadius:8,border:"1px solid var(--semi-color-border)",background:"var(--semi-color-fill-0)"},children:[n.jsxs("div",{style:{marginBottom:12},children:[n.jsx(es,{strong:!0,style:{fontSize:14},children:i("USDT 隐藏用户")}),n.jsx(es,{type:"tertiary",size:"small",style:{display:"block",marginTop:4},children:i("名单内的用户充值页不显示 USDT / 虚拟货币支付")})]}),n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:12},children:[n.jsx(k,{value:R,onChange:P,placeholder:i("输入用户名或 ID 搜索"),onEnterPress:()=>M(R),style:{flex:1},showClear:!0}),n.jsx(d,{loading:T,onClick:()=>M(R),children:i("搜索")})]}),v.length>0&&n.jsx("div",{style:{border:"1px solid var(--semi-color-border)",borderRadius:6,background:"var(--semi-color-bg-0)",maxHeight:180,overflowY:"auto",marginBottom:12},children:v.map(e=>{const t=_.some(t=>t.value===e.value);return n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"8px 12px",borderBottom:"1px solid var(--semi-color-border)"},children:[n.jsx(es,{type:t?"tertiary":void 0,children:e.label}),n.jsx(d,{size:"small",theme:t?"borderless":"light",type:t?"tertiary":"primary",disabled:t,onClick:()=>{return t=e,void(t?.value&&(S(e=>e.some(e=>e.value===t.value)?e:[...e,t]),P(""),w([])));var t},children:i(t?"已添加":"添加")})]},e.value)})}),n.jsx("div",{style:{marginBottom:8},children:n.jsxs(es,{type:"secondary",size:"small",children:[i("已添加")," (",_.length,")"]})}),n.jsx("div",{style:{minHeight:56,padding:_.length>0?"10px 12px":0,borderRadius:6,border:"1px dashed var(--semi-color-border)",background:"var(--semi-color-bg-0)",marginBottom:12},children:_.length>0?n.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:8},children:_.map(e=>n.jsx(j,{closable:!0,onClose:()=>{return t=e.value,void S(e=>e.filter(e=>e.value!==t));var t},color:"blue",size:"large",children:e.label},e.value))}):n.jsx(C,{image:C.PRESENTED_IMAGE_SIMPLE,description:i("暂无用户,请搜索后添加"),style:{padding:"12px 0"}})}),n.jsx("div",{style:{display:"flex",justifyContent:"flex-end"},children:n.jsx(d,{loading:z,onClick:async()=>{N(!0);try{const t=_.map(e=>e.value).join(","),n=await ye.put("/api/option/",{key:"BepusdtHideUserIds",value:t});n.data.success?(be(i("黑名单保存成功")),e.refresh&&e.refresh()):je(n.data.message)}catch{je(i("黑名单保存失败"))}N(!1)},type:"primary",children:i("保存名单")})})]})]}),n.jsxs(a.Section,{text:i("分站支付配置"),children:[n.jsx(h,{type:"info",description:i('为所有分站统一配置支付网关。
1选择"跟随主站"则分站使用上方的主站支付配置;选择"独立配置"则分站使用下方的专用支付配置。'),style:{marginBottom:16}}),n.jsx(h,{type:"warning",description:i("切换支付配置后,请保留旧的商户ID和密钥配置,直到所有旧订单处理完毕。系统会根据订单的商户ID自动匹配对应密钥验签,清空旧配置会导致未回调的旧订单验签失败。"),style:{marginBottom:16}}),n.jsxs(a.RadioGroup,{field:"SubSiteFollowMainPayment",label:i("分站支付模式"),onChange:e=>x(t=>({...t,SubSiteFollowMainPayment:e.target.value})),children:[n.jsx(a.Radio,{value:"true",children:i("跟随主站配置")}),n.jsx(a.Radio,{value:"false",children:i("使用独立配置")})]}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:8,display:"false"===p.SubSiteFollowMainPayment?"flex":"none"},children:[n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"SubSitePayAddress",label:i("分站支付地址"),placeholder:i("例如:https://yourdomain.com")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"SubSiteEpayId",label:i("分站易支付商户ID"),placeholder:i("例如:0001"),autoComplete:"off"})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"SubSiteEpayKey",label:i("分站易支付商户密钥"),placeholder:i("敏感信息不会发送到前端显示"),autoComplete:"off",style:b,inputStyle:b})})]})]}),n.jsxs("div",{style:{display:"flex",gap:12,marginTop:16,flexWrap:"wrap"},children:[n.jsx(d,{onClick:async()=>{if(""!==e.options.ServerAddress)if(g.TopupGroupRatio===p.TopupGroupRatio||Re(p.TopupGroupRatio))if(g.PayMethods===p.PayMethods||Re(p.PayMethods))if(g.PayChannelNames===p.PayChannelNames||!p.PayChannelNames||Re(p.PayChannelNames)){l(!0);try{const t=[{key:"PayAddress",value:fe(p.PayAddress)}];""!==p.EpayId&&t.push({key:"EpayId",value:p.EpayId}),void 0!==p.EpayKey&&""!==p.EpayKey&&t.push({key:"EpayKey",value:p.EpayKey}),""!==p.Price&&t.push({key:"Price",value:p.Price.toString()}),""!==p.MinTopUp&&t.push({key:"MinTopUp",value:p.MinTopUp.toString()}),""!==p.CustomCallbackAddress&&t.push({key:"CustomCallbackAddress",value:p.CustomCallbackAddress}),g.TopupGroupRatio!==p.TopupGroupRatio&&t.push({key:"TopupGroupRatio",value:p.TopupGroupRatio}),g.PayMethods!==p.PayMethods&&t.push({key:"PayMethods",value:p.PayMethods}),g.PayChannelNames!==p.PayChannelNames&&t.push({key:"PayChannelNames",value:p.PayChannelNames||"{}"}),t.push({key:"ForceHideBepusdt",value:p.ForceHideBepusdt?"true":"false"}),t.push({key:"SubSiteFollowMainPayment",value:p.SubSiteFollowMainPayment}),"false"===p.SubSiteFollowMainPayment&&(t.push({key:"SubSitePayAddress",value:fe(p.SubSitePayAddress)}),""!==p.SubSiteEpayId&&t.push({key:"SubSiteEpayId",value:p.SubSiteEpayId}),void 0!==p.SubSiteEpayKey&&""!==p.SubSiteEpayKey&&t.push({key:"SubSiteEpayKey",value:p.SubSiteEpayKey}));const n=t.map(e=>ye.put("/api/option/",{key:e.key,value:e.value})),s=(await Promise.all(n)).filter(e=>!e.data.success);s.length>0?s.forEach(e=>{je(e.data.message)}):(be(i("更新成功")),y({...p}),e.refresh&&e.refresh())}catch(t){je(i("更新失败"))}l(!1)}else je(i("支付渠道名称映射不是合法的 JSON 字符串"));else je(i("充值方式设置不是合法的 JSON 字符串"));else je(i("充值分组倍率不是合法的 JSON 字符串"));else je(i("请先填写服务器地址"))},children:i("更新支付设置")}),n.jsx(d,{onClick:async()=>{u(!0);try{const e=await ye.post("/api/option/admin/reload-geoip");e.data.success?be(e.data.data?.message||i("GeoIP 数据库更新成功")):je(e.data.message||i("GeoIP 数据库更新失败"))}catch{je(i("GeoIP 数据库更新失败"))}u(!1)},loading:r,theme:"light",type:"secondary",children:i("更新 GeoIP 数据库")})]})]})})}const{Text:ns}=u;function is(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({StripeApiSecret:"",StripeWebhookSecret:"",StripePriceId:"",StripeProductPrice:.01,StripeExchangeRate:1.1,StripeMinTopUp:1}),[p,x]=t.useState({}),g=t.useRef(null);return t.useEffect(()=>{if(e.options&&g.current){const t={StripeApiSecret:e.options.StripeApiSecret||"",StripeWebhookSecret:e.options.StripeWebhookSecret||"",StripePriceId:e.options.StripePriceId||"",StripeProductPrice:void 0!==e.options.StripeProductPrice?parseFloat(e.options.StripeProductPrice):.01,StripeExchangeRate:void 0!==e.options.StripeExchangeRate?parseFloat(e.options.StripeExchangeRate):1.1,StripeMinTopUp:void 0!==e.options.StripeMinTopUp?parseFloat(e.options.StripeMinTopUp):1};u(t),x({...t}),g.current.setValues(t)}},[e.options]),n.jsx(m,{spinning:s,children:n.jsx(a,{initValues:r,onValueChange:e=>{u(e)},getFormApi:e=>g.current=e,children:n.jsxs(a.Section,{text:i("Stripe 设置"),children:[n.jsxs(ns,{children:[n.jsx(ln,{i18nKey:"stripe_setup_description",components:{dashboardLink:n.jsx("a",{href:"https://dashboard.stripe.com/developers",target:"_blank",rel:"noreferrer"}),testLink:n.jsx("a",{href:"https://dashboard.stripe.com/test/developers",target:"_blank",rel:"noreferrer"})}}),n.jsx("br",{})]}),n.jsx(h,{type:"info",description:i("stripe_webhook_url_hint",{url:e.options.ServerAddress?fe(e.options.ServerAddress):i("网站地址")})}),n.jsx(h,{type:"warning",description:i("stripe_webhook_events_hint")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"StripeApiSecret",label:i("API 密钥"),placeholder:i("sk_xxx 或 rk_xxx 的 Stripe 密钥,敏感信息不显示"),type:"password"})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"StripeWebhookSecret",label:i("Webhook 签名密钥"),placeholder:i("whsec_xxx 的 Webhook 签名密钥,敏感信息不显示"),type:"password"})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"StripePriceId",label:i("商品价格 ID"),placeholder:i("price_xxx 的商品价格 ID,新建产品后可获得")})})]}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:[n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"StripeProductPrice",precision:3,label:i("Stripe商品单价(港元)"),placeholder:i("例如:0.01,即HK$0.01")})}),n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"StripeExchangeRate",precision:3,label:i("人民币转港元汇率"),placeholder:i("例如:1.10,即1元=1.10港元")})})]}),n.jsx(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:n.jsx(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"StripeMinTopUp",label:i("最低充值额度数量"),placeholder:i("例如:1,最低充值1个额度")})})}),n.jsx(d,{onClick:async()=>
1{if(""!==e.options.ServerAddress){l(!0);try{const t=[];r.StripeApiSecret&&""!==r.StripeApiSecret&&t.push({key:"StripeApiSecret",value:r.StripeApiSecret}),r.StripeWebhookSecret&&""!==r.StripeWebhookSecret&&t.push({key:"StripeWebhookSecret",value:r.StripeWebhookSecret}),""!==r.StripePriceId&&t.push({key:"StripePriceId",value:r.StripePriceId}),void 0!==r.StripeProductPrice&&null!==r.StripeProductPrice&&t.push({key:"StripeProductPrice",value:r.StripeProductPrice.toString()}),void 0!==r.StripeExchangeRate&&null!==r.StripeExchangeRate&&t.push({key:"StripeExchangeRate",value:r.StripeExchangeRate.toString()}),void 0!==r.StripeMinTopUp&&null!==r.StripeMinTopUp&&t.push({key:"StripeMinTopUp",value:r.StripeMinTopUp.toString()});const n=t.map(e=>ye.put("/api/option/",{key:e.key,value:e.value})),s=(await Promise.all(n)).filter(e=>!e.data.success);s.length>0?s.forEach(e=>{je(e.data.message)}):(be(i("更新成功")),x({...r}),e.refresh?.())}catch(t){je(i("更新失败"))}l(!1)}else je(i("请先填写服务器地址"))},children:i("更新 Stripe 设置")})]})})})}const ss=()=>{const{t:e}=ge();let[i,s]=t.useState({ServerAddress:"",PayAddress:"",EpayId:"",EpayKey:"",Price:7.3,MinTopUp:1,TopupGroupRatio:"",CustomCallbackAddress:"",PayMethods:"",StripeApiSecret:"",StripeWebhookSecret:"",StripePriceId:"",StripeProductPrice:.01,StripeExchangeRate:1.1,StripeMinTopUp:1}),[l,a]=t.useState(!1);async function o(){try{a(!0),await(async()=>{const t=await ye.get("/api/option/"),{success:n,message:i,data:l}=t.data;if(n){let e={};l.forEach(t=>{switch(t.key){case"TopupGroupRatio":try{e[t.key]=JSON.stringify(JSON.parse(t.value),null,2)}catch(n){console.error("解析TopupGroupRatio出错:",n),e[t.key]=t.value}break;case"Price":case"MinTopUp":case"StripeProductPrice":case"StripeExchangeRate":case"StripeMinTopUp":e[t.key]=parseFloat(t.value);break;case"ForceHideBepusdt":e[t.key]=an(t.value);break;
1default:t.key.endsWith("Enabled")?e[t.key]=an(t.value):e[t.key]=t.value}}),s(e)}else je(e(i))})()}catch(t){je(e("刷新失败"))}finally{a(!1)}}return t.useEffect(()=>{o()},[]),n.jsx(n.Fragment,{children:n.jsxs(m,{spinning:l,size:"large",children:[n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(Zi,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(ts,{options:i,refresh:o})}),n.jsx(r,{style:{marginTop:"10px"},children:n.jsx(is,{options:i,refresh:o})})]})})},{Text:ls}=u,as=()=>{const e=G(),t=e?.values?.agent_domain||"",s=i.useMemo(()=>{if(!t)return[];if("string"==typeof t&&t.trim()){return t.split(",").map(e=>e.trim()).filter(e=>""!==e)}return[]},[t]);return n.jsx("div",{style:{marginBottom:16},children:s.length>0?n.jsxs("div",{style:{marginBottom:12},children:[n.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:8,marginBottom:8,padding:12,backgroundColor:"#f8f9fa",borderRadius:6,border:"1px solid #e9ecef"},children:s.map((e,t)=>n.jsxs(j,{color:"blue",style:{cursor:"pointer",transition:"all 0.2s ease",padding:"4px 8px",margin:0},onClick:()=>(async e=>{const t=`https://${e}`;try{if(navigator.clipboard&&navigator.clipboard.writeText)await navigator.clipboard.writeText(t),y.success({content:`已复制: ${t}`,duration:2});else{const e=document.createElement("textarea");e.value=t,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.focus(),e.select(),document.execCommand("copy")?y.success({content:`已复制: ${t}`,duration:2}):y.error({content:"复制失败,请手动复制",duration:3}),document.body.removeChild(e)}}catch(n){console.error("复制失败:",n),y.error({content:"复制失败,请手动复制",duration:3})}})(e),title:`点击复制: https://${e}`,children:[n.jsx(gt,{style:{marginRight:4},size:12}),e,n.jsx(yt,{style:{marginLeft:4,opacity:.6},size:12})]},t))}),n.jsxs(ls,{style:{fontSize:12,color:"#6c757d"},children:["💡 共配置 ",s.length," 个服务器域名,点击域名可复制完整URL"]})]}):n.jsx("div",{style:{padding:16,backgroundColor:"#f8f9fa",borderRadius:6,textAlign:"center",border:"1px solid #e9ecef"},children:n.jsx(ls,{type:"tertiary",style:{fontSize:14},children:e?.values?"暂无配置域名":"正在加载配置..."})})})},rs={headerGradientFrom:"#53ACFF",headerGradientTo:"#0084FF"},os=({label:e,color:t,onChange:i})=>n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:12},children:[n.jsx("input",{type:"color",value:t||"#FFFFFF",onChange:e=>i(e.target.value),style:{width:36,height:36,border:"2px solid #e9ecef",borderRadius:8,padding:2,cursor:"pointer",background:"transparent"}}),n.jsx("div",{style:{flex:1},children:n.jsx(ls,{style:{fontSize:13,fontWeight:500},children:e})}),n.jsx(k,{value:t||"",onChange:e=>i(e),placeholder:"#FFFFFF",style:{width:100,fontFamily:"monospace",fontSize:12},size:"small"})]}),cs=()=>{const{t:e}=ge(),[i,s]=t.useContext(Te),[l,u]=t.useState(!1),[p,x]=t.useState({system_name:"",system_name_en:"",logo:"",url:"",home_url:"",notice:"",agent_domain:"",domain_restricted:!1,rate:"",agent_price:"",sale_price:"",invite_reward_enabled:!1,invite_reward_rate:10,checkin_enabled:!1,enable_topup_sections:!0,enable_invite_reward_section:!0,enable_topup_records_section:!0,enable_withdrawal_records_section:!0,custom_menu_links:"",header_color_config:""}),[g,y]=t.useState({...rs}),[j,f]=t.useState(p),b=t.useRef(),[_,S]=t.useState([]),[v,C]=t.useState("template"),[w,T]=t.useState(!1);function I(e){return t=>{x(n=>({...n,[e]:t}))}}const E=(e,t,n)=>{const i=[..._];i[e]={...i[e],[t]:n},S(i)};return t.useEffect(()=>{(async()=>{try{const t=await ye.get("/api/option/getagentoptions"),{success:n,message:i,data:s}=t.data;if(n){const t={};for(let e in s)Object.keys(p).includes(e)&&(t[e]=s[e]);if(x(t),f(structuredClone(t)),t.custom_menu_links)try{const e=JSON.parse(t.custom_menu_links);S(Array.isArray(e)?e:[])}catch(e){console.error("解析自定义菜单链接失败:",e),S([])}else S([]);if(t.header_color_config)try{const e=JSON.parse(t.header_color_config);y({...rs,...e})}catch(e){console.error("解析区域色块配置失败:",e),y({...rs})}else y({...rs});b.current&&b.current.setValues(t)}else je(i)}catch(t){je(t.message)}})()},[]),t.useEffect(()=>{if(!w&&p&&void 0!==p.home_url){const t=(e=p.home_url)&&""!==e?/^\d+$/.test(e)?"template":(/<[^>]+>/.test(e)||e.startsWith("https://"),"custom"):"template";C(e=>t!==e?t:e)}var e},[p?.home_url,w]),n.jsx(m,{spinning:l,children:n.jsxs(a,{values:p,getFormApi:e=>b.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:e("基础设置"),children:[n.jsxs(o,{gutter:{xs:8,sm:12,md:16,lg:24,xl:24},children:[n.jsx(c,{xs:24,sm:12,md:12,lg:6,xl:6,children:n.jsx(a.Input,{field:"system_name",label:e("系统名称"),placeholder:e("请输入系统名称,如:我的API服务"),extraText:e("将显示在网站标题和导航栏中"),onChange:I("system_name"),showClear:!0,rules:[{required:!0,message:e("系统名称不能为空")},{type:"string",min:2,max:50,message:e("系统名称长度应在2-50个字符之间")}]})}),n.jsx(c,{xs:24,sm:12,md:12,lg:6,xl:6,children:n.jsx(a.Input,{field:"system_name_en",label:e("系统名称(英文)"),placeholder:e("请输入英文系统名称,如:My API Service"),extraText:e("英文环境下显示在网站标题和导航栏中"),onChange:I("system_name_en"),showClear:!0,rules:[{type:"string",min:2,max:50,message:e("系统名称长度应在2-50个字符之间")}]})}),n.jsx(c,{xs:24,sm:12,md:12,lg:6,xl:6,children:n.jsx(a.Input,{field:"logo",label:e("LOGO"),placeholder:e("请输入logo网址,如:https://example.com/logo.png"),onChange:I("logo"),showClear:!0})}),n.jsx(c,{xs:24,sm:12,md:12,lg:6,xl:6,children:n.jsx(a.Input,{field:"url",label:e("教程文档网址"),placeholder:e("请输入教程文档网址,如:https://docs.example.com"),extraText:e("用户点击帮助按钮时将跳转到此地址"),onChange:I("url"),showClear:!0,validate:t=>t&&t.trim()&&!/^https?:\/\/.+/.test(t.trim())?e("请输入有效的网址,需以 http:// 或 https:// 开头"):""})})]}),n.jsxs("div",{style:{marginTop:24},children:[n.jsx(ls,{strong:!0,style:{fontSize:14,display:"block",marginBottom:12},children:e("右上角区域色块自定义")}),n.jsx(ls,{type:"tertiary",style:{display:"block",marginBottom:16,fontSize:13},children:e("自定义控制台标题栏的渐变色方案")}),n.jsxs(r,{title:e("标题栏渐变色"),style:{marginBottom:16},headerStyle:{padding:"12px 16px"},bodyStyle:{padding:16},children:[n.jsx(os,{label:e("控制台标题栏 - 渐变起始色"),color:g.headerGradientFrom,onChange:e=>y(t=>({...t,headerGradientFrom:e}))}),n.jsx(os,{label:e("控制台标题栏 - 渐变结束色"),color:g.headerGradientTo,onChange:e=>y(t=>({...t,headerGradientTo:e}))}),n.jsxs("div",{style:{marginTop:16},children:[n.jsx(ls,{style:{fontSize:13,fontWeight:500,marginBottom:8,display:"block"},children:e("渐变预览")}),n.jsx("div",{style:{height:48,borderRadius:8,background:`linear-gradient(to right, ${g.headerGradientFrom||"#53ACFF"}, ${g.headerGradientTo||"#0084FF"})`,display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontWeight:600,fontSize:14,letterSpacing:1},children:e("标题栏渐变效果预览")})]})]}),n.jsx(d,{type:"tertiary",size:"small",onClick:()=>y({...rs}),style:{marginBottom:8},children:e("恢复默认颜色")})]})]}),n.jsxs(a.Section,{text:e("首页设置"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{marginBottom:16},children:[n.jsx("label",{style:{display:"block",marginBottom:8,fontWeight:600,fontSize:14,color:"hsl(var(--foreground))"},children:e("首页显示模式")}
1),n.jsxs(L,{value:v,onChange:e=>{const t=e.target.value;C(t),T(!0),I("home_url")("")},direction:"vertical",style:{width:"100%"},children:[n.jsx(B,{value:"template",children:n.jsxs("div",{children:[n.jsx("div",{style:{fontWeight:500},children:e("官方模板模式")}),n.jsx("div",{style:{fontSize:12,color:"hsl(var(--muted-foreground))",marginTop:4},children:e("使用系统内置的精美模板,快速配置,开箱即用")})]})}),n.jsx(B,{value:"custom",children:n.jsxs("div",{children:[n.jsx("div",{style:{fontWeight:500},children:e("自定义模式")}),n.jsx("div",{style:{fontSize:12,color:"hsl(var(--muted-foreground))",marginTop:4},children:e("完全自定义首页内容,支持HTML/CSS,安全可靠")})]})})]})]})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:24,children:"template"===v?n.jsxs(n.Fragment,{children:[n.jsx(a.Select,{field:"home_url",label:e("选择首页模板"),style:{width:"100%"},placeholder:e("请选择首页模板"),onChange:I("home_url"),optionList:[{value:"",label:e("默认模板 - 模板1")},...Mt()]}),n.jsx(h,{type:"info",icon:n.jsx(mt,{size:16}),description:e('官方模板模式:选择模板后,home_url字段将存储模板ID(如"1","2","3"等)'),style:{marginBottom:16}})]}):n.jsxs(n.Fragment,{children:[n.jsx(a.TextArea,{field:"home_url",label:e("自定义首页内容"),placeholder:e("请输入自定义首页内容(支持HTML、CSS)..."),autosize:{minRows:10,maxRows:25},style:{fontFamily:'Monaco, Menlo, "Ubuntu Mono", monospace'},onChange:I("home_url")}),n.jsx(h,{type:"info",icon:n.jsx(mt,{size:16}),description:n.jsxs("div",{children:[n.jsx("div",{style:{marginBottom:12},children:e("基础示例代码(可复制):")}),n.jsx("div",{style:{background:"#f8f9fa",padding:"12px",borderRadius:"6px",fontFamily:'Monaco, Menlo, "Ubuntu Mono", monospace',fontSize:"12px",lineHeight:"1.4",border:"1px solid #e9ecef",whiteSpace:"pre-wrap",userSelect:"text",cursor:"text"},children:'<style>\n  .welcome {\n    text-align: center;\n    padding: 50px;\n    margin-top: 80px;\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    color: white;\n    border-radius: 12px;\n    box-shadow: 0 10px 30px rgba(0,0,0,0.2);\n  }\n</style>\n<div class="welcome">\n  <h1>欢迎使用我的API服务</h1>\n  <p>这里是自定义内容...</p>\n</div>'}),n.jsx("div",{style:{marginTop:16,marginBottom:12},children:n.jsx("strong",{children:e("多语言适配示例(纯CSS实现):")})}),n.jsx("div",{style:{background:"#f8f9fa",padding:"12px",borderRadius:"6px",fontFamily:'Monaco, Menlo, "Ubuntu Mono", monospace',fontSize:"12px",lineHeight:"1.4",border:"1px solid #e9ecef",whiteSpace:"pre-wrap",userSelect:"text",cursor:"text"},children:'<style>\n  /* 默认隐藏所有语言 */\n  .lang { display: none; }\n  \n  /* 根据 data-lang-main 属性显示对应语言 */\n  [data-lang-main="zh"] .lang-zh,\n  [data-lang-main="en"] .lang-en,\n  [data-lang-main="ru"] .lang-ru,\n  [data-lang-main="ko"] .lang-ko,\n  [data-lang-main="ja"] .lang-ja,\n  [data-lang-main="es"] .lang-es,\n  [data-lang-main="de"] .lang-de {\n    display: block;\n  }\n  \n  .welcome {\n    text-align: center;\n    padding: 50px;\n    margin-top: 80px;\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    color: white;\n    border-radius: 12px;\n  }\n</style>\n\n<div class="welcome">\n  \x3c!-- 中文内容 --\x3e\n  <div class="lang lang-zh">\n    <h1>欢迎使用我的API服务</h1>\n    <p>这是自定义的多语言内容</p>\n  </div>\n  \n  \x3c!-- 英文内容 --\x3e\n  <div class="lang lang-en">\n    <h1>Welcome to My API Service</h1>\n    <p>This is custom multilingual content</p>\n  </div>\n  \n  \x3c!-- 日文内容 --\x3e\n  <div class="lang lang-ja">\n    <h1>APIサービスへようこそ</h1>\n    <p>これはカスタム多言語コンテンツです</p>\n  </div>\n  \n  \x3c!-- 韩文内容 --\x3e\n  <div class="lang lang-ko">\n    <h1>API 서비스에 오신 것을 환영합니다</h1>\n    <p>사용자 정의 다국어 콘텐츠입니다</p>\n  </div>\n</div>'}),n.jsxs("div",{style:{marginTop:12,fontSize:"12px",color:"#6c757d"},children:[n.jsx("div",{children:n.jsx("strong",{children:e("支持的语言代码:")})}),n.jsx("div",{children:"zh (中文) | en (English) | ru (Русский) | ko (한국어) | ja (日本語) | es (Español) | de (Deutsch)"})]})]}),style:{marginBottom:12}}),n.jsx(h,{type:"warning",icon:n.jsx(mt,{size:16}),description:n.jsxs("div",{children:[n.jsx("div",{children:e("自定义模式注意事项:")}),n.jsxs("ul",{style:{margin:"8px 0",paddingLeft:"20px"},children:[n.jsx("li",{children:e("home_url字段将存储完整的HTML/CSS代码")}),n.jsx("li",{children:e("支持完整的HTML、CSS代码")}),n.jsx("li",{children:e("不支持JavaScript代码,所有script标签和事件属性将被自动移除")}),n.jsx("li",{children:e("可以使用内联CSS(<style>标签)和外部CSS链接(<link>标签)")}),n.jsxs("li",{children:[n.jsx("strong",{children:e("支持多语言适配")}),e(":系统会自动添加 data-lang 和 data-lang-main 属性,可通过纯CSS实现多语言切换")]}),n.jsx("li",{children:e("建议测试代码兼容性,确保在不同设备上正常显示")})]})]}),style:{marginBottom:16}})]})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:24,children:n.jsx(a.TextArea,{field:"notice",label:e("系统公告"),placeholder:e("请输入系统公告,支持HTML格式..."),extraText:e("支持HTML标签ï¼
1Œå°†æ˜¾ç¤ºåœ¨é¦–页顶部公告栏"),autosize:{minRows:3,maxRows:6},onChange:I("notice"),validate:t=>t&&t.length>1e5?e("系统公告内容不能超过1000个字符"):""})})})]}),n.jsxs(a.Section,{text:e("服务器设置"),children:[n.jsx(a.Input,{field:"agent_domain",allowEmptyString:!0,style:{display:"none"}}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:24,children:n.jsxs(a.Slot,{label:{text:e("服务器地址")},children:[n.jsx(as,{}),n.jsx(ls,{style:{fontSize:12,color:"#6c757d",marginTop:4},children:e("用户可通过这些域名访问API服务(只读显示)")})]})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"domain_restricted",label:e("限制域名访问"),extraText:e("启用后,只有代理旗下的用户才能通过此域名访问API服务"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:I("domain_restricted")})})})]}),n.jsx(a.Section,{text:e("充值页面显示设置"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"enable_topup_sections",label:e("显示充值分区"),extraText:e('控制充值页面的"充值类型"、"选择充值金额"、"充值数量"、"选择支付方式"等充值相关分区的显示'),size:"default",checkedText:"|",uncheckedText:"〇",onChange:I("enable_topup_sections")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"enable_invite_reward_section",label:e("显示邀请奖励模块"),extraText:e('控制充值页面的"邀请奖励"模块显示,包括邀请链接、邀请码、邀请奖励余额等信息'),size:"default",checkedText:"|",uncheckedText:"〇",onChange:I("enable_invite_reward_section")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"enable_topup_records_section",label:e("显示充值记录"),extraText:e('控制充值页面的"充值记录"标签页显示,用户可查看历史充值订单'),size:"default",checkedText:"|",uncheckedText:"〇",onChange:I("enable_topup_records_section")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"enable_withdrawal_records_section",label:e("显示提现记录"),extraText:e('控制充值页面的"提现记录"标签页显示,用户可查看提现申请和处理状态'),size:"default",checkedText:"|",uncheckedText:"〇",onChange:I("enable_withdrawal_records_section")})})]})}),n.jsx(a.Section,{text:e("签到功能设置"),children:n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"checkin_enabled",label:e("启用旗下用户签到"),extraText:e("启用后,旗下用户每日可签到领取余额;签到金额范围由主站统一配置"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:I("checkin_enabled")})})})}),n.jsx(a.Section,{text:e("邀请奖励功能设置"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"invite_reward_enabled",label:e("启用邀请奖励功能"),extraText:e("启用后,用户通过邀请链接注册的新用户产生消费时,邀请人可获得相应比例的奖励金额"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:I("invite_reward_enabled")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"invite_reward_rate",label:e("邀请奖励比例"),initValue:10,placeholder:e("请输入邀请奖励比例"),extraText:e("设置邀请人可获得被邀请人消费金额的奖励百分比,范围1%-10%"),suffix:"%",min:1,max:10,precision:1,step:.5,style:{width:"100%"},onChange:I("invite_reward_rate"),validate:t=>{if(t<1||t>10)return e("奖励比例必须在1-10之间")}})})]})}),n.jsxs(a.Section,{text:e("自定义菜单链接"),children:[n.jsx(ls,{type:"tertiary",style:{display:"block",marginBottom:16},children:e("添加自定义菜单链接,将在顶部导航栏和侧边栏中显示,点击后跳转到指定地址")}),_.map((t,i)=>n.jsx(r,{style:{marginBottom:16},title:`${e("链接")} ${i+1}`,headerExtraContent:n.jsx(d,{type:"danger",theme:"borderless",icon:n.jsx(He,{size:16}),onClick:()=>(e=>{const t=[..._];t.splice(e,1),S(t)})(i),children:e("删除")}),children:n.jsxs(o,{gutter:16,children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx(ls,{strong:!0,children:e("名称")}),n.jsx(ls,{type:"tertiary",style:{marginLeft:8},children:e("显示在菜单中的名称")})]}),n.jsx(k,{value:t.name,onChange:e=>E(i,"name",e),placeholder:e("例如:帮助中心"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx(ls,{strong:!0,children:e("链接地址")}),n.jsx(ls,{type:"tertiary",style:{marginLeft:8},children:e("点击后跳转的URL")})]}),n.jsx(k,{value:t.url,onChange:e=>E(i,"url",e),placeholder:e("例如:https://help.example.com"),style:{width:"100%"}})]})]})},i)),n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>{S([..._,{name:"",url:""}])},style:{marginBottom:16},children:e("添加链接")})]}),n.jsx(o,{children:n.jsx(c,{children:n.jsx(d,{type:"primary",size:"default",onClick:function(){for(let n=0;n<_.length;n++){const t=_[n];if(!t.name||""===t.name.trim())return void je(e("自定义菜单链接")+` ${n+1}: `+e("名称不能为空"));if(!t.url||""===t.url.trim())return void je(e("自定义菜单链接")+` ${n+1}: `+e("链接地址不能为空"))}u(!0);try{const t={...p};""!==p.sale_price&&void 0!==p.sale_price&&null!==p.sale_price?t.sale_price=parseFloat(p.sale_price):delete t.sale_price,""!==p.invite_reward_rate&&void 0!==p.invite_reward_rate&&null!==p.invite_reward_rate?t.invite_reward_rate=parseFloat(p.invite_reward_rate):delete t.invite_reward_rate,t.custom_menu_links=JSON.stringify(_),t.header_color_config=JSON.stringify(g),ye.post("/api/option/updateagentoption",t).then(async n=>{const{success:i,message:l}=n.data;if(i){be(e("保存成功")),f(structuredClone(t)),x(t);try{const e=await ye.get("/api/status");e?.data?.success&&s({type:"set",payload:e.data.data})}catch(a){}}else je(l||e("保存失败"))}).catch(t=>{je(t.message||e("保存失败,请重试"))}).finally(()=>{u(!1)})}catch(t){je(t.message||e("提交时发生错误")),u(!1)}},children:e("保存基础设置")})})})]})})},{Text:ds}=u,us=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({seo_title:"",keywords:"",description:"",statistics_code:"",baidu_ocpc_token:"",footer:"",seo_page_configs:""}),[u,p]=t.useState(l),g=t.useRef(),[y,f]=t.useState([]),[b,_]=t.useState(!1),[S,k]=t.useState({path:"",title:"",description:"",keywords:""}),[C,w]=t.useState(-1);function T(e){return t=>{r(n=>({...n,[e]:t}))}}const I=(e,t)=>{k({...S,[e]:t})};t.useEffect(()=>{(async()=>{try{const t=await ye.get("/api/option/getagentoptions"),{success:n,message:i,data:s}=t.data;if(n){const t={};for(let e in s)Object.keys(l).includes(e)&&(t[e]=s[e]);r(t),p(structuredClone(t));try{if(s.seo_page_configs){const e=JSON.parse(s.seo_page_configs||"[]");f(e)}}catch(e){f([])}g.current&&g.current.setValues(t)}else je(i)}catch(t){je(t.message)}})()},[]);const E=[{title:e("页面路径"),dataIndex:"path",render:t=>t.endsWith("*")?n.jsxs(n.Fragment,{children:[t," ",n.jsx(j,{color:"blue",children:e("前缀匹配")})]}):t},{title:e("标题"),dataIndex:"title",width:200},{title:e("描述"),dataIndex:"description",width:300,ellipsis:!0},{title:e("关键词"),dataIndex:"keywords",width:200,ellipsis:!0},{title:e("操作"),width:120,render:(t,i,s)=>n.jsxs(n.Fragment,{children:[n.jsx(d,{theme:"light",type:"primary",style:{marginRight:8},onClick:()=>((e,t)=>{k(e),w(t),_(!0)})(i,s),children:e("编辑")}),n.jsx(d,{theme:"light",type:"danger",onClick:()=>(e=>{const t=[...y];t.splice(e,1),f(t)})(s),children:e("删除")})]})}];return n.jsxs(n.Fragment,{children:[n.jsx(m,{spinning:i,children:n.jsxs(a,{values:l,getFormApi:e=>g.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:e("SEO设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"seo_title",label:e("SEO标题"),placeholder:e("请输入网站SEO标题"),onChange:T("seo_title"),showClear:!0})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"footer",label:e("页脚设置"),placeholder:e("请输入页脚设置"),onChange:T("footer"),showClear:!0})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:12,lg:12,xl:12,children:n.jsx(a.TextArea,{field:"
1keywords",label:e("网站关键词"),placeholder:e("请输入网站关键词,多个关键词用逗号分隔"),autosize:{minRows:3,maxRows:6},onChange:T("keywords")})}),n.jsx(c,{xs:24,sm:12,md:12,lg:12,xl:12,children:n.jsx(a.TextArea,{field:"description",label:e("网站描述"),placeholder:e("请输入网站描述"),autosize:{minRows:3,maxRows:6},onChange:T("description")})})]}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:24,children:n.jsx(a.Input,{field:"baidu_ocpc_token",label:e("百度 OCPC Token"),placeholder:e("请输入百度 OCPC Token(例如:_f7L2XwGXjyszb4d1e2oxPybgD)"),onChange:T("baidu_ocpc_token"),showClear:!0})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:24,children:n.jsx(a.TextArea,{field:"statistics_code",label:e("统计代码"),placeholder:e("请输入网站统计代码,如Google Analytics、百度统计等"),autosize:{minRows:3,maxRows:6},onChange:T("statistics_code")})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{marginTop:16},children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16},children:[n.jsx(ds,{strong:!0,children:e("页面SEO设置")}),n.jsx(d,{icon:n.jsx(Ye,{size:16}),type:"primary",onClick:()=>{k({path:"",title:"",description:"",keywords:""}),w(-1),_(!0)},children:e("添加页面")})]}),n.jsx(v,{columns:E,dataSource:y,pagination:!1,size:"small",empty:e("暂无页面SEO配置")})]})})}),n.jsx(h,{type:"info",icon:n.jsx(mt,{size:16}),description:n.jsxs("div",{children:[n.jsx("div",{style:{marginBottom:8},children:e("SEO优化建议:")}),n.jsxs("ul",{style:{margin:0,paddingLeft:"20px"},children:[n.jsx("li",{children:e("SEO标题应简洁明了,包含核心关键词")}),n.jsx("li",{children:e("网站描述应控制在150字符以内")}),n.jsx("li",{children:e("关键词不宜过多,3-5个为佳")}),n.jsx("li",{children:e("可为不同页面设置专门的SEO信息")})]})]}),style:{marginTop:16,marginBottom:16}})]}),n.jsx(o,{children:n.jsx(c,{children:n.jsx(d,{type:"primary",size:"default",onClick:function(){s(!0);try{const t={...l,seo_page_configs:JSON.stringify(y)};t.baidu_ocpc_token||delete t.baidu_ocpc_token,ye.post("/api/option/updateagentoption",t).then(n=>{const{success:i,message:s}=n.data;i?(be(e("保存成功")),p(structuredClone(t))):je(s||e("保存失败"))}).catch(t=>{je(t.message||e("保存失败,请重试"))}).finally(()=>{s(!1)})}catch(t){je(t.message||e("提交时发生错误")),s(!1)}},children:e("保存SEO设置")})})})]})}),n.jsx(x,{title:e(C>=0?"编辑页面SEO":"添加页面SEO"),visible:b,onOk:()=>{if(S.path){if(C>=0){const e=[...y];e[C]=S,f(e)}else{if(y.some(e=>e.path===S.path))return void je(e("该页面路径已存在"));f([...y,S])}_(!1)}else je(e("页面路径不能为空"))},onCancel:()=>_(!1),closeOnEsc:!0,width:600,children:b&&n.jsxs(a,{initValues:S,children:[n.jsx(a.Input,{field:"path",label:e("页面路径"),placeholder:e("例如: /chat 或 /chat/* (通配符匹配所有chat子页面)"),onChange:e=>I("path",e),help:e("以/开头的路径。使用*作为通配符可以匹配以相同前缀开头的所有页面"),required:!0}),n.jsx(a.Input,{field:"title",label:e("页面标题"),placeholder:e("页面标题"),onChange:e=>I("title",e),help:e("不需要包含系统名称,系统会自动添加")}),n.jsx(a.TextArea,{field:"description",label:e("页面描述"),placeholder:e("页面描述"),onChange:e=>I("description",e),rows:3}
1),n.jsx(a.TextArea,{field:"keywords",label:e("页面关键词"),placeholder:e("页面关键词,多个关键词用英文逗号分隔"),onChange:e=>I("keywords",e),rows:3})]})})]})},ps=["email","phone","qrcode","link"];function hs(e){if(!e||"string"!=typeof e)return[];try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function xs(e){const t=hs(e).map(e=>{if(!e||"object"!=typeof e)return e;const t=e.category,n={...e.payload&&"object"==typeof e.payload?e.payload:{}};return"email"===t&&null!=n.address&&(n.address=String(n.address).trim()),"phone"===t&&null!=n.number&&(n.number=String(n.number).trim()),"qrcode"===t&&(null!=n.image_url&&(n.image_url=String(n.image_url).trim()),null!=n.subtitle&&(n.subtitle=String(n.subtitle).trim())),"link"===t&&null!=n.url&&(n.url=String(n.url).trim()),{...e,payload:n}});return JSON.stringify(t)}function ms(e){const t=e.payload||{};switch(e.category){case"email":return t.address||"";case"phone":return t.number||"";case"qrcode":return t.image_url||"";case"link":return t.url||"";default:return JSON.stringify(t||{})}}function gs(e,t){const n=null==t?"":String(t),i={...e.payload||{}};switch(e.category){case"email":i.address=n;break;case"phone":i.number=n;break;case"qrcode":i.image_url=n;break;case"link":i.url=n}return{...e,payload:i}}function ys(e){const t=String(e??"").trim();return""===t?"":/^https?:\/\//i.test(t)?t:`https://${t}`}function js(e){const t=e.payload||{};switch(e.category){case"email":return t.address||"";case"phone":return t.number||"";case"qrcode":return t.image_url||"";case"link":return t.url||"";default:return""}}t.forwardRef(function({value:e,onChange:i,colProps:s,translationEnabled:l=!1},a){const{t:r}=ge(),[o,p]=t.useState([]),[h,m]=t.useState(-1);t.useEffect(()=>{p(hs(e))},[e]);const y=t.useCallback(e=>{p(e),i(JSON.stringify(e))},[i]),[j,f]=t.useState(!1),[b,_]=t.useState("email"),[S,v]=t.useState(""),[C,w]=t.useState(""),[T,I]=t.useState(""),[E,R]=t.useState(""),[P,z]=t.useState(""),[A,M]=t.useState(""),O=t.useCallback(()=>{_("email"),v(""),w(""),I(""),R(""),z(""),M(""),f(!0)},[]);t.useImperativeHandle(a,()=>({openAdd:O}),[O]);const D=t.useCallback(e=>({email:r("自定义联系分类_email"),phone:r("自定义联系分类_phone"),qrcode:r("自定义联系分类_qrcode"),link:r("自定义联系分类_link")}[e]||e),[r]),L=t.useMemo(()=>ps.map(e=>({value:e,label:D(e)})),[D]),B=s||{span:12};return n.jsxs(n.Fragment,{children:[o.map((e,t)=>{const i=Ot(e),s=Dt(e);return n.jsx(c,{...B,children:n.jsxs("div",{className:"semi-form-field semi-form-field-vertical",children:[n.jsxs("div",{className:"semi-form-field-label",style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:8,width:"100%"},children:[n.jsxs("span",{children:[n.jsx("span",{children:e.title}),n.jsxs(u.Text,{type:"tertiary",size:"small",style:{marginLeft:4},children:["(",D(e.category),")"]})]}),n.jsxs(g,{spacing:4,children:[l&&n.jsxs(n.Fragment,{children:[n.jsx(hn,{item:i,fields:s,onClick:()=>m(t)}),n.jsx(d,{theme:"borderless",type:"tertiary",size:"small",icon:n.jsx(Ge,{size:14}),"aria-label":r("查看 / 编辑译文"),onMouseDown:e=>e.preventDefault(),onClick:e=>{e?.stopPropagation?.(),m(t)}})]}),n.jsx(d,{theme:"borderless",type:"tertiary",size:"small",icon:n.jsx(lt,{size:16}),"aria-label":r("删除该联系条目"),onMouseDown:e=>e.preventDefault(),onClick:e=>{e?.stopPropagation?.(),function(e){const t=o.filter((t,n)=>n!==e);y(t)}(t)}})]})]}),n.jsx(k,{value:ms(e),onChange:e=>function(e,t){const n=[...o];n[e]=gs(n[e],t),y(n)}(t,e),onBlur:e=>function(e,t){const n=o[e];if(!n||"qrcode"!==n.category)return;const i=ys(t);if(i===String(t??"").trim())return;const s=[...o];s[e]=gs(s[e],i),y(s)}(t,e?.target?.value),showClear:!0})]})},e.id||t)}),n.jsx(x,{title:r("添加自定义联系条目"),visible:j,onOk:function(){const e=S.trim();if(!e)return void x.error({title:r("提示"),content:r("请输入展示标题")});const t=b,n=function(e){switch(e){case"email":return{address:C.trim()};case"phone":return{number:T.trim()};case"qrcode":{const e={image_url:ys(E)};return P.trim()&&(e.subtitle=P.trim()),e}case"link":return{url:ys(A)};default:return{}}}(t),i={id:"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():`ce-${Date.now()}-${Math.random().toString(36).slice(2,11)}`,category:t,title:e,payload:n};y([...o,i]),f(!1)},onCancel:()=>f(!1),width:520,children:n.jsxs(g,{vertical:!0,align:"start",style:{width:"100%"},spacing:"loose",children:[n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:r("联系条目分类")}),n.jsx(N,{style:{width:"100%"},optionList:L,value:b,onChange:e=>_(e)})]}),n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:r("展示标题")}),n.jsx(k,{value:S,onChange:v,placeholder:r("请输入展示标题")})]}),"email"===b&&n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:r("邮箱地址")}),n.jsx(k,{value:C,onChange:w,placeholder:r("请输入邮箱地址")})]}),"phone"===b&&n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:r("电话号码")}),n.jsx(k,{value:T,onChange:I,placeholder:r("请输入电话号码")})]}),"qrcode"===b&&n.jsxs(n.Fragment,{children:[n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:r("图片URL")}),n.jsx(k,{value:E,onChange:R,placeholder:r("请输入二维码图片URL")})]}),n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:r("副文案")}),n.jsx(k,{value:P,onChange:z,placeholder:r("可选副文案")})]})]}),"link"===b&&n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:r("链接地址")}),n.jsx(k,{value:A,onChange:M,placeholder:r("请输入链接地址,如 https://example.com")})]})]})}),(()=>{const e=h,t=e>=0?o[e]:null;if(!t)return null;const i=Ot(t),s=Lt(t).map(e=>({...e,label:r(e.label)}));return n.jsx(xn,{visible:e>=0,onClose:()=>m(-1),item:i,fields:s,translationEnabled:l,onApply:t=>{const n=o.slice();n[e]=Bt(o[e],t),y(n)}})})()]})});const fs=({id:e,label:t,placeholder:i,value:s,onValueChange:l,onRemove:a,translationTag:r,translationButton:o})=>
1{const{attributes:c,listeners:u,setNodeRef:p,transform:h,transition:x,isDragging:m}=ie({id:e}),y={transform:se.Transform.toString(h),transition:x,opacity:m?.5:1,zIndex:m?1e3:"auto"};return n.jsx("div",{ref:p,style:y,children:n.jsxs("div",{className:"semi-form-field semi-form-field-vertical",style:{marginBottom:12},children:[n.jsxs("div",{className:"semi-form-field-label",style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:8,width:"100%"},children:[n.jsx("div",{...c,...u,style:{cursor:"grab",touchAction:"none",flexShrink:0},children:n.jsx(jt,{size:14,style:{color:"var(--semi-color-text-2)"}})}),n.jsx("span",{style:{flex:1,fontWeight:500,fontSize:14,color:"var(--semi-color-text-0)"},children:t}),n.jsxs(g,{spacing:4,children:[r,o,n.jsx(d,{theme:"borderless",type:"tertiary",size:"small",icon:n.jsx(lt,{size:16}),onMouseDown:e=>e.preventDefault(),onClick:e=>{e?.stopPropagation?.(),a()}})]})]}),n.jsx(k,{value:s,onChange:e=>l(e),placeholder:i,showClear:!0})]})})},bs=({order:e,builtinValues:i,customEntries:s,onOrderChange:l,onBuiltinChange:a,onCustomEntriesChange:r,translationEnabled:o})=>{const{t:c}=ge(),p=function(){const{t:e}=ge();return t=>({[Ft.EMAIL]:e("客服邮箱"),[Ft.PHONE]:e("客服电话"),[Ft.ONLINE_TIME]:e("客服在线时间"),[Ft.WEIXIN]:e("企业微信客服链接"),[Ft.WHATSAPP]:e("WhatsApp 二维码图片地址"),[Ft.QRCODE]:e("二维码URL")}[t]||t)}(),h=function(){const{t:e}=ge();return t=>({[Ft.EMAIL]:e("请输入客服邮箱"),[Ft.PHONE]:e("请输入客服电话"),[Ft.ONLINE_TIME]:e("请输入客服在线时间"),[Ft.WEIXIN]:e("请输入企业微信客服链接"),[Ft.WHATSAPP]:e("请输入二维码图片链接"),[Ft.QRCODE]:e("请输入二维码URL")}[t]||"")}(),x=function(){const{t:e}=ge();return t=>({email:e("自定义联系分类_email"),phone:e("自定义联系分类_phone"),qrcode:e("自定义联系分类_qrcode"),link:e("自定义联系分类_link")}[t]||t)}(),[m,g]=t.useState(null),y=q($(X),$(Q,{coordinateGetter:H}));function j(t){const n=e.filter(e=>e!==t);if(l(n),t.startsWith("builtin:"))a(t,"");else{const e=s.filter(e=>e.id!==t);r(e)}}const f=t.useMemo(()=>m?s.find(e=>e.id===m):null,[m,s]);return n.jsxs(n.Fragment,{children:[n.jsx(Y,{sensors:y,collisionDetection:Z,onDragEnd:function(t){const{active:n,over:i}=t;if(!i||n.id===i.id)return;const s=e.indexOf(n.id),a=e.indexOf(i.id);l(ne(e,s,a))},children:n.jsx(ee,{items:e,strategy:te,children:e.map(e=>{if(e.startsWith("builtin:"))return n.jsx(fs,{id:e,label:p(e),placeholder:h(e),value:i[e]||"",onValueChange:t=>function(e,t){a(e,t)}(e,t),onRemove:()=>j(e)},e);const t=s.find(t=>t.id===e);if(!t)return null;const l=Ot(t),m=Dt(t);return n.jsx(fs,{id:e,label:n.jsxs("span",{children:[t.title,n.jsxs(u.Text,{type:"tertiary",size:"small",style:{marginLeft:4},children:["(",x(t.category),")"]})]}),placeholder:"",value:js(t),onValueChange:t=>function(e,t){const n=s.map(n=>n.id===e?function(e,t){const n=null==t?"":String(t),i={...e.payload||{}};switch(e.category){case"email":i.address=n;break;case"phone":i.number=n;break;case"qrcode":i.image_url=n;break;case"link":i.url=n}return{...e,payload:i}}(n,t):n);r(n)}(e,t),onRemove:()=>j(e),translationTag:o?n.jsx(hn,{item:l,fields:m,onClick:()=>g(e)}):null,translationButton:o?n.jsx(d,{theme:"borderless",type:"tertiary",size:"small",icon:n.jsx(Ge,{size:14}),"aria-label":c("查看 / 编辑译文"),onMouseDown:e=>e.preventDefault(),onClick:t=>
1{t?.stopPropagation?.(),g(e)}}):null},e)})})}),f&&(()=>{const e=Ot(f),t=Lt(f).map(e=>({...e,label:c(e.label)}));return n.jsx(xn,{visible:!!m,onClose:()=>g(null),item:e,fields:t,translationEnabled:o,onApply:e=>{const t=s.map(t=>t.id===m?Bt(t,e):t);r(t)}})})()]})},_s={[Ft.EMAIL]:"agent_email",[Ft.PHONE]:"phone",[Ft.ONLINE_TIME]:"work_time",[Ft.WEIXIN]:"customer_support_weixin_link",[Ft.QRCODE]:"qrcode_url"},Ss=[Ft.EMAIL,Ft.PHONE,Ft.ONLINE_TIME,Ft.WEIXIN,Ft.QRCODE],ks=["agent_email","phone","work_time","qrcode_url","customer_support_weixin_link","customer_support_custom_entries","customer_support_contact_order"],vs={agent_email:"",phone:"",work_time:"",qrcode_url:"",customer_support_weixin_link:"",customer_support_custom_entries:"[]",customer_support_contact_order:""};function Cs(e){const t={};for(const[n,i]of Object.entries(_s))t[n]=e[i]||"";return t}function ws(e,t){const n=Wt(e.customer_support_contact_order),i=Object.keys(_s),s=t.map(e=>e.id);return Jt(n||Ss,i,s)}function Ts(e){if(!e)return!0;try{const t=new URL(e);return"http:"===t.protocol||"https:"===t.protocol}catch{return!1}}const Is=["email","phone","qrcode","link"],Es=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,a]=t.useState(vs),[r,o]=t.useState(vs),[c,p]=t.useState(!1),[h,y]=t.useState(!1),[j,f]=t.useState("email"),[b,_]=t.useState(""),[S,k]=t.useState(""),[v,C]=t.useState(""),[w,T]=t.useState(""),[I,E]=t.useState(""),[R,P]=t.useState(""),z=hs(l.customer_support_custom_entries),N=ws(l,z);function A(e){a(t=>({...t,customer_support_contact_order:JSON.stringify(e)}))}function M(e){a(t=>({...t,customer_support_custom_entries:JSON.stringify(e)}))}t.useEffect(()=>{(async()=>{try{const e=await ye.get("/api/option/getagentoptions"),{success:t,message:n,data:i}=e.data;if(t){const e={...vs};for(const t of ks)void 0!==i[t]&&null!==i[t]&&(e[t]="string"==typeof i[t]?i[t]:JSON.stringify(i[t]));e.customer_support_custom_entries||(e.customer_support_custom_entries="[]"),a(e),o(structuredClone(e)),p(an(i.translation_enabled))}else je(n)}catch(e){je(e.message)}})()},[]);const O=t=>({email:e("自定义联系分类_email"),phone:e("自定义联系分类_phone"),qrcode:e("自定义联系分类_qrcode"),link:e("自定义联系分类_link")}[t]||t);return n.jsxs(m,{spinning:i,children:[n.jsxs(g,{align:"center",style:{marginBottom:12},children:[n.jsx(u.Title,{heading:6,style:{margin:0},children:e("联系方式设置")}),n.jsx(d,{icon:n.jsx(Ye,{size:16}),type:"tertiary",size:"small",onClick:()=>{f("email"),_(""),k(""),C(""),T(""),E(""),P(""),y(!0)},children:e("添加自定义联系条目")})]}),n.jsx(bs,{order:N,builtinValues:Cs(l),customEntries:z,onOrderChange:function(e){A(e)},onBuiltinChange:function(e,t){const n=_s[e];n&&a(e=>({...e,[n]:t}))},onCustomEntriesChange:function(e){M(e);const t=new Set(e.map(e=>e.id));A(ws(l,z).filter(e=>e.startsWith("builtin:")||t.has(e)))},translationEnabled:c}),c&&n.jsx("div",{style:{marginTop:8},children:n.jsx(u.Text,{type:"warning",size:"small",children:e("已开启自动翻译:保存设置时由后端并发翻译为 6 种语言(耗时取决于条目数与模型,通常 30 秒~2 分钟)")})}),n.jsx("div",{style:{marginTop:16},children:n.jsx(d,{type:"primary",size:"default",onClick:async function(){const t=z.find(e=>"link"===e.category&&!Ts(e.payload?.url||""));if(t)x.error({title:e("提示"),content:e("请输入有效的URL地址")+`(${t.title})`});else{s(!0);try{const t={...l,customer_support_custom_entries:xs(l.customer_support_custom_entries),customer_support_contact_order:l.customer_support_contact_order||JSON.stringify(N)},n=await ye.post("/api/option/updateagentoption",t),{success:i,message:s}=n.data;i?(be(e("保存成功")),a(structuredClone(t)),o(structuredClone(t))):je(s||e("保存失败"))}catch(n){je(n?.message||e("保存失败,请重试"))}finally{s(!1)}}},children:e("保存联系方式设置")})}),n.jsx(x,{title:e("添加自定义联系条目"),visible:h,onOk:function(){const t=b.trim();if(!t)return void x.error({title:e("提示"),content:e("请输入展示标题")});let n={};if("email"===j)n={address:S.trim()};else if("phone"===j)n={number:v.trim()};else if("qrcode"===j)n={image_url:w.trim()},I.trim()&&(n.subtitle=I.trim());else if("link"===j){const t=R.trim();if(!Ts(t))return void x.error({title:e("提示"),content:e("请输入有效的URL地址")});n={url:t}}const i={id:"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():`ce-${Date.now()}-${Math.random().toString(36).slice(2,11)}`,category:j,title:t,payload:n};M([...z,i]);const s=ws(l,z);A(Ut(s,i.id)),y(!1),_(""),k(""),C(""),T(""),E(""),P("")},onCancel:()=>y(!1),width:520,children:n.jsxs(g,{vertical:!0,align:"start",style:{width:"100%"},spacing:"loose",children:[n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:e("联系条目分类")}),n.jsx("select",{value:j,onChange:e=>f(e.target.value),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)"},children:Is.map(e=>n.jsx("option",{value:e,children:O(e)},e))})]}),n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:e("展示标题")}),n.jsx("input",{value:b,onChange:e=>_(e.target.value),placeholder:e("请输入展示标题"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]}),"email"===j&&n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:e("邮箱地址")}),n.jsx("input",{value:S,onChange:e=>k(e.target.value),placeholder:e("请输入邮箱地址"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]}),"phone"===j&&n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:e("电话号码")}
1),n.jsx("input",{value:v,onChange:e=>C(e.target.value),placeholder:e("请输入电话号码"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]}),"qrcode"===j&&n.jsxs(n.Fragment,{children:[n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:e("图片URL")}),n.jsx("input",{value:w,onChange:e=>T(e.target.value),placeholder:e("请输入二维码图片URL"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]}),n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:e("副文案")}),n.jsx("input",{value:I,onChange:e=>E(e.target.value),placeholder:e("可选副文案"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]})]}),"link"===j&&n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:e("链接地址")}),n.jsx("input",{value:R,onChange:e=>P(e.target.value),placeholder:e("请输入链接地址,如 https://example.com"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]})]})})]})},Rs=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({smtp_server:"",smtp_port:"",smtp_account:"",smtp_from:"",smtp_token:""}),[u,p]=t.useState(l),h=t.useRef();function x(e){return t=>{r(n=>({...n,[e]:t}))}}return t.useEffect(()=>{(async()=>{try{const e=await ye.get("/api/option/getagentoptions"),{success:t,message:n,data:i}=e.data;if(t){const e={};for(let t in i)Object.keys(l).includes(t)&&(e[t]=i[t]);r(e),p(structuredClone(e)),h.current&&h.current.setValues(e)}else je(n)}catch(e){je(e.message)}})()},[]),n.jsx(m,{spinning:i,children:n.jsxs(a,{values:l,getFormApi:e=>h.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:e("SMTP邮件设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"smtp_server",label:e("SMTP 服务器地址"),placeholder:e("请输入SMTP 服务器地址,如:smtp.gmail.com"),onChange:x("smtp_server"),showClear:!0,rules:[{required:!0,message:e("SMTP 服务器地址不能为空")}]})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"smtp_port",label:e("SMTP 端口"),placeholder:e("请输入SMTP 端口,如:587"),onChange:x("smtp_port"),min:1,max:65535,style:{width:"100%"},rules:[{required:!0,message:e("SMTP 端口不能为空")},{type:"number",min:1,max:65535,message:e("端口范围为1-65535")}]})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"smtp_account",label:e("SMTP 账户"),autoComplete:"off",placeholder:e("请输入SMTP 账户,通常是邮箱地址"),onChange:x("smtp_account"),showClear:!0,rules:[{required:!0,message:e("SMTP 账户不能为空")}]})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"smtp_from",label:e("SMTP 发送者邮箱"),placeholder:e("请输入发送者邮箱地址"),onChange:x("smtp_from"),showClear:!0,validate:t=>t&&t.trim()&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t.trim())?e("请输入有效的邮箱地址"):"",rules:[{required:!0,message:e("发送者邮箱不能为空")}]})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"smtp_token",label:e("SMTP 访问凭证"),autoComplete:"new-password",type:"password",placeholder:e("请输入SMTP 访问凭证或密码"),onChange:x("smtp_token"),showClear:!0,rules:[{required:!0,message:e("SMTP 访问凭证不能为空")}]})})]})]}),n.jsx(o,{children:n.jsx(c,{children:n.jsx(d,{type:"primary",size:"default",onClick:function(){s(!0);try{const t={...l,smtp_port:""!==l.smtp_port?parseInt(l.smtp_port):""};ye.post("/api/option/updateagentoption",t).then(t=>{const{success:n,message:i}=t.data;n?(be(e("保存成功")),p(structuredClone(l))):je(i||e("保存失败"))}).catch(t=>{je(t.message||e("保存失败,请重试"))}).finally(()=>{s(!1)})}catch(t){je(t.message||e("提交时发生错误")),s(!1)}},children:e("保存 SMTP 设置")})})})]})})},Ps=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({agent_domain:"",github_oauth_enabled:!1,github_client_id:"",github_client_secret:"",google_oauth_enabled:!1,google_client_id:"",google_client_secret:"",linuxdo_oauth_enabled:!1,linuxdo_client_id:"",linuxdo_client_secret:"",telegram_oauth_enabled:!1,wechat_auth_enabled:!1,wechat_server_address:"",wechat_server_token:"",wechat_account_qrcode_image_url:"",captcha_login_mode:0,captcha_register_mode:0}),[p,x]=t.useState(l),g=t.useRef();function y(e){return t=>{r(n=>({...n,[e]:t}))}}t.useEffect(()=>{j()},[]);const j=async()=>{try{const e=await ye.get("/api/option/getagentoptions"),{success:t,message:n,data:i}=e.data;if(t){const e={};for(let t in i)Object.keys(l).includes(t)&&(e[t]=i[t]);r(e),x(structuredClone(e)),g.current&&g.current.setValues(e)}else je(n)}catch(e){je(e.message)}};return n.jsx(m,{spinning:i,children:n.jsxs(a,{values:l,getFormApi:e=>g.current=e,labelPosition:"left",labelWidth:"120px",onValueChange:e=>{r(t=>({...t,...e}))},children:[n.jsxs(a.Section,{children:[n.jsx(u.Title,{heading:4,children:e("配置 GitHub OAuth App")}),n.jsx(u.Text,{children:n.jsx(ln,{i18nKey:"github_oauth_intro",components:{link:n.jsx("a",{href:"https://github.com/settings/developers",target:"_blank",rel:"noreferrer"})}})}),n.jsx(h,{type:"info",icon:n.jsx(mt,{size:16}),description:n.jsx(u.Text,{children:n.jsx(ln,{i18nKey:"github_oauth_banner_desc",values:{homepageUrl:l.agent_domain?`https://${l.agent_domain}`:e("您的域名"),callbackUrl:l.agent_domain?`https://${l.agent_domain}/oauth/github`:`${e("您的域名")}/oauth/github`},components:{code:n.jsx("code",{})}})}),style:{marginBottom:12}}),n.jsx(a.Switch,{field:"github_oauth_enabled",label:e("启用 GitHub 登录"),extraText:"允许用户通过 GitHub 账号登录和注册",size:"default",checkedText:"|",uncheckedText:"〇",onChange:y("github_oauth_enabled")}),n.jsx(a.Input,{field:"github_client_id",label:"GitHub Client ID",placeholder:e("请输入 GitHub Client ID"),autoComplete:"off",onChange:y("github_client_id")}),n.jsx(a.Input,{field:"github_client_secret",label:"GitHub Client Secret",type:"password",placeholder:e("敏感信息不会发送到前端显示"),autoComplete:"new-password",onChange:y("github_client_secret")})]}),n.jsxs(a.Section,{children:[n.jsx(u.Title,{heading:4,children:e("配置 Google OAuth 2.0")}),n.jsx(u.Text,{children:n.jsx(ln,{i18nKey:"google_oauth_intro_with_link",components:{gconsole:n.jsx("a",{href:"https://console.cloud.google.com/",target:"_blank",rel:"noreferrer"})}})}),n.jsx(h,{type:"info",icon:n.jsx(mt,{size:16}),description:n.jsx(u.Text,{children:n.jsx(ln,{i18nKey:"google_oauth_banner_desc",values:{callbackUrl:l.agent_domain?`https://${l.agent_domain}/oauth/google`:`${e("您的域名")}/oauth/google`},components:{code:n.jsx("code",{})}})}),style:{marginBottom:12}}),n.jsx(a.Switch,{field:"google_oauth_enabled",label:e("启用 Google 登录"),extraText:"允许用户通过 Google 账号登录和注册",size:"default",checkedText:"|",uncheckedText:"〇",onChange:y("google_oauth_enabled")}),n.jsx(a.Input,{field:"google_client_id",label:"Google Client ID",placeholder:e("请输入 Google Client ID"),autoComplete:"off",onChange:y("google_client_id")}),n.jsx(a.Input,{field:"google_client_secret",label:"Google Client Secret",type:"password",placeholder:e("敏感信息不会发送到前端显示"),autoComplete:"new-password",onChange:y("google_client_secret")})]}),n.jsxs(a.Section,{children:[n.jsx(u.Title,{heading:4,children:e("配置 LinuxDO OAuth App")}),n.jsx(u.Text,{children:n.jsx(ln,{i18nKey:"linuxdo_oauth_intro",components:{link:n.jsx("a",{href:"https://connect.linux.do/",target:"_blank",rel:"noreferrer"})}})}),n.jsx(h,{type:"info",icon:n.jsx(mt,{size:16}),description:n.jsx(u.Text,{children:n.jsx(ln,{i18nKey:"linuxdo_oauth_banner_desc",values:{homepageUrl:l.agent_domain?`https://${l.agent_domain}`:e("您的域名"),callbackUrl:l.agent_domain?`https://${l.agent_domain}/oauth/linuxdo`:`${e("您的域名")}/oauth/linuxdo`},components:{code:n.jsx("code",{})}})}),style:{marginBottom:12}}),n.jsx(a.Switch,{field:"linuxdo_oauth_enabled",label:e("启用 LinuxDO 登录"),extraText:"允许用户通过 LinuxDO 账号登录和注册",size:"default",checkedText:"|",uncheckedText:"〇",onChange:y("linuxdo_oauth_enabled")}),n.jsx(a.Input,{field:"linuxdo_client_id",label:"LinuxDO Client ID",placeholder:e("请输入 LinuxDO Client ID"),autoComplete:"off",onChange:y("linuxdo_client_id")}),n.jsx(a.Input,{field:"linuxdo_client_secret",label:"LinuxDO Client Secret",type:"password",placeholder:e("敏感信息不会发送到前端显示"),autoComplete:"new-password",onChange:y("linuxdo_client_secret")})]}),n.jsxs(a.Section,{children:[n.jsx(u.Title,{heading:4,children:e("配置微信登录")}),n.jsx(u.Text,{children:n.jsx(ln,{i18nKey:"wechat_oauth_intro",components:{link:n.jsx("a",{href:"https://github.com/songquanpeng/wechat-server",target:"_blank",rel:"noreferrer"})}})}),n.jsx(a.Switch,{field:"wechat_auth_enabled",label:e("启用微信登录"),extraText:e("允许用户通过微信账号登录和注册"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:y("wechat_auth_enabled")}),n.jsx(a.Input,{field:"wechat_server_address",label:e("WeChat Server 地址"),placeholder:e("例如:https://yourdomain.com"),autoComplete:"off",onChange:y("wechat_server_address")}),n.jsx(a.Input,{field:"wechat_server_token",label:e("WeChat Server 访问凭证"),type:"password",placeholder:e("敏感信息不会发送到前端显示"),autoComplete:"new-password",onChange:y("wechat_server_token")}),n.jsx(a.Input,{field:"wechat_account_qrcode_image_url",label:e("微信公众号二维码图片链接"),placeholder:e("请输入图片链接"),autoComplete:"off",onChange:y("wechat_account_qrcode_image_url")})]}),n.jsxs(a.Section,{children:[n.jsx(u.Title,{heading:4,children:e("滑块验证码")}),n.jsx(u.Text,{children:e('控制代理站登录和注册是否需要滑块验证码,"跟随主站"表示使用主站的全局设置。')}
1),n.jsxs(a.Select,{field:"captcha_login_mode",label:e("登录滑块验证"),style:{width:"100%"},onChange:y("captcha_login_mode"),children:[n.jsx(a.Select.Option,{value:0,children:e("跟随主站")}),n.jsx(a.Select.Option,{value:1,children:e("强制开启")}),n.jsx(a.Select.Option,{value:2,children:e("强制关闭")})]}),n.jsxs(a.Select,{field:"captcha_register_mode",label:e("注册滑块验证"),style:{width:"100%"},onChange:y("captcha_register_mode"),children:[n.jsx(a.Select.Option,{value:0,children:e("跟随主站")}),n.jsx(a.Select.Option,{value:1,children:e("强制开启")}),n.jsx(a.Select.Option,{value:2,children:e("强制关闭")})]})]}),n.jsx(o,{children:n.jsx(c,{span:24,style:{textAlign:"center",marginTop:24},children:n.jsx(d,{type:"primary",onClick:()=>{!l.github_oauth_enabled||l.github_client_id&&l.github_client_secret?!l.google_oauth_enabled||l.google_client_id&&l.google_client_secret?!l.linuxdo_oauth_enabled||l.linuxdo_client_id&&l.linuxdo_client_secret?ke(p,l).length>0?(s(!0),ye.post("/api/option/updateagentoption",l).then(t=>{const{success:n,message:i}=t.data;n?(be(e("保存成功")),x(structuredClone(l))):je(i||e("保存失败"))}).catch(t=>{je(t.message||e("保存失败,请重试"))}).finally(()=>{s(!1)})):je(e("无变更,无需保存")):je("启用 LinuxDO 登录需要配置 LinuxDO Client ID 和 Client Secret"):je(e("启用 Google 登录需要配置 Google Client ID 和 Client Secret")):je(e("启用 GitHub 登录需要配置 GitHub Client ID 和 Client Secret"))},loading:i,children:e("保存设置")})})})]})})},{Text:zs}=u,Ns=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({disclaimer:""}),[u,p]=t.useState(l),x=t.useRef();return t.useEffect(()=>{(async()=>{try{const e=await ye.get("/api/option/getagentoptions"),{success:t,message:n,data:i}=e.data;if(t){const e={};for(let t in i)Object.keys(l).includes(t)&&(e[t]=i[t]);r(e),p(structuredClone(e)),x.current&&x.current.setValues(e)}else je(n)}catch(e){je(e.message)}})()},[]),n.jsx(m,{spinning:i,children:n.jsxs(a,{values:l,getFormApi:e=>x.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:e("用户协议设置"),children:[n.jsx(o,{gutter:16,children:n.jsxs(c,{span:24,children:[n.jsx(a.TextArea,{field:"disclaimer",label:e("用户协议内容"),placeholder:e("在此输入用户协议内容,支持 Markdown & HTML 代码"),autosize:{minRows:10,maxRows:20},style:{fontFamily:"JetBrains Mono, Consolas, Monaco, monospace"},onChange:(g="disclaimer",e=>{r(t=>({...t,[g]:e}))}),validate:t=>t&&t.length>1e5?e("用户协议内容不能超过100000个字符"):""}),n.jsx(zs,{type:"tertiary",style:{marginTop:8,display:"block"},children:e("用户协议将在用户注册/登录时显示,用户必须同意协议才能注册/登录")})]})}),n.jsx(h,{type:"info",icon:n.jsx(mt,{size:16}),description:n.jsxs("div",{children:[n.jsx("div",{style:{marginBottom:8},children:e("用户协议编写建议:")}),n.jsxs("ul",{style:{margin:0,paddingLeft:"20px"},children:[n.jsx("li",{children:e("支持 Markdown 语法,如 **粗体**、*斜体*")}),n.jsx("li",{children:e("支持 HTML 标签,如 <h1>、<p>、<a> 等")}),n.jsx("li",{children:e("建议包含服务条款、隐私政策、免责声明等")}),n.jsx("li",{children:e("应明确用户权利和义务,保护服务提供者合法权益")})]})]}),style:{marginTop:16,marginBottom:16}})]}),n.jsx(o,{children:n.jsx(c,{children:n.jsx(d,{type:"primary",size:"default",onClick:function(){s(!0);try{ye.post("/api/option/updateagentoption",l).then(t=>{const{success:n,message:i}=t.data;n?(be(e("保存成功")),p(structuredClone(l))):je(i||e("保存失败"))}).catch(t=>{je(t.message||e("保存失败,请重试"))}).finally(()=>{s(!1)})}catch(t){je(t.message||e("提交时发生错误")),s(!1)}},children:e("保存用户协议")})})})]})});var g},{Text:As}=u,Ms=()=>{const{t:e}=ge(),[i,s]=t.useContext(Te),[l,r]=t.useState(!1),[u,p]=t.useState({enabled_menus:"",enabled_side_menus:"",enabled_personal_features:"",enable_invite_reward_section:!0}),[x,y]=t.useState(u),j=t.useRef(),f=[{label:e("首页"),value:"home"},{label:e("OpenClaw 一键部署"),value:"openclaw"},{label:e("API 文档"),value:"docs"},{label:e("技能中心"),value:"skills"},{label:e("公告"),value:"announcement"},{label:e("代理加盟"),value:"affiliate"},{label:e("联系我们"),value:"customersupport"},{label:e("文章资讯"),value:"news"}],b=[{label:e("文章管理"),value:"article"},{label:e("推广渠道管理"),value:"invite_channel"},{label:e("OpenClaw 部署"),value:"openclaw"}],_=[{label:e("密码管理"),value:"change_password"},{label:e("删除账户"),value:"delete_account"}];function S(e){return t=>{const n=Array.isArray(t)?t.join(","):t;p(t=>({...t,[e]:n}))}}return t.useEffect(()=>{(async()=>{try{const e=await ye.get("/api/option/getagentoptions"),{success:t,message:n,data:i}=e.data;if(t){const e={...u};for(let t in i)Object.keys(e).includes(t)&&(e[t]=i[t]);p(e),y(structuredClone(e)),j.current&&j.current.setValues({...e,enabled_menus:e.enabled_menus?e.enabled_menus.split(","):[],enabled_side_menus:e.enabled_side_menus?e.enabled_side_menus.split(","):[],enabled_personal_features:e.enabled_personal_features?e.enabled_personal_features.split(","):[]})}else je(n)}catch(e){je(e.message)}})()},[]),n.jsx(m,{spinning:l,children:n.jsxs(a,{values:u,getFormApi:e=>j.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:e("顶部菜单设置"),children:[n.jsx(o,{gutter:16,children:n.jsxs(c,{span:24,children:[n.jsx(a.CheckboxGroup,{field:"enabled_menus",label:e("启用的顶部菜单"),direction:"vertical",initValue:[],onChange:S("enabled_menus"),children:n.jsx(g,{spacing:"loose",wrap:!0,children:f.map(e=>n.jsx(D,{value:e.value,children:e.label},e.value))})}),n.jsx(As,{type:"tertiary",style:{marginTop:8,display:"block"},children:e("选择要在网站顶部显示的菜单项")})]})}),n.jsx(h,{type:"info",icon:n.jsx(mt,{size:16}),description:n.jsxs("div",{children:[n.jsx("div",{style:{marginBottom:8},children:e("菜单说明:")}),n.jsxs("ul",{style:{margin:0,paddingLeft:"20px"},children:[n.jsx("li",{children:e("首页:若取消勾选,未登录用户将跳转至登录页,已登录用户将跳转至控制台")}),n.jsx("li",{children:e("OpenClaw 一键部署:显示 OpenClaw 一键部署介绍页入口")}),n.jsx("li",{children:e("API 文档:显示 API 文档外链入口")}),n.jsx("li",{children:e("公告:显示顶部公告铃铛按钮")}),n.jsx("li",{children:e("代理加盟:显示代理加盟相关信息和链接")}),n.jsx("li",{children:e("联系我们:显示客服联系方式和支持信息")}),n.jsx("li",{children:e("文章资讯:显示已发布的文章列表页面")}),n.jsx("li",{children:e("未选择的菜单项将不会在网站顶部显示")}),n.jsx("li",{children:n.jsx("strong",{children:e('自定义菜单链接请在"基础è
1®¾ç½®"中配置')})})]})]}),style:{marginTop:16,marginBottom:16}})]}),n.jsx(a.Section,{text:e("侧边菜单设置"),children:n.jsx(o,{gutter:16,children:n.jsxs(c,{span:24,children:[n.jsx(a.CheckboxGroup,{field:"enabled_side_menus",label:e("启用的侧边菜单"),direction:"vertical",initValue:[],onChange:S("enabled_side_menus"),children:n.jsx(g,{spacing:"loose",wrap:!0,children:b.map(e=>n.jsx(D,{value:e.value,children:e.label},e.value))})}),n.jsx(As,{type:"tertiary",style:{marginTop:8,display:"block"},children:e("取消勾选的菜单项将对所有用户隐藏(包含代理管理员)")})]})})}),n.jsx(a.Section,{text:e("个人设置功能"),children:n.jsx(o,{gutter:16,children:n.jsxs(c,{span:24,children:[n.jsx(a.CheckboxGroup,{field:"enabled_personal_features",label:e("启用的个人设置功能"),direction:"vertical",initValue:[],onChange:S("enabled_personal_features"),children:n.jsx(g,{spacing:"loose",wrap:!0,children:_.map(e=>n.jsx(D,{value:e.value,children:e.label},e.value))})}),n.jsx(As,{type:"tertiary",style:{marginTop:8,display:"block"},children:e("取消勾选的功能将在用户个人设置页面中隐藏")})]})})}),n.jsx(a.Section,{text:e("钱包页面设置"),children:n.jsx(o,{gutter:16,children:n.jsxs(c,{span:24,children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:4},children:[n.jsx(E,{checked:!!u.enable_invite_reward_section,onChange:e=>p(t=>({...t,enable_invite_reward_section:e}))}),n.jsx(As,{children:e("显示邀请奖励模块")})]}),n.jsx(As,{type:"tertiary",style:{display:"block"},children:e("关闭后钱包页面右侧的邀请奖励卡片将不再显示")})]})})}),n.jsx(o,{children:n.jsx(c,{children:n.jsx(d,{type:"primary",size:"default",onClick:function(){r(!0),ye.post("/api/option/updateagentoption",u).then(t=>{const{success:n,message:l,data:a}=t.data;if(n){if(be(e("保存成功")),y(structuredClone(u)),i?.status?.is_global_agent){const e={};void 0!==a?.enabled_menus&&(e.enabled_menus=a.enabled_menus),void 0!==a?.enabled_side_menus&&(e.enabled_side_menus=a.enabled_side_menus),void 0!==a?.enabled_personal_features&&(e.enabled_personal_features=a.enabled_personal_features),void 0!==a?.enable_invite_reward_section&&(e.invite_reward_section_enabled=a.enable_invite_reward_section),Object.keys(e).length>0&&s({type:"set",payload:{...i?.status,...e}})}}else je(l||e("保存失败"))}).catch(t=>{je(t.message||e("保存失败,请重试"))}).finally(()=>{r(!1)})},children:e("保存菜单设置")})})})]})})},{Text:Os}=u,Ds=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({currency_type:"CUSTOM",custom_currency_symbol:"💰",rate:"",agent_price:"",sale_price:"",show_official_discount:!0}),[u,p]=t.useState(l),x=t.useRef();function g(e){return t=>{r(n=>({...n,[e]:t}))}}t.useEffect(()=>{y()},[]);const y=async()=>{try{const e=await ye.get("/api/option/getagentoptions"),{success:t,message:n,data:i}=e.data;if(t){const e={};for(let t in i)Object.keys(l).includes(t)&&(e[t]=i[t]);void 0!==e.show_official_discount&&null!==e.show_official_discount||(e.show_official_discount=!0),r(e),p(structuredClone(e)),x.current&&x.current.setValues(e)}else je(n)}catch(e){je(e.message)}};return n.jsx(n.Fragment,{children:n.jsxs(m,{spinning:i,children:[n.jsx(h,{type:"info",description:e("配置代理站点的货币显示方式和充值价格。货币汇率由主站统一管理。"),icon:n.jsx(mt,{size:16}),style:{marginBottom:16}}),n.jsxs(a,{getFormApi:e=>x.current=e,onValueChange:e=>r(e),labelPosition:"left",labelAlign:"left",labelWidth:140,children:[n.jsx(a.Section,{text:e("货币配置"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsxs(a.Select,{field:"currency_type",label:e("货币类型"),placeholder:e("请选择货币类型"),initValue:"CUSTOM",extraText:e("选择站点显示的货币类型"),style:{width:"100%"},onChange:g("currency_type"),children:[n.jsx(N.Option,{value:"USD",children:e("美元 ($)")}),n.jsx(N.Option,{value:"TOKENS",children:e("代币 (TOKEN)")}),n.jsx(N.Option,{value:"CUSTOM",children:e("自定义货币")})]})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"custom_currency_symbol",label:e("自定义货币符号"),placeholder:e("请输入货币符号"),initValue:"💰",extraText:e("选择CUSTOM时使用的货币符号"),style:{width:"100%"},onChange:g("custom_currency_symbol"),disabled:"CUSTOM"!==l.currency_type})})]})}),n.jsx(a.Section,{text:e("充值价格设置"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"rate",label:e("系统费率"),placeholder:e("请输入系统费率"),disabled:!0,extraText:e("系统计费费率(系统自动设置,不可修改)"),suffix:"%",min:0,precision:4,style:{width:"100%"}})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"agent_price",label:e("成本价格"),placeholder:e("请输入成本价格"),disabled:!0,extraText:e("您的成本价格(系统自动设置,不可修改)"),suffix:e("元/1$ 额度"),min:0,precision:6,style:{width:"100%"}})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"sale_price",label:e("在线充值价格"),placeholder:e("请输入在线充值价格"),extraText:e("用户在线充值时的单价,建议设置合理的利润空间"),suffix:e("元/1$ 额度"),min:0,precision:6,style:{width:"100%"},onChange:g("sale_price"),rules:[{required:!0,message:e("在线充值价格不能为空")},{type:"number",min:1e-6,message:e("价格必须大于0")}]})})]})}),n.jsx(a.Section,{text:e("模型广场展示设置"),children:n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"show_official_discount",label:e("显示「比官方便宜」标签"),extraText:e("关闭后,模型广场分组价格将不再展示「比官方便宜 N%」红色标签;默认开启"),onChange:g("show_official_discount")}
1)})})}),n.jsx("div",{style:{marginTop:24,display:"flex",justifyContent:"flex-end"},children:n.jsx(d,{type:"primary",onClick:function(){s(!0),ye.post("/api/option/updateagentoption",l).then(t=>{const{success:n,message:i}=t.data;n?(be(e("保存成功")),p(structuredClone(l))):je(i||e("保存失败"))}).catch(t=>{je(t.message||e("保存失败,请重试"))}).finally(()=>{s(!1)})},loading:i,children:e("保存配置")})})]})]})})},Ls=["content","extra"],Bs=[{key:"content",label:"内容",type:"textarea",rows:4,maxCount:500},{key:"extra",label:"说明",type:"input",maxLength:200}],{Text:Fs}=u,Ws=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({agent_announcements:"",follow_main_announce:!0,announcements_enabled:!0}),[u,p]=t.useState(l),[h,y]=t.useState([]),[f,b]=t.useState(!1),[_,S]=t.useState(!1),[k,R]=t.useState(null),[P,z]=t.useState(null),[N,A]=t.useState(!1),[M,O]=t.useState(!1),[D,L]=t.useState({content:"",publishDate:new Date,type:"default",extra:""}),[B,F]=t.useState(1),[W,J]=t.useState(10),[U,V]=t.useState([]),[K,G]=t.useState(!0),[q,$]=t.useState(!0),[H,Q]=t.useState(!1),[X,Y]=t.useState(null);t.useEffect(()=>{Z()},[]);const Z=async()=>{try{s(!0);const t=await ye.get("/api/option/getagentoptions"),{success:n,message:i,data:a}=t.data;if(n){const t={};for(let e in a)Object.keys(l).includes(e)&&(t[e]=a[e]);r(t),p(structuredClone(t));try{if(a.agent_announcements){const e=JSON.parse(a.agent_announcements);y(Array.isArray(e)?e:[])}}catch(e){console.error("解析公告数据失败:",e),y([])}G(!1!==a.follow_main_announce),$(!1!==a.announcements_enabled),Q(an(a.translation_enabled))}else je(i)}catch(t){je(t.message)}finally{s(!1)}},ee=[{value:"default",label:e("默认")},{value:"ongoing",label:e("进行中")},{value:"success",label:e("成功")},{value:"warning",label:e("警告")},{value:"error",label:e("错误")}],te=e=>({default:"grey",ongoing:"blue",success:"green",warning:"orange",error:"red"}[e]||"grey"),ne=[{title:e("内容"),dataIndex:"content",key:"content",render:e=>n.jsx("div",{style:{maxWidth:"300px",wordBreak:"break-word",whiteSpace:"pre-wrap"},children:e})},{title:e("发布时间"),dataIndex:"publishDate",key:"publishDate",width:180,render:e=>n.jsxs("div",{children:[n.jsx("div",{style:{fontWeight:"bold"},children:Ce(e)}),n.jsx("div",{style:{fontSize:"12px",color:"hsl(var(--muted-foreground))",marginTop:"2px"},children:e?we(new Date(e)):"-"})]})},{title:e("类型"),dataIndex:"type",key:"type",width:100,render:e=>n.jsx(j,{color:te(e),shape:"circle",children:ee.find(t=>t.value===e)?.label||e})},{title:e("说明"),dataIndex:"extra",key:"extra",render:e=>n.jsx("div",{style:{maxWidth:"200px",wordBreak:"break-word",color:"hsl(var(--muted-foreground))"},children:e||"-"})},...H?[{title:e("翻译"),key:"translation_status",width:110,render:(e,t)=>n.jsx(hn,{item:t,fields:Ls,onClick:()=>Y(t)})}]:[],{title:e("操作"),key:"action",fixed:"right",width:H?230:150,render:(t,i)=>n.jsxs(g,{children:[H&&n.jsx(d,{icon:n.jsx(Ge,{size:14}),theme:"light",type:"tertiary",size:"small",className:"!rounded-full",onClick:()=>Y(i),children:e("译文")}),n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",className:"!rounded-full",onClick:()=>ie(i),children:e("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",className:"!rounded-full",onClick:()=>se(i),children:e("删除")})]})}],ie=e=>{z(e),L({content:e.content,publishDate:e.publishDate?new Date(e.publishDate):new Date,type:e.type||"default",extra:e.extra||""}),b(!0)},se=e=>{R(e),S(!0)},le={selectedRowKeys:U,onChange:(e,t)=>
1{V(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(m,{spinning:i,children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsxs("div",{className:"mb-2",children:[n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(Xe,{size:16,className:"mr-2"}),n.jsx(Fs,{children:e("代理站系统公告管理,可以发布站点通知和重要消息(最多50个,前端显示最新10条)")})]}),H&&n.jsxs("div",{className:"flex items-center text-amber-500 mt-1",children:[n.jsx(Ge,{size:14,className:"mr-2"}),n.jsx(Fs,{type:"warning",size:"small",children:"t('已开启自动翻译:保存设置时会对未翻译/原文已修改的条目自动翻译为 6 种语言')"})]})]}),n.jsx("div",{className:"mb-4 p-3 bg-gray-50 rounded-lg",children:n.jsxs("div",{className:"flex flex-col md:flex-row gap-4 items-start md:items-center",children:[n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(E,{checked:q,onChange:e=>{$(e),O(!0)}}),n.jsx(Fs,{strong:!0,children:e("启用公告模块")})]}),q&&n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(E,{checked:K,onChange:e=>{G(e),O(!0)}}),n.jsx(Fs,{children:e("跟随主站公告")}),n.jsx(Fs,{type:"tertiary",size:"small",children:e(K?"(将显示主站公告,忽略自定义公告)":"(使用下方自定义公告)")})]})]})}),n.jsx(I,{margin:"12px"}),n.jsx("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:n.jsxs("div",{className:"flex gap-2 w-full md:w-auto",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"!rounded-full w-full md:w-auto",onClick:()=>{z(null),L({content:"",publishDate:new Date,type:"default",extra:""}),b(!0)},disabled:!q||K,children:e("添加公告")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===U.length)return void je(e("请先选择要删除的系统公告"));const t=h.filter(e=>!U.includes(e.id));y(t),V([]),O(!0),be(e("已删除 {{count}} 个系统公告,记得保存设置",{count:U.length}))},disabled:0===U.length||!q||K,className:"!rounded-full w-full md:w-auto",children:[e("批量删除")," ",U.length>0&&`(${U.length})`]})]})})]}),children:q?K?n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:e("当前跟随主站公告,将显示主站的系统公告"),style:{padding:30}}):n.jsx(v,{columns:ne,dataSource:(()=>{const e=[...h].sort((e,t)=>{const n=new Date(e.publishDate).getTime();return new Date(t.publishDate).getTime()-n}),t=(B-1)*W,n=t+W;return e.slice(t,n)})(),rowSelection:le,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:B,pageSize:W,total:h.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:t=>e("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:t.currentStart,end:t.currentEnd,total:h.length}),pageSizeOptions:["5","10","20","30"],onChange:(e,t)=>
1{F(e),J(t)},onShowSizeChange:(e,t)=>{F(1),J(t)}},size:"middle",empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:e("暂无系统公告"),style:{padding:30}}),className:"rounded-xl overflow-hidden"}):n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:e("公告模块已禁用"),style:{padding:30}})}),n.jsx(o,{children:n.jsx(c,{span:24,style:{textAlign:"center",marginTop:24},children:n.jsx(d,{type:"primary",size:"large",onClick:async()=>{if(ke(u,l).length>0||M){s(!0);try{let t=h;const n={...l,agent_announcements:JSON.stringify(t),follow_main_announce:K,announcements_enabled:q},i=await ye.post("/api/option/updateagentoption",n),{success:s,message:a}=i.data;s?(be(e("保存成功")),p(structuredClone(l)),O(!1)):je(a||e("保存失败"))}catch(t){je(t?.message||e("保存失败,请重试"))}finally{s(!1)}}else je(e("无变更,无需保存"))},loading:i,disabled:!M&&ke(l,u),children:e("保存设置")})})}),n.jsx(x,{title:e(P?"编辑公告":"添加公告"),visible:f,onOk:async()=>{if(D.content&&D.publishDate)try{A(!0);const t={...D,publishDate:D.publishDate.toISOString()};let n;if(P)n=h.map(e=>e.id===P.id?{...e,...t}:e);else{const e={id:Math.max(...h.map(e=>e.id),0)+1,...t};n=[...h,e]}y(n),O(!0),b(!1),be(e(P?"公告已更新,记得保存设置":"公告已添加,记得保存设置"))}catch(t){je(e("操作失败")+": "+t.message)}finally{A(!1)}else je(e("请填写完整的公告信息"))},onCancel:()=>b(!1),okText:e("保存"),cancelText:e("取消"),className:"rounded-xl",confirmLoading:N,children:n.jsxs(a,{layout:"vertical",initValues:D,children:[n.jsx(a.TextArea,{field:"content",label:e("公告内容"),placeholder:e("请输入公告内容"),maxCount:500,rows:3,rules:[{required:!0,message:e("请输入公告内容")}],onChange:e=>L({...D,content:e})}),n.jsx(a.DatePicker,{field:"publishDate",label:e("发布日期"),type:"dateTime",rules:[{required:!0,message:e("请选择发布日期")}],onChange:e=>L({...D,publishDate:e})}),n.jsx(a.Select,{field:"type",label:e("公告类型"),optionList:ee,onChange:e=>L({...D,type:e})}),n.jsx(a.Input,{field:"extra",label:e("说明信息"),placeholder:e("可选的说明信息"),maxLength:100,onChange:e=>L({...D,extra:e})})]},P?P.id:"new")}),n.jsx(x,{title:e("确认删除"),visible:_,onOk:()=>{if(k){const t=h.filter(e=>e.id!==k.id);y(t),O(!0),be(e("公告已删除,记得保存设置"))}S(!1),R(null)},onCancel:()=>{S(!1),R(null)},okText:e("确认删除"),cancelText:e("取消"),type:"warning",className:"rounded-xl",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(Fs,{children:e("确定要删除此公告吗?")})}),n.jsx(xn,{visible:!!X,onClose:()=>Y(null),item:X||{},fields:Bs.map(t=>({...t,label:e(t.label)})),translationEnabled:H,onApply:e=>{if(!X)return;const t=h.map(t=>t.id===X.id?{...t,...e}:t);y(t),O(!0)}})]})},Js=["description","route"],Us=[{key:"description",label:"说明",type:"input",maxLength:200},{key:"route",label:"线路描述",type:"input",maxLength:100}],{Text:Vs}=u,Ks=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({agent_api_info:"",api_info_enabled:!0}),[u,p]=t.useState(l),[h,y]=t.useState([]),[f,b]=t.useState(!1),[_,S]=t.useState(!1),[k,P]=t.useState(null),[z,N]=t.useState(null),[A,M]=t.useState(!1),[O,D]=t.useState(!1),[L,B]=t.useState({url:"",description:"",route:"",color:"blue"}),[F,W]=t.useState(1),[J,U]=t.useState(10),[V,K]=t.useState([]),[G,q]=t.useState(!0),[$,H]=t.useState(!1),[Q,X]=t.useState(null);t.useEffect(()=>{Y()},[]);const Y=async()=>{try{s(!0);const t=await ye.get("/api/option/getagentoptions"),{success:n,message:i,data:a}=t.data;if(n){const t={};for(let e in a)Object.keys(l).includes(e)&&(t[e]=a[e]);r(t),p(structuredClone(t));try{if(a.agent_api_info){const e=JSON.parse(a.agent_api_info);y(Array.isArray(e)?e:[])}}catch(e){console.error("解析API信息数据失败:",e),y([])}q(!1!==a.api_info_enabled),H(an(a.translation_enabled))}else je(i)}catch(t){je(t.message)}finally{s(!1)}},Z=[{title:"ID",dataIndex:"id"},{title:e("API地址"),dataIndex:"url",render:(e,t)=>n.jsx(j,{color:t.color,className:"!rounded-full",style:{maxWidth:"280px"},children:e})},{title:e("线路描述"),dataIndex:"route",render:(e,t)=>n.jsx(j,{shape:"circle",children:e})},{title:e("说明"),dataIndex:"description",ellipsis:!0,render:(e,t)=>n.jsx(j,{shape:"circle",children:e||"-"})},{title:e("颜色"),dataIndex:"color",render:e=>n.jsx(R,{size:"extra-extra-small",color:e})},...$?[{title:e("翻译"),key:"translation_status",width:110,render:(e,t)=>n.jsx(hn,{item:t,fields:Js,onClick:()=>X(t)})}]:[],{title:e("操作"),fixed:"right",width:$?230:150,render:(t,i)=>n.jsxs(g,{children:[$&&n.jsx(d,{icon:n.jsx(Ge,{size:14}),theme:"light",type:"tertiary",size:"small",className:"!rounded-full",onClick:()=>X(i),children:e("译文")}),n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",className:"!rounded-full",onClick:()=>ee(i),children:e("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",className:"!rounded-full",onClick:()=>te(i),children:e("删除")})]})}],ee=e=>{N(e),B({url:e.url,description:e.description,route:e.route,color:e.color||"blue"}),b(!0)},te=e=>{P(e),S(!0)},ne={selectedRowKeys:V,onChange:(e,t)=>
1{K(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(m,{spinning:i,children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsxs("div",{className:"mb-2",children:[n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(it,{size:16,className:"mr-2"}),n.jsx(Vs,{children:e("API信息管理,可以配置多个API地址用于状态展示和负载均衡(最多30个)")})]}),$&&n.jsxs("div",{className:"flex items-center text-amber-500 mt-1",children:[n.jsx(Ge,{size:14,className:"mr-2"}),n.jsx(Vs,{type:"warning",size:"small",children:"t('已开启自动翻译:保存设置时会对未翻译/原文已修改的条目自动翻译为 6 种语言')"})]})]}),n.jsx("div",{className:"mb-4 p-3 bg-gray-50 rounded-lg",children:n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(E,{checked:G,onChange:e=>{q(e),D(!0)}}),n.jsx(Vs,{strong:!0,children:e("启用API信息模块")}),n.jsx(Vs,{type:"tertiary",size:"small",children:e("(关闭后将不会在前端显示API状态信息)")})]})}),n.jsx(I,{margin:"12px"}),n.jsx("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:n.jsxs("div",{className:"flex gap-2 w-full md:w-auto",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"!rounded-full w-full md:w-auto",onClick:()=>{N(null),B({url:"",description:"",route:"",color:"blue"}),b(!0)},disabled:!G,children:e("添加API")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===V.length)return void je(e("请先选择要删除的API信息"));const t=h.filter(e=>!V.includes(e.id));y(t),K([]),D(!0),be(e("已删除 {{count}} 个API信息,记得保存设置",{count:V.length}))},disabled:0===V.length||!G,className:"!rounded-full w-full md:w-auto",children:[e("批量删除")," ",V.length>0&&`(${V.length})`]})]})})]}),children:G?n.jsx(v,{columns:Z,dataSource:(()=>{const e=(F-1)*J,t=e+J;return h.slice(e,t)})(),rowSelection:ne,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:F,pageSize:J,total:h.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:t=>e("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:t.currentStart,end:t.currentEnd,total:h.length}),pageSizeOptions:["5","10","20","30"],onChange:(e,t)=>
1{W(e),U(t)},onShowSizeChange:(e,t)=>{W(1),U(t)}},size:"middle",empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:e("暂无API信息"),style:{padding:30}}),className:"rounded-xl overflow-hidden"}):n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:e("API信息模块已禁用"),style:{padding:30}})}),n.jsx(o,{children:n.jsx(c,{span:24,style:{textAlign:"center",marginTop:24},children:n.jsx(d,{type:"primary",size:"large",onClick:async()=>{if(!ke(l,u)||O){s(!0);try{let t=h;const n={...l,agent_api_info:JSON.stringify(t),api_info_enabled:G},i=await ye.post("/api/option/updateagentoption",n),{success:s,message:a}=i.data;s?(be(e("保存成功")),p(structuredClone(l)),D(!1)):je(a||e("保存失败"))}catch(t){je(t?.message||e("保存失败,请重试"))}finally{s(!1)}}else je(e("无变更,无需保存"))},loading:i,disabled:!O&&ke(l,u),children:e("保存设置")})})}),n.jsx(x,{title:e(z?"编辑API":"添加API"),visible:f,onOk:async()=>{if(L.url&&L.route&&L.description){try{new URL(L.url)}catch(t){return void je(e("请输入有效的URL地址"))}try{let t;if(M(!0),z)t=h.map(e=>e.id===z.id?{...e,...L}:e);else{const e={id:Math.max(...h.map(e=>e.id),0)+1,...L};t=[...h,e]}y(t),D(!0),b(!1),be(e(z?"API信息已更新,记得保存设置":"API信息已添加,记得保存设置"))}catch(t){je(e("操作失败")+": "+t.message)}finally{M(!1)}}else je(e("请填写完整的API信息"))},onCancel:()=>b(!1),okText:e("保存"),cancelText:e("取消"),className:"rounded-xl",confirmLoading:A,children:n.jsxs(a,{layout:"vertical",initValues:L,children:[n.jsx(a.Input,{field:"url",label:e("API地址"),placeholder:"https://api.example.com",rules:[{required:!0,message:e("请输入API地址")}],onChange:e=>B({...L,url:e})}),n.jsx(a.Input,{field:"route",label:e("线路描述"),placeholder:e("如:香港线路"),rules:[{required:!0,message:e("请输入线路描述")}],onChange:e=>B({...L,route:e})}),n.jsx(a.Input,{field:"description",label:e("说明"),placeholder:e("如:大带宽批量分析图片推荐"),rules:[{required:!0,message:e("请输入说明")}],onChange:e=>B({...L,description:e})}),n.jsx(a.Select,{field:"color",label:e("标识颜色"),optionList:[{value:"blue",label:"blue"},{value:"green",label:"green"},{value:"cyan",label:"cyan"},{value:"purple",label:"purple"},{value:"pink",label:"pink"},{value:"red",label:"red"},{value:"orange",label:"orange"},{value:"amber",label:"amber"},{value:"yellow",label:"yellow"},{value:"lime",label:"lime"},{value:"light-green",label:"light-green"},{value:"teal",label:"teal"},{value:"light-blue",label:"light-blue"},{value:"indigo",label:"indigo"},{value:"violet",label:"violet"},{value:"grey",label:"grey"}],onChange:e=>B({...L,color:e}),render:e=>n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[n.jsx(R,{size:"extra-extra-small",color:e.value}),e.label]})})]},z?z.id:"new")}),n.jsx(x,{title:e("确认删除"),visible:_,onOk:()=>{if(k){const t=h.filter(e=>e.id!==k.id);y(t),D(!0),be(e("API信息已删除,记得保存设置"))}S(!1),P(null)},onCancel:()=>{S(!1),P(null)},okText:e("确认删除"),cancelText:e("取消"),type:"warning",className:"rounded-xl",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx(Vs,{children:e("确定要删除此API信息吗?")})}),n.jsx(xn,{visible:!!Q,onClose:()=>X(null),item:Q||{},fields:Us.map(t=>({...t,label:e(t.label)})),translationEnabled:$,onApply:e=>{if(!Q)return;const t=h.map(t=>t.id===Q.id?{...t,...e}:t);y(t),D(!0)}})]})},Gs=["question","answer"],qs=[{key:"question",label:"问题标题",type:"input",maxLength:200},{key:"answer",label:"回答内容",type:"textarea",rows:5,maxCount:1e3}],{Text:$s}=u,Hs=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({agent_faq:"",follow_main_faq:!0,faq_enabled:!0}),[u,p]=t.useState(l),[h,y]=t.useState([]),[j,f]=t.useState(!1),[b,_]=t.useState(!1),[S,k]=t.useState(null),[R,P]=t.useState(null),[z,N]=t.useState(!1),[A,M]=t.useState(!1),[O,D]=t.useState({question:"",answer:""}),[L,B]=t.useState(1),[F,W]=t.useState(10),[J,U]=t.useState([]),[V,K]=t.useState(!0),[G,q]=t.useState(!0),[$,H]=t.useState(!1),[Q,X]=t.useState(null);t.useEffect(()=>{Y()},[]);const Y=async()=>{try{s(!0);const t=await ye.get("/api/option/getagentoptions"),{success:n,message:i,data:a}=t.data;if(n){const t={};for(let e in a)Object.keys(l).includes(e)&&(t[e]=a[e]);r(t),p(structuredClone(t));try{if(a.agent_faq){const e=JSON.parse(a.agent_faq);y(Array.isArray(e)?e:[])}}catch(e){console.error("解析FAQ数据失败:",e),y([])}K(!1!==a.follow_main_faq),q(!1!==a.faq_enabled),H(an(a.translation_enabled))}else je(i)}catch(t){je(t.message)}finally{s(!1)}},Z=[{title:e("问题标题"),dataIndex:"question",key:"question",render:e=>n.jsx("div",{style:{maxWidth:"300px",wordBreak:"break-word",fontWeight:"bold"},children:e})}
1,{title:e("回答内容"),dataIndex:"answer",key:"answer",render:e=>n.jsx("div",{style:{maxWidth:"400px",wordBreak:"break-word",whiteSpace:"pre-wrap",color:"hsl(var(--foreground) / 0.80)"},children:e})},...$?[{title:e("翻译"),key:"translation_status",width:110,render:(e,t)=>n.jsx(hn,{item:t,fields:Gs,onClick:()=>X(t)})}]:[],{title:e("操作"),key:"action",fixed:"right",width:$?230:150,render:(t,i)=>n.jsxs(g,{children:[$&&n.jsx(d,{icon:n.jsx(Ge,{size:14}),theme:"light",type:"tertiary",size:"small",className:"!rounded-full",onClick:()=>X(i),children:e("译文")}),n.jsx(d,{icon:n.jsx($e,{size:14}),theme:"light",type:"tertiary",size:"small",className:"!rounded-full",onClick:()=>ee(i),children:e("编辑")}),n.jsx(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",size:"small",className:"!rounded-full",onClick:()=>te(i),children:e("删除")})]})}],ee=e=>{P(e),D({question:e.question,answer:e.answer}),f(!0)},te=e=>{k(e),_(!0)},ne={selectedRowKeys:J,onChange:(e,t)=>{U(e)},onSelect:(e,t,n)=>{},onSelectAll:(e,t)=>{},getCheckboxProps:e=>({disabled:!1,name:e.id})};return n.jsxs(m,{spinning:i,children:[n.jsx(a.Section,{text:n.jsxs("div",{className:"flex flex-col w-full",children:[n.jsxs("div",{className:"mb-2",children:[n.jsxs("div",{className:"flex items-center text-blue-500",children:[n.jsx(tt,{size:16,className:"mr-2"}),n.jsx($s,{children:e("代理站常见问答管理,为用户提供常见问题的答案(最多30个,前端显示最新15条)")})]}),$&&n.jsxs("div",{className:"flex items-center text-amber-500 mt-1",children:[n.jsx(Ge,{size:14,className:"mr-2"}),n.jsx($s,{type:"warning",size:"small",children:"t('已开启自动翻译:保存设置时会对未翻译/原文已修改的条目自动翻译为 6 种语言')"})]})]}),n.jsx("div",{className:"mb-4 p-3 bg-gray-50 rounded-lg",children:n.jsxs("div",{className:"flex flex-col md:flex-row gap-4 items-start md:items-center",children:[n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(E,{checked:G,onChange:e=>{q(e),M(!0)}}),n.jsx($s,{strong:!0,children:e("启用问答模块")})]}),G&&n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(E,{checked:V,onChange:e=>{K(e),M(!0)}}),n.jsx($s,{children:e("跟随主站问答")}),n.jsx($s,{type:"tertiary",size:"small",children:e(V?"(将显示主站问答,忽略自定义问答)":"(使用下方自定义问答)")})]})]})}),n.jsx(I,{margin:"12px"}),n.jsx("div",{className:"flex flex-col md:flex-row justify-between items-center gap-4 w-full",children:n.jsxs("div",{className:"flex gap-2 w-full md:w-auto",children:[n.jsx(d,{theme:"light",type:"primary",icon:n.jsx(Ye,{size:14}),className:"!rounded-full w-full md:w-auto",onClick:()=>{P(null),D({question:"",answer:""}),f(!0)},disabled:!G||V,children:e("添加问答")}),n.jsxs(d,{icon:n.jsx(He,{size:14}),type:"danger",theme:"light",onClick:()=>{if(0===J.length)return void je(e("请先选择要删除的常见问答"));const t=h.filter(e=>!J.includes(e.id));y(t),U([]),M(!0),be(e("已删除 {{count}} 个常见问答,记得保存设置",{count:J.length}))},disabled:0===J.length||!G||V,className:"!rounded-full w-full md:w-auto",children:[e("批量删除")," ",J.length>0&&`(${J.length})`]})]})})]}),children:G?V?n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:e("当前跟随主站问答,将显示主站的常见问答"),style:{padding:30}}):n.jsx(v,{columns:Z,dataSource:(()=>{const e=(L-1)*F,t=e+F;return h.slice(e,t)})(),rowSelection:ne,rowKey:"id",scroll:{x:"max-content"},pagination:{currentPage:L,pageSize:F,total:h.length,showSizeChanger:!0,showQuickJumper:!0,formatPageText:t=>e("第 {{start}} - {{end}} 条,共 {{total}} 条",{start:t.currentStart,end:t.currentEnd,total:h.length}),pageSizeOptions:["5","10","20","30"],onChange:(e,t)=>
1{B(e),W(t)},onShowSizeChange:(e,t)=>{B(1),W(t)}},size:"middle",empty:n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:e("暂无常见问答"),style:{padding:30}}),className:"rounded-xl overflow-hidden"}):n.jsx(C,{image:n.jsx(T,{style:{width:150,height:150}}),darkModeImage:n.jsx(w,{style:{width:150,height:150}}),description:e("问答模块已禁用"),style:{padding:30}})}),n.jsx(o,{children:n.jsx(c,{span:24,style:{textAlign:"center",marginTop:24},children:n.jsx(d,{type:"primary",size:"large",onClick:async()=>{if(!ke(l,u)||A){s(!0);try{let t=h;const n={...l,agent_faq:JSON.stringify(t),follow_main_faq:V,faq_enabled:G},i=await ye.post("/api/option/updateagentoption",n),{success:s,message:a}=i.data;s?(be(e("保存成功")),p(structuredClone(l)),M(!1)):je(a||e("保存失败"))}catch(t){je(t?.message||e("保存失败,请重试"))}finally{s(!1)}}else je(e("无变更,无需保存"))},loading:i,disabled:!A&&ke(l,u),children:e("保存设置")})})}),n.jsx(x,{title:e(R?"编辑问答":"添加问答"),visible:j,onOk:async()=>{if(O.question&&O.answer)try{let t;if(N(!0),R)t=h.map(e=>e.id===R.id?{...e,...O}:e);else{const e={id:Math.max(...h.map(e=>e.id),0)+1,...O};t=[...h,e]}y(t),M(!0),f(!1),be(e(R?"问答已更新,记得保存设置":"问答已添加,记得保存设置"))}catch(t){je(e("操作失败")+": "+t.message)}finally{N(!1)}else je(e("请填写完整的问答信息"))},onCancel:()=>f(!1),okText:e("保存"),cancelText:e("取消"),className:"rounded-xl",confirmLoading:z,width:800,children:n.jsxs(a,{layout:"vertical",initValues:O,children:[n.jsx(a.Input,{field:"question",label:e("问题标题"),placeholder:e("请输入问题标题"),maxLength:200,rules:[{required:!0,message:e("请输入问题标题")}],onChange:e=>D({...O,question:e})}),n.jsx(a.TextArea,{field:"answer",label:e("回答内容"),placeholder:e("请输入回答内容"),maxCount:1e3,rows:6,rules:[{required:!0,message:e("请输入回答内容")}],onChange:e=>D({...O,answer:e})})]},R?R.id:"new")}),n.jsx(x,{title:e("确认删除"),visible:b,onOk:()=>{if(S){const t=h.filter(e=>e.id!==S.id);y(t),M(!0),be(e("问答已删除,记得保存设置"))}_(!1),k(null)},onCancel:()=>{_(!1),k(null)},okText:e("确认删除"),cancelText:e("取消"),type:"warning",className:"rounded-xl",okButtonProps:{type:"danger",theme:"solid"},children:n.jsx($s,{children:e("确定要删除此问答吗?")})}),n.jsx(xn,{visible:!!Q,onClose:()=>X(null),item:Q||{},fields:qs.map(t=>({...t,label:e(t.label)})),translationEnabled:$,onApply:e=>{if(!Q)return;const t=h.map(t=>t.id===Q.id?{...t,...e}:t);y(t),M(!0)}})]})},{Text:Qs}=u,Xs=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({sms_login_enabled:!1,sms_provider:"",sms_secret_id:"",sms_secret_key:"",sms_region:"",sms_sdk_app_id:"",sms_sign_name:"",sms_template_id:"",sms_code_expire_minutes:5,sms_rate_limit_minutes:1,sms_rate_limit_count:1,sms_mos_username:"",sms_mos_password:"",sms_mos_signature:"",sms_mos_content_template:"您的验证码为{code},{expire}分钟内有效,请勿泄露。",sms_mos_biz_type:"",sms_mos_endpoint:"https://ns.mosapi.cn:9100"}),[u,p]=t.useState(l),h=t.useRef();function x(e){return t=>{r(n=>({...n,[e]:t}))}}return t.useEffect(()=>{(async()=>{try{const e=await ye.get("/api/option/getagentoptions"),{success:t,message:n,data:i}=e.data;if(t){const e={};for(let t in i)Object.keys(l).includes(t)&&(e[t]=i[t]);e.sms_login_enabled=!0===i.sms_login_enabled,e.sms_code_expire_minutes=Number(i.sms_code_expire_minutes)||5,e.sms_rate_limit_minutes=Number(i.sms_rate_limit_minutes)||1,e.sms_rate_limit_count=Number(i.sms_rate_limit_count)||1,r(e),p(structuredClone(e)),h.current&&h.current.setValues(e)}else je(n)}catch(e){je(e.message)}})()},[]),n.jsx(m,{spinning:i,children:n.jsxs(a,{values:l,getFormApi:e=>h.current=e,style:{marginBottom:15},children:[n.jsx(a.Section,{text:e("短信验证码登录"),children:n.jsx(o,{gutter:16,children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"sms_login_enabled",label:e("启用短信验证码登录"),checkedText:e("开"),uncheckedText:e("关"),onChange:x("sms_login_enabled")}),n.jsx(Qs,{type:"tertiary",style:{fontSize:12,display:"block",marginTop:6},children:e("开启后,用户可使用手机号+验证码登录,需配置下方短信服务信息")})]})})}),n.jsxs(a.Section,{text:e("短信服务配置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,children:n.jsxs(a.Select,{field:"sms_provider",label:e("短信服务提供商"),placeholder:e("请选择服务提供商"),style:{width:"100%"}
1,initValue:l.sms_provider,onChange:e=>{r(t=>({...t,sms_provider:e}))},children:[n.jsx(a.Select.Option,{value:"tencent",children:e("腾讯云短信")}),n.jsx(a.Select.Option,{value:"aliyun",children:e("阿里云短信")}),n.jsx(a.Select.Option,{value:"xuanwu",children:e("玄武云MOS短信")})]})}),"xuanwu"!==l.sms_provider&&n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_region",label:e("服务区域"),placeholder:"ap-guangzhou",extraText:e("腾讯云默认 ap-guangzhou,阿里云默认 cn-hangzhou"),onChange:x("sms_region"),showClear:!0})}),"xuanwu"===l.sms_provider&&n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_mos_endpoint",label:e("接入地址"),placeholder:"https://ns.mosapi.cn:9100",extraText:e("默认 https://ns.mosapi.cn:9100,一般无需修改"),initValue:l.sms_mos_endpoint,onChange:x("sms_mos_endpoint"),showClear:!0})})]}),"xuanwu"!==l.sms_provider&&n.jsxs(n.Fragment,{children:[n.jsxs(o,{gutter:16,style:{marginTop:8},children:[n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_secret_id",label:e("Secret ID"),autoComplete:"off",placeholder:u.sms_secret_id?e("已配置(输入新值以更新)"):e("请输入 Secret ID / AccessKey ID"),onChange:x("sms_secret_id"),showClear:!0})}),n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_secret_key",label:e("Secret Key"),autoComplete:"new-password",type:"password",placeholder:u.sms_secret_key?e("已配置(输入新值以更新)"):e("请输入 Secret Key / AccessKey Secret"),onChange:x("sms_secret_key"),showClear:!0})})]}),n.jsxs(o,{gutter:16,style:{marginTop:8},children:[n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_sdk_app_id",label:e("SDK App ID"),placeholder:"1400xxxxxx",extraText:e("腾讯云专用,在短信控制台应用列表获取"),onChange:x("sms_sdk_app_id"),showClear:!0})}),n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_sign_name",label:e("短信签名"),placeholder:e("请输入短信签名"),onChange:x("sms_sign_name"),showClear:!0})}),n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_template_id",label:e("模板 ID"),placeholder:"123456",extraText:e("模板示例:您的验证码是{1},{2}分钟内有效"),onChange:x("sms_template_id"),showClear:!0})})]})]}),"xuanwu"===l.sms_provider&&n.jsxs(n.Fragment,{children:[n.jsxs(o,{gutter:16,style:{marginTop:8},children:[n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_mos_username",label:e("MOS 账号"),autoComplete:"off",placeholder:e("请输入玄武云 MOS 账号"),initValue:l.sms_mos_username,onChange:x("sms_mos_username"),showClear:!0})}),n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_mos_password",label:e("MOS 密码"),autoComplete:"new-password",type:"password",placeholder:u.sms_mos_password?e("已配置(输入新值以更新)"):e("请输入玄武云 MOS 密码"),onChange:x("sms_mos_password"),showClear:!0})}),n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_mos_signature",label:e("短信签名"),placeholder:e("如:玄武科技"),extraText:e("会自动拼接到内容开头,无需写进内容模板"),initValue:l.sms_mos_signature,onChange:x("sms_mos_signature"),showClear:!0})})]}),n.jsxs(o,{gutter:16,style:{marginTop:8},children:[n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.Input,{field:"sms_mos_biz_type",label:e("业务类型 ID(bizType,可选)"),placeholder:"100",initValue:l.sms_mos_biz_type,onChange:x("sms_mos_biz_type"),showClear:!0})}),n.jsx(c,{xs:24,sm:24,md:16,children:n.jsx(a.Input,{field:"sms_mos_content_template",label:e("验证码内容模板"),placeholder:"您的验证码为{code},{expire}分钟内有效,请勿泄露。",extraText:e("占位符 {code} 为验证码,{expire} 为有效期分钟数;必须包含 {code}"),initValue:l.sms_mos_content_template,onChange:x("sms_mos_content_template"),showClear:!0})})]})]})]}),n.jsx(a.Section,{text:e("频率控制"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.InputNumber,{field:"sms_code_expire_minutes",label:e("验证码有效期(分钟)"),placeholder:"5",min:1,max:30,initValue:l.sms_code_expire_minutes,onChange:e=>{r(t=>({...t,sms_code_expire_minutes:e}))},style:{width:"100%"}})}),n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.InputNumber,{field:"sms_rate_limit_minutes",label:e("频率限制周期(分钟)"),placeholder:"1",min:1,max:60,initValue:l.sms_rate_limit_minutes,onChange:e=>{r(t=>({...t,sms_rate_limit_minutes:e}))},style:{width:"100%"}})}),n.jsx(c,{xs:24,sm:12,md:8,children:n.jsx(a.InputNumber,{field:"sms_rate_limit_count",label:e("周期内最大发送次数"),placeholder:"1",min:1,max:10,initValue:l.sms_rate_limit_count,onChange:e=>{r(t=>({...t,sms_rate_limit_count:e}))},style:{width:"100%"}})})]})}),n.jsx(o,{style:{marginTop:8},children:n.jsx(c,{children:n.jsx(d,{type:"primary",onClick:()=>{s(!0);const t={...l};t.sms_secret_id||delete t.sms_secret_id,t.sms_secret_key||delete t.sms_secret_key,t.sms_mos_password||delete t.sms_mos_password,ye.post("/api/option/updateagentoption",t).then(t=>{const{success:n,message:i}=t.data;n?(be(e("保存成功")),p(structuredClone(l))):je(i||e("保存失败"))}).catch(t=>{je(t.message||e("保存失败,请重试"))}).finally(()=>{s(!1)})},loading:i,children:e("保存短信设置")})})})]})})},{Text:Ys}=u,Zs="https://meiye.clife.cn/v1/homing/auth/oauth2/token",el="https://homing.clife.cn/v1/homing/open/api/user/getUserinfo",tl=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,u]=t.useState(!1),[p,x]=t.useState(!1),[g,j]=t.useState({hongming_sso_enabled:!1,hongming_app_key:"",hongming_app_secret:"",hongming_token_url:Zs,hongming_user_info_url:el,hongming_register_api_key:""}),[f,b]=t.useState(null);t.useEffect(()=>{(async()=>{s(!0);try{const e=await ye.get("/api/option/getagentoptions"),{success:t,message:n,data:i}=e.data;t?j(e=>({...e,hongming_sso_enabled:!!i.hongming_sso_enabled,hongming_app_key:i.hongming_app_key||"",hongming_app_secret:i.hongming_app_secret||"",hongming_token_url:i.hongming_token_url||Zs,hongming_user_info_url:i.hongming_user_info_url||el,hongming_register_api_key:i.hongming_register_api_key||""})):je(n)}catch(e){je(e.message)}finally{s(!1)}})()},[]);const _=async e=>{try{await navigator.clipboard.writeText(e),y.success({content:"已复制",duration:2})}catch{y.error({content:"复制失败,请手动复制",duration:3})}},S=`${window.location.origin}/oauth/hongming`;return n.jsx(m,{spinning:i,children:n.jsxs(a,{style:{marginBottom:15},children:[n.jsx(a.Section,{text:"单点登录接入说明",children:n.jsx(h,{type:"info",description:n.jsxs("div",{children:[n.jsx("div",{style:{marginBottom:8,fontWeight:500},children:"登录流程"}),n.jsxs("ol",{style:{margin:"0 0 12px 0",paddingLeft:20,lineHeight:"1.8"},children:[n.jsxs("li",{children:["用户在鸿溟业务系统点击登录,鸿溟平台生成 ",n.jsx("code",{children:"auth_code"})]}),n.jsxs("li",{children:["鸿溟平台将用户重定向至本站回调地址,携带 ",n.jsx("code",{children:"auth_code"})," 参数"]}),n.jsxs("li",{children:["本站后端用 ",n.jsx("code",{children:"auth_code"}
1)," 向鸿溟换取用户 ",n.jsx("code",{children:"orgId"}),",完成登录"]})]}),n.jsx("div",{style:{marginBottom:6,fontWeight:500},children:"需在鸿溟平台配置的回调地址"}),n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[n.jsx("code",{style:{background:"#f5f5f5",padding:"6px 12px",borderRadius:4,fontSize:13,flex:1,wordBreak:"break-all"},children:S}),n.jsx(d,{size:"small",icon:n.jsx(yt,{size:16}),onClick:()=>_(S)})]}),n.jsxs("div",{style:{marginTop:8,fontSize:12,color:"#888"},children:["鸿溟平台实际跳转示例:",n.jsxs("code",{children:[S,"?auth_code=xxxxxx"]})]})]}),style:{marginBottom:0}})}),n.jsxs(a.Section,{text:"鸿溟平台配置",children:[n.jsx(o,{gutter:16,children:n.jsx(c,{span:24,children:n.jsx(a.Slot,{label:{text:"启用鸿溟SSO"},children:n.jsx(E,{checked:g.hongming_sso_enabled,onChange:e=>j(t=>({...t,hongming_sso_enabled:e})),checkedText:"开",uncheckedText:"关"})})})}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,children:n.jsx(a.Slot,{label:{text:"AppKey(client_id)"},children:n.jsx(k,{value:g.hongming_app_key,onChange:e=>j(t=>({...t,hongming_app_key:e})),placeholder:"请输入鸿溟平台 AppKey",showClear:!0})})}),n.jsx(c,{xs:24,sm:12,children:n.jsx(a.Slot,{label:{text:"AppSecret"},children:n.jsx(k,{value:g.hongming_app_secret,onChange:e=>j(t=>({...t,hongming_app_secret:e})),placeholder:"请输入鸿溟平台 AppSecret",mode:"password",showClear:!0})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,children:n.jsx(a.Slot,{label:{text:"Token 接口地址"},children:n.jsx(k,{value:g.hongming_token_url,onChange:e=>j(t=>({...t,hongming_token_url:e})),placeholder:Zs,showClear:!0})})}),n.jsx(c,{xs:24,sm:12,children:n.jsx(a.Slot,{label:{text:"getUserInfo 接口地址"},children:n.jsx(k,{value:g.hongming_user_info_url,onChange:e=>j(t=>({...t,hongming_user_info_url:e})),placeholder:el,showClear:!0})})})]}),n.jsx(d,{type:"primary",loading:l,onClick:async()=>{u(!0);try{const t=await ye.post("/api/option/updateagentoption",{hongming_sso_enabled:g.hongming_sso_enabled,hongming_app_key:g.hongming_app_key,hongming_app_secret:g.hongming_app_secret,hongming_token_url:g.hongming_token_url,hongming_user_info_url:g.hongming_user_info_url}),{success:n,message:i}=t.data;n?be(e("保存成功")):je(i)}catch(t){je(t.message)}finally{u(!1)}},style:{marginTop:8},children:"保存鸿溟平台配置"})]}),n.jsxs(a.Section,{text:"注册 API 凭据",children:[n.jsx(h,{type:"info",description:n.jsxs("div",{children:[n.jsx("div",{style:{marginBottom:8},children:"鸿溟业务系统调用以下接口向本站注册用户:"}),n.jsxs("div",{style:{fontFamily:"monospace",background:"#f5f5f5",padding:"8px 12px",borderRadius:6,fontSize:13},children:["POST ",window.location.origin,"/api/sso/hongming/register"]}),n.jsxs("div",{style:{marginTop:8,fontSize:12,color:"#666"},children:["请求头:",n.jsx("code",{children:"X-Api-Key"})," 和 ",n.jsx("code",{children:"X-Api-Secret"}),n.jsx("br",{}),"请求体:",n.jsx("code",{children:"org_id"}),"(必填,鸿溟平台的 orgId)"]})]}),style:{marginBottom:16}}),n.jsxs(o,{gutter:16,style:{alignItems:"center"},children:[n.jsx(c,{xs:24,sm:16,children:n.jsx(a.Slot,{label:{text:"当前 Api Key"},children:n.jsx(k,{value:g.hongming_register_api_key,placeholder:"尚未生成",disabled:!0,suffix:g.hongming_register_api_key?n.jsx(yt,{size:16,style:{cursor:"pointer"},onClick:()=>_(g.hongming_register_api_key)}):null})})}),n.jsx(c,{xs:24,sm:8,children:n.jsx("div",{style:{paddingTop:28},children:n.jsx(d,{icon:n.jsx(et,{size:16}),loading:p,onClick:async()=>{if(g.hongming_sso_enabled){x(!0);try{const e=await ye.post("/api/oauth/hongming/credentials"),{success:t,message:n,data:i}=e.data;t?(b(i),j(e=>({...e,hongming_register_api_key:i.api_key})),y.success({content:"凭据生成成功,请立即保存 api_secret!",duration:6})):je(n)}catch(e){je(e.message)}finally{x(!1)}}else y.warning({content:"请先启用鸿溟SSO",duration:3})},type:"secondary",children:"生成注册凭据"})})})]}),f&&n.jsxs(r,{style:{marginTop:16,border:"1px solid #faad14",background:"#fffbe6"}
1,title:"⚠️ 请立即保存以下凭据,Api Secret 仅显示一次",children:[n.jsxs("div",{style:{marginBottom:12},children:[n.jsx(Ys,{strong:!0,children:"Api Key:"}),n.jsx(Ys,{code:!0,style:{marginLeft:8,marginRight:8},children:f.api_key}),n.jsx(d,{size:"small",icon:n.jsx(yt,{size:16}),onClick:()=>_(f.api_key)})]}),n.jsxs("div",{children:[n.jsx(Ys,{strong:!0,children:"Api Secret:"}),n.jsx(Ys,{code:!0,style:{marginLeft:8,marginRight:8},children:f.api_secret}),n.jsx(d,{size:"small",icon:n.jsx(yt,{size:16}),onClick:()=>_(f.api_secret)})]})]})]})]})})},{Text:nl}=u,il=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,r]=t.useState({enabled_menus:"",agent_announcements:"",agent_api_info:"",agent_faq:"",agent_domain:"",github_oauth_enabled:!1,github_client_id:"",github_client_secret:"",linuxdo_oauth_enabled:!1,linuxdo_client_id:"",linuxdo_client_secret:"",telegram_oauth_enabled:!1,wechat_auth_enabled:!1,wechat_server_address:"",wechat_server_token:"",wechat_account_qrcode_image_url:"",turnstile_check_enabled:!1,show_hongming_sso_settings:!1}),[o,c]=t.useState(l),d=t.useRef(),[u,p]=t.useState([]),[h,g]=t.useState(!1),[y,j]=t.useState({path:"",title:"",description:"",keywords:""}),[f,S]=t.useState(-1);t.useEffect(()=>{k()},[]);const k=async()=>{try{const e=await ye.get("/api/option/getagentoptions"),{success:t,message:n,data:i}=e.data;if(t){const e={};for(let t in i)Object.keys(l).includes(t)&&(e[t]=i[t]);if(e.github_oauth_enabled=!0===i.github_oauth_enabled,e.linuxdo_oauth_enabled=!0===i.linuxdo_oauth_enabled,e.telegram_oauth_enabled=!0===i.telegram_oauth_enabled,e.wechat_auth_enabled=!0===i.wechat_auth_enabled,e.turnstile_check_enabled=!0===i.turnstile_check_enabled,e.domain_restricted=!0===i.domain_restricted,e.invite_reward_enabled=!0===i.invite_reward_enabled,e.checkin_enabled=!0===i.checkin_enabled,e.invite_reward_rate=i.invite_reward_rate||10,r(e),c(structuredClone(e)),d.current){const t={...e,enabled_menus:e.enabled_menus?e.enabled_menus.split(","):[]};d.current.setValues(t)}}else je(n)}catch(e){je(e.message)}};t.useEffect(()=>{if(l&&l.seo_page_configs)try{const e=JSON.parse(l.seo_page_configs||"[]");p(e)}catch(e){p([])}},[l]);const v=(e,t)=>{j({...y,[e]:t})};return n.jsxs(m,{spinning:i,children:[n.jsx(le,{style:{padding:"24px"},children:n.jsxs(b,{type:"line",style:{marginBottom:"20px"},children:[n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(it,{size:16,style:{marginRight:8}}),e("基础设置")]}),itemKey:"basic",children:n.jsx(cs,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(ft,{size:16,style:{marginRight:8}}),e("货币和定价")]}),itemKey:"pricing",children:n.jsx(Ds,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(bt,{size:16,style:{marginRight:8}}),e("SEO设置")]}),itemKey:"seo",children:n.jsx(us,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(_t,{size:16,style:{marginRight:8}}),e("联系方式")]}),itemKey:"contact",children:n.jsx(Es,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(_t,{size:16,style:{marginRight:8}}),e("SMTP设置")]}),itemKey:"smtp",children:n.jsx(Rs,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(St,{size:16,style:{marginRight:8}}),e("快捷登录设置")]}),itemKey:"oauth",children:n.jsx(Ps,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(_t,{size:16,style:{marginRight:8}}),e("短信设置")]}),itemKey:"sms",children:n.jsx(Xs,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(mt,{size:16,style:{marginRight:8}}),e("用户协议")]}),itemKey:"disclaimer",children:n.jsx(Ns,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(kt,{size:16,style:{marginRight:8}}),e("菜单设置")]}),itemKey:"menu",children:n.jsx(Ms,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(mt,{size:16,style:{marginRight:8}}),e("系统公告")]}),itemKey:"announcements",children:n.jsx(Ws,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(it,{size:16,style:{marginRight:8}}),e("API信息")]}),itemKey:"apiinfo",children:n.jsx(Ks,{})}),n.jsx(_,{tab:n.jsxs("span",{children:[n.jsx(mt,{size:16,style:{marginRight:8}}),e("常见问答")]}),itemKey:"faq",children:n.jsx(Hs,{})}),l.show_hongming_sso_settings&&n.jsx(_,{tab:n.jsxs("span",{children:["🔗 ",e("鸿溟SSO")]}),itemKey:"hongmingsso",children:n.jsx(tl,{})})]})}),n.jsx(x,{title:e(f>=0?"编辑页面SEO":"添加页面SEO"),visible:h,onOk:()=>
1{if(y.path){if(f>=0){const e=[...u];e[f]=y,p(e)}else{if(u.some(e=>e.path===y.path))return void je(e("该页面路径已存在"));p([...u,y])}g(!1)}else je(e("页面路径不能为空"))},onCancel:()=>g(!1),closeOnEsc:!0,width:600,children:h&&n.jsxs(a,{initValues:y,children:[n.jsx(a.Input,{field:"path",label:e("页面路径"),placeholder:e("例如: /chat 或 /chat/* (通配符匹配所有chat子页面)"),onChange:e=>v("path",e),help:e("以/开头的路径。使用*作为通配符可以匹配以相同前缀开头的所有页面"),required:!0}),n.jsx(a.Input,{field:"title",label:e("页面标题"),placeholder:e("页面标题"),onChange:e=>v("title",e),help:e("不需要包含系统名称,系统会自动添加")}),n.jsx(a.TextArea,{field:"description",label:e("页面描述"),placeholder:e("页面描述"),onChange:e=>v("description",e),rows:3}),n.jsx(a.TextArea,{field:"keywords",label:e("页面关键词"),placeholder:e("页面关键词,多个关键词用英文逗号分隔"),onChange:e=>v("keywords",e),rows:3}),n.jsx("div",{style:{marginTop:8},children:n.jsxs(nl,{type:"tertiary",children:[e("当前值"),": ",JSON.stringify(y)]})})]})})]})};function sl(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,p]=t.useState({ImageProxyEnabled:!1,ImageProxyServiceUrl:"",MjImageModeDefault:"origin",MjCustomProxyDefault:"https://mj.zhongzhuan.chat"}),[h,x]=t.useState(r),g=t.useRef();return t.useEffect(()=>{const t={};for(let n in e.options)"ImageProxyEnabled"===n?t[n]=!0===e.options[n]:"ImageProxyServiceUrl"===n?t[n]=e.options[n]||"":("MjImageModeDefault"===n||"MjCustomProxyDefault"===n)&&(t[n]=e.options[n]);Object.keys(t).length>0&&(p(t),x(structuredClone(t)),g.current?.setValues(t),setTimeout(()=>{g.current?.setValues(t)},100))},[e.options]),n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>g.current=e,style:{marginBottom:15},initValues:r,children:n.jsxs(a.Section,{text:i("图片代理设置"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{span:8,children:n.jsx(a.Switch,{field:"ImageProxyEnabled",label:i("启用图片代理(防止下游通过图片URL追踪)"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{p({...r,ImageProxyEnabled:e})}})})}),r.ImageProxyEnabled&&n.jsx(o,{gutter:16,children:n.jsxs(c,{span:12,children:[n.jsx(a.Input,{field:"ImageProxyServiceUrl",label:i("图片代理服务地址"),placeholder:i("请输入图片代理服务地址,如: https://your-domain.com"),onChange:e=>{p({...r,ImageProxyServiceUrl:e})}}),n.jsx(u.Text,{type:"secondary",style:{display:"block",marginTop:4},children:i("独立的图片代理服务地址,用于处理通用图片代理请求")})]})}),n.jsx("div",{style:{marginTop:16,borderTop:"1px solid hsl(var(--border))",paddingTop:16},children:n.jsx(u.Text,{strong:!0,style:{marginBottom:8,display:"block"},children:i("Midjourney 图片代理设置 (系统默认)")})}),n.jsx(o,{gutter:16,children:n.jsxs(c,{span:8,children:[n.jsxs(a.Select,{field:"MjImageModeDefault",label:i("图片代理方式"),defaultValue:r.MjImageModeDefault,value:r.MjImageModeDefault,onChange:e=>{p({...r,MjImageModeDefault:e})},children:[n.jsx(a.Select.Option,{value:"origin",children:i("Discord 原链接")}),n.jsx(a.Select.Option,{value:"proxy",children:i("图片代理地址")})]}),!1]})}),"proxy"===r.MjImageModeDefault&&n.jsx(o,{gutter:16,children:n.jsxs(c,{span:12,children:[n.jsx(a.Input,{field:"MjCustomProxyDefault",label:i("自定义图片代理"),placeholder:i("请输入自定义图片代理地址"),onChange:e=>{p({...r,MjCustomProxyDefault:e})}}),n.jsx(u.Text,{type:"secondary",style:{display:"block",marginTop:4},children:i("替换 https://cdn.discordapp.com 的地址,必须以 https,http 开头")})]})}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));l(!0);const n=Se(),s=t.map(e=>ye.put(n,{key:e.key,value:"boolean"==typeof r[e.key]?String(r[e.key]):r[e.key]}));Promise.all(s).then(t=>{if(1===s.length){if(t.includes(void 0))return}else if(s.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存图片代理设置")})})]})})})}function ll(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState([]),[h,x]=t.useState(""),[g,y]=t.useState([]),[j,f]=t.useState(""),[b,_]=t.useState([]),[S,v]=t.useState(""),[C,w]=t.useState({AutoSortChannelEnabled:!1,MinRequestsForSuccessRate:5,ExplorationEpsilon:.1,MinRequestsForPenalty:100,MinSuccessRateThreshold:.05,PenaltyScoreMultiplier:.3,SuccessRateAutoBanEnabled:!1,SuccessRateAutoBanMinRequests:1e3,SuccessRateAutoBanThreshold:.02,MaxRetryDuration:0,DynamicTimeoutEnabled:!1,DynamicTimeoutScope:"retry_only",DynamicTimeoutPercentile:99,DynamicTimeoutMultiplier:1.2,DynamicTimeoutMin:30,DynamicTimeoutMax:600,DynamicTimeoutFallback:0,TimeoutPenaltyMultiplier:.5,TimeoutAutoBanCount:3,ErrorCountWhitelist:"",AutoSortChannelWhitelist:"",Pri
1orityWeight:10,WeightItemWeight:5,SuccessRateWeight:40,SpeedWeight:30,PriceWeight:15,DefaultSuccessRate:1,DefaultSpeedScore:.3,DefaultPriceScore:.5,EnableSigmoidSmoothing:!1,SigmoidPriceSteepness:10,SigmoidPrioritySteepness:10,SigmoidWeightSteepness:8,SigmoidSpeedSteepness:12,SpeedLogNormalization:!0,TimeoutStreakPenaltyRate:.03,ShortTermStatWeight:5,MediumTermStatWeight:3,LongTermStatWeight:2,UltraShortTermPeriod:120,ShortTermPeriod:300,MediumTermPeriod:1800,LongTermPeriod:10800}),[T,I]=t.useState(C),E=t.useRef();function R(){const t=ke(C,T);if(!t.length)return ve(i("你似乎并没有修改什么"));l(!0);const n=Se(),s=t.map(e=>{let t="";if("boolean"==typeof C[e.key])t=String(C[e.key]);else if("ExplorationEpsilon"===e.key){const n=parseFloat(C[e.key]);if(n<0||n>.5)return ve(i("探索概率应在0到0.5之间")),l(!1),null;t=String(n)}else if(["SigmoidPriceSteepness","SigmoidPrioritySteepness","SigmoidWeightSteepness","SigmoidSpeedSteepness"].includes(e.key)){const n=parseFloat(C[e.key]);if(n<4||n>20)return ve(i("Sigmoid 陡峭度应在4到20之间")),l(!1),null;t=String(n)}else if(["UltraShortTermPeriod","ShortTermPeriod","MediumTermPeriod","LongTermPeriod","MinRequestsForSuccessRate","MaxRetryDuration","DynamicTimeoutMin","DynamicTimeoutMax","DynamicTimeoutFallback","TimeoutAutoBanCount","SuccessRateAutoBanMinRequests"].includes(e.key)){const n=parseInt(C[e.key]);if(t=String(n),"UltraShortTermPeriod"===e.key&&(n<30||n>600))return ve(i("超短期统计时间应在30秒到600秒之间")),l(!1),null;if("ShortTermPeriod"===e.key&&(n<60||n>3600))return ve(i("短期统计时间应在60秒到3600秒之间")),l(!1),null;if("MediumTermPeriod"===e.key&&(n<600||n>7200))return ve(i("中期统计时间应在600秒到7200秒之间")),l(!1),null;if("LongTermPeriod"===e.key&&(n<3600||n>86400))return ve(i("长期统计时间应在3600秒到86400秒之间")),l(!1),null}else t=String(C[e.key]);return ye.put(n,{key:e.key,value:t})}).filter(e=>null!==e);0!==s.length?Promise.all(s).then(t=>{if(1===s.length){if(t.includes(void 0))return}else if(s.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)}):l(!1)}function P(){const e=parseFloat(C.PriorityWeight)+parseFloat(C.WeightItemWeight)+parseFloat(C.SuccessRateWeight)+parseFloat(C.SpeedWeight)+parseFloat(C.PriceWeight);return Math.abs(e-100)<.1}const z=()=>{const e=h.trim();e&&!r.includes(e)&&(u([...r,e]),x(""))},N=()=>{const e=j.trim();e&&!g.includes(e)&&(y([...g,e]),f(""))},A=()=>{const e=S.trim();e&&!b.includes(e)&&(_([...b,e]),v(""))};return t.useEffect(()=>{const t={AutoSortChannelEnabled:!1,MinRequestsForSuccessRate:5,ExplorationEpsilon:.1,MinRequestsForPenalty:100,MinSuccessRateThreshold:.05,PenaltyScoreMultiplier:.3,SuccessRateAutoBanEnabled:!1,SuccessRateAutoBanMinRequests:1e3,SuccessRateAutoBanThreshold:.02,MaxRetryDuration:0,DynamicTimeoutEnabled:!1,DynamicTimeoutScope:"retry_only",DynamicTimeoutPercentile:99,DynamicTimeoutMultiplier:1.2,DynamicTimeoutMin:30,DynamicTimeoutMax:600,DynamicTimeoutFallback:0,TimeoutPenaltyMultiplier:.5,TimeoutAutoBanCount:3,ErrorCountWhitelist:"",AutoSortChannelWhitelist:"",PriorityWeight:10,WeightItemWeight:5,SuccessRateWeight:40,SpeedWeight:30,PriceWeight:15,DefaultSuccessRate:1,DefaultSpeedScore:.3,DefaultPriceScore:.5,EnableSigmoidSmoothing:!1,SigmoidPriceSteepness:10,SigmoidPrioritySteepness:10,SigmoidWeightSteepness:8,SigmoidSpeedSteepness:12,SpeedLogNormalization:!0,TimeoutStreakPenaltyRate:.03,ShortTermStatWeight:5,MediumTermStatWeight:3,LongTermStatWeight:2,UltraShortTermPeriod:120,ShortTermPeriod:300,MediumTermPeriod:1800,LongTermPeriod:10800},n={...t};for(let i in e.options)t.hasOwnProperty(i)&&(["AutoSortChannelEnabled","EnableSigmoidSmoothing","DynamicTimeoutEnabled","SpeedLogNormalization","SuccessRateAutoBanEnabled"].includes(i)?n[i]=!0===e.options[i]||"true"===e.options[i]:["MinRequestsForSuccessRate","MinRequestsForPenalty","UltraShortTermPeriod","ShortTermPeriod","MediumTermPeriod","LongTermPeriod","MaxRetryDuration","DynamicTimeoutMin","DynamicTimeoutMax","DynamicTimeoutFallback","TimeoutAutoBanCount","SuccessRateAutoBanMinRequests"].includes(i)?n[i]=parseInt(e.options[i]):n[i]="DynamicTimeoutScope"===i?e.options[i]||"retry_only":"ErrorCountWhitelist"===i||"AutoSortChannelWhitelist"===i?e.options[i]||"":parseFloat(e.options[i]));if(w(n),I(structuredClone(n)),E.current?.setValues(n),e.options.ErrorCountWhitelist){const t=e.options.ErrorCountWhitelist.split(/[\n,]/).map(e=>e.trim()).filter(e=>e);u(t)}else u([]);if(e.options.AutoSortChannelWhitelist){const t=e.options.AutoSortChannelWhitelist.split(/[\n,]/).map(e=>e.trim()).filter(e=>e);y(t)}else y([]);if(e.options.DynamicTimeoutModels){const t=e.options.DynamicTimeoutModels.split(/[\n,]/).map(e=>e.trim()).filter(e=>e);_(t)}else _([])},[e.options]),n.jsx(m,{spinning:s,children:n.jsxs(a,{values:C,getFormApi:e=>E.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:i("渠道智能排序设置"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{span:8,children:n.jsx(a.Switch,{field:"AutoSortChannelEnabled",label:i("启用渠道智能排序(自动选择性能最佳渠道)"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{w({...C,AutoSortChannelEnabled:e})}})})}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("最小请求数阈值"),step:1,min:1,max:100,suffix:i("次"),extraText:i("计算成功率所需的最小请求数,低于此值的渠道不考虑成功率"),field:"MinRequestsForSuccessRate",onCh
1ange:e=>w({...C,MinRequestsForSuccessRate:e})})}),n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("探索概率 (Epsilon)"),step:.01,min:0,max:.5,precision:2,extraText:i("数据不足渠道的随机探索概率(推荐: 0.05-0.15),用于冷启动"),field:"ExplorationEpsilon",onChange:e=>w({...C,ExplorationEpsilon:e})})}),n.jsx(c,{span:8,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",marginTop:"24px",backgroundColor:"#f6f7f9"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:"💡 探索概率说明"}),n.jsxs("div",{style:{fontSize:"12px",color:"#666"},children:["• ",n.jsx("strong",{children:"0.05-0.10"}),": 谨慎探索(推荐)",n.jsx("br",{}),"• ",n.jsx("strong",{children:"0.10-0.15"}),": 积极探索",n.jsx("br",{}),"• ",n.jsx("strong",{children:"0.0"}),": 关闭探索(不推荐)"]})]})})]}),n.jsxs(a.Section,{text:i("渠道惩罚机制配置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("惩罚最小请求数"),step:10,min:50,max:1e3,suffix:i("次"),extraText:i("触发惩罚机制所需的最小请求数(长期统计),建议100"),field:"MinRequestsForPenalty",onChange:e=>w({...C,MinRequestsForPenalty:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("最低成功率阈值"),step:.01,min:0,max:.5,precision:2,extraText:i("低于此成功率的渠道将被严厉惩罚(推荐: 0.05即5%)"),field:"MinSuccessRateThreshold",onChange:e=>w({...C,MinSuccessRateThreshold:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("惩罚得分倍率"),step:.05,min:.1,max:1,precision:2,extraText:i("被惩罚渠道的总分将乘以此倍率(推荐: 0.3即打3折)"),field:"PenaltyScoreMultiplier",onChange:e=>w({...C,PenaltyScoreMultiplier:e})})}),n.jsx(c,{span:6,children:n.jsx(a.Switch,{label:i("低成功率自动禁用模型"),field:"SuccessRateAutoBanEnabled",extraText:i("满足下方条件时自动临时禁用该渠道的该模型(不影响其他模型),反复触发将延长禁用时间(30分钟→1h→2h→...→24h),探活成功自动恢复"),onChange:e=>w({...C,SuccessRateAutoBanEnabled:e})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("自动禁用最小请求数"),step:100,min:100,max:1e4,suffix:i("次"),extraText:i("触发自动禁用所需的最小请求数(长期统计),建议1000"),field:"SuccessRateAutoBanMinRequests",disabled:!C.SuccessRateAutoBanEnabled,onChange:e=>w({...C,SuccessRateAutoBanMinRequests:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("自动禁用成功率阈值"),step:.01,min:0,max:.2,precision:2,extraText:i("低于此成功率将自动禁用该模型(推荐: 0.02即2%)"),field:"SuccessRateAutoBanThreshold",disabled:!C.SuccessRateAutoBanEnabled,onChange:e=>w({...C,SuccessRateAutoBanThreshold:e})})})]})]}),n.jsxs(a.Section,{text:i("动态超时与渠道超时惩罚"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("总重试时间预算(秒)"),step:10,min:0,max:600,suffix:i("秒"),extraText:i("所有重试的总时间上限(0=不限制)"),field:"MaxRetryDuration",onChange:e=>w({...C,MaxRetryDuration:e})})}),n.jsx(c,{span:6,children:n.jsx(a.Switch,{field:"DynamicTimeoutEnabled",label:i("启用动态超时(基于模型P99统计)"),size:"default",checkedText:"|",uncheckedText:"O",onChange:e=>{w({...C,DynamicTimeoutEnabled:e})}})}),n.jsx(c,{span:6,children:n.jsxs(a.Select,{field:"DynamicTimeoutScope",label:i("动态超时应用范围"),disabled:!C.DynamicTimeoutEnabled,onChange:e=>w({...C,DynamicTimeoutScope:e}),children:[n.jsx(a.Select.Option,{value:"retry_only",children:i("仅重试请求")}),n.jsx(a.Select.Option,{value:"all",children:i("所有请求")})]})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("统计百分位数"),step:.5,min:90,max:99.9,precision:1,extraText:i("使用的百分位数(推荐99即P99)"),field:"DynamicTimeoutPercentile",disabled:!C.DynamicTimeoutEnabled,onChange:e=>w({...C,DynamicTimeoutPercentile:e})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("超时安全系数"),step:.1,min:1,max:3,precision:1,extraText:i("P99乘以此系数作为超时阈值(推荐1.2)"),field:"DynamicTimeoutMultiplier",disabled:!C.DynamicTimeoutEnabled,onChange:e=>w({...C,DynamicTimeoutMultiplier:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("最小超时(秒)"),step:5,min:5,max:300,suffix:i("秒"),extraText:i("动态超时的下限(推荐30秒)"),field:"DynamicTimeoutMin",disabled:!C.DynamicTimeoutEnabled,onChange:e=>w({...C,DynamicTimeoutMin:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("最大超时(秒)"),step:30,min:60,max:1e5,suffix:i("秒"),extraText:i("动态超时的上限(推荐600秒)"),field:"DynamicTimeoutMax",disabled:!C.DynamicTimeoutEnabled,onChange:e=>w({...C,DynamicTimeoutMax:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("无数据时默认超时(秒)"),step:10,min:0,max:600,suffix:i("秒"),extraText:i("模型无统计数据时的超时(0=不限制)"),field:"DynamicTimeoutFallback",disabled:!C.DynamicTimeoutEnabled,onChange:e=>w({...C,DynamicTimeoutFallback:e})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("超时惩罚倍率"),step:.
105,min:.1,max:1,precision:2,extraText:i("超时渠道评分乘以此倍率(推荐0.5)"),field:"TimeoutPenaltyMultiplier",disabled:!C.DynamicTimeoutEnabled,onChange:e=>w({...C,TimeoutPenaltyMultiplier:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("连续超时禁用阈值"),step:1,min:1,max:20,suffix:i("次"),extraText:i("同一模型连续超时N次临时禁用该渠道的该模型(不影响其他模型),反复触发将自动延长:30分钟→1h→2h→4h→8h→24h"),field:"TimeoutAutoBanCount",disabled:!C.DynamicTimeoutEnabled,onChange:e=>w({...C,TimeoutAutoBanCount:e})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("实时超时降权比例"),step:.01,min:0,max:.5,precision:2,extraText:i("每次连续超时实时降低的得分比例,绕过缓存立即生效(0.03=每次降3%)"),field:"TimeoutStreakPenaltyRate",disabled:!C.DynamicTimeoutEnabled,onChange:e=>w({...C,TimeoutStreakPenaltyRate:e})})}),n.jsx(c,{span:12,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",marginTop:"24px",backgroundColor:"#f0f9ff"},children:[n.jsxs("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:["* ",i("动态超时说明")]}),n.jsxs("div",{style:{fontSize:"12px",color:"#666"},children:[i("根据每个模型历史请求的有效等待时间统计值,自动计算超时阈值"),n.jsx("br",{}),"* ",n.jsx("strong",{children:i("流式")}),": ",i("统计首字时间(TTFT),限制等待响应头阶段(ResponseHeaderTimeout),不影响流数据传输"),n.jsx("br",{}),"* ",n.jsx("strong",{children:i("非流式")}),": ",i("统计总响应时间,限制整个请求周期(Client.Timeout)"),n.jsx("br",{}),"* ",i("超时的渠道会被降权,连续超时会自动禁用,减少上游计费损失")]})]})})]}),n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("指定启用动态超时的模型")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("留空表示所有模型都启用动态超时, 支持通配符(如 gemini-*)")})]}),n.jsx(p,{value:b,onChange:_,placeholder:i("输入模型名称后回车"),style:{width:"100%"},disabled:!C.DynamicTimeoutEnabled})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("添加模型")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("输入后点击添加或按回车, 支持 * 后缀通配符")})]}),n.jsx(k,{placeholder:i("如: gemini-3-pro-image-preview 或 gemini-*"),value:S,onChange:e=>v(e),disabled:!C.DynamicTimeoutEnabled,suffix:n.jsx(d,{onClick:A,disabled:!C.DynamicTimeoutEnabled,children:i("添加")}),onEnterPress:A})]})]}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async()=>{l(!0);try{const t=Se(),n=b.join("\n");await ye.put(t,{key:"DynamicTimeoutModels",value:n}),be(i("保存成功")),e.refresh()}catch(t){je(i("保存失败,请重试"))}finally{l(!1)}},disabled:!C.DynamicTimeoutEnabled,children:i("保存动态超时模型列表")})})]}),n.jsx(o,{style:{marginTop:16,marginBottom:24},children:n.jsx(d,{size:"default",onClick:R,children:i("保存渠道排序设置")})}),n.jsxs(a.Section,{text:i("智能排序白名单配置"),children:[n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("已添加的白名单分组")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("点击标签可删除该项")})]}),n.jsx(p,{value:g,onChange:y,placeholder:i("输入分组名称后回车"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("添加新的白名单分组")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("输入后点击添加按钮或按回车")})]}),n.jsx(k,{placeholder:i("输入分组名称(如:Claude Code专属)"),value:j,onChange:e=>f(e),suffix:n.jsx(d,{onClick:N,children:i("添加")}),onEnterPress:N})]})]}),n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",backgroundColor:"#fff7e6"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:"💡 智能排序白名单说明"}),n.jsxs("div",{style:{fontSize:"12px",color:"#666"},children:["• 在白名单中的分组将",n.jsx("strong",{children:"跳过智能排序"}),",直接按照",n.jsx("strong",{children:"优先级和权重"}),"选择渠道",n.jsx("br",{}),"• 适用场景:需要固定路由策略的分组、不希望受统计数据影响的专用分ç
1»„",n.jsx("br",{}),"• 常见示例:",n.jsx("code",{children:"Claude Code专属"}),"、",n.jsx("code",{children:"Codex专属"}),"、",n.jsx("code",{children:"特殊模型专用"}),n.jsx("br",{}),"• 注意:分组名称必须与渠道配置中的分组名称",n.jsx("strong",{children:"完全一致"}),"(区分大小写)"]})]})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async()=>{if(Array.isArray(g)){l(!0);try{const t=Se(),n=g.join("\n");await ye.put(t,{key:"AutoSortChannelWhitelist",value:n}),be(i("保存成功")),e.refresh()}catch(t){je(i("保存失败,请重试"))}finally{l(!1)}}else je(i("智能排序白名单格式不正确"))},children:i("保存智能排序白名单")})})]}),n.jsxs(a.Section,{text:i("错误计数白名单配置"),children:[n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("已添加的白名单项")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("点击标签可删除该项")})]}),n.jsx(p,{value:r,onChange:u,placeholder:i("输入错误码或错误消息关键词后回车"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("添加新的白名单项")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("输入后点击添加按钮或按回车")})]}),n.jsx(k,{placeholder:i("输入错误码或错误消息关键词"),value:h,onChange:e=>x(e),suffix:n.jsx(d,{onClick:z,children:i("添加")}),onEnterPress:z})]})]}),n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",backgroundColor:"#f0f9ff"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:"💡 白名单说明"}),n.jsxs("div",{style:{fontSize:"12px",color:"#666"},children:["• 当请求失败时,如果错误码或错误消息",n.jsx("strong",{children:"包含"}),"白名单中的任何一项,则不会记录为渠道失败",n.jsx("br",{}),"• 适用场景:用户请求体问题、配额不足等非渠道原因导致的失败",n.jsx("br",{}),"• 常见示例:",n.jsx("code",{children:"invalid_request_error"}),"、",n.jsx("code",{children:"insufficient_quota"}),"、",n.jsx("code",{children:"content_filter"}),"、",n.jsx("code",{children:"rate_limit_exceeded"})]})]})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async()=>{if(Array.isArray(r)){l(!0);try{const t=Se(),n=r.join("\n");await ye.put(t,{key:"ErrorCountWhitelist",value:n}),be(i("保存成功")),e.refresh()}catch(t){je(i("保存失败,请重试"))}finally{l(!1)}}else je(i("错误计数白名单格式不正确"))},children:i("保存错误计数白名单")})})]})]}),n.jsxs(a.Section,{text:i("统一权重系统(所有权重总和应为100%)"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("优先级权重"),step:1,min:0,max:50,precision:1,suffix:"%",extraText:i("渠道优先级在最终得分中的权重"),field:"PriorityWeight",onCh
1ange:e=>w({...C,PriorityWeight:e})})}),n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("权重项权重"),step:1,min:0,max:50,precision:1,suffix:"%",extraText:i("渠道权重项在最终得分中的权重"),field:"WeightItemWeight",onChange:e=>w({...C,WeightItemWeight:e})})}),n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("成功率权重"),step:1,min:0,max:100,precision:1,suffix:"%",extraText:i("成功率在最终得分中的权重"),field:"SuccessRateWeight",onChange:e=>w({...C,SuccessRateWeight:e})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("速度权重"),step:1,min:0,max:50,precision:1,suffix:"%",extraText:i("速度在最终得分中的权重"),field:"SpeedWeight",onChange:e=>w({...C,SpeedWeight:e})})}),n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("价格权重"),step:1,min:0,max:50,precision:1,suffix:"%",extraText:i("价格在最终得分中的权重(价格越低得分越高)"),field:"PriceWeight",onChange:e=>w({...C,PriceWeight:e})})}),n.jsx(c,{span:8,children:n.jsxs("div",{style:{padding:"10px",border:P()?"1px solid #52c41a":"1px solid #ff4d4f",borderRadius:"4px",marginTop:"24px"},children:[n.jsxs("div",{style:{fontWeight:"bold"},children:["权重总和:",(parseFloat(C.PriorityWeight)+parseFloat(C.WeightItemWeight)+parseFloat(C.SuccessRateWeight)+parseFloat(C.SpeedWeight)+parseFloat(C.PriceWeight)).toFixed(1),"%"]}),n.jsx("div",{style:{color:P()?"#52c41a":"#ff4d4f"},children:P()?"✓ 权重总和正确":"✗ 权重总和应为100%"})]})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("默认成功率"),step:.1,min:0,max:1,precision:2,extraText:i("无数据渠道的默认成功率(0-1)"),field:"DefaultSuccessRate",onCh
1ange:e=>w({...C,DefaultSuccessRate:e})})}),n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("默认速度得分"),step:.1,min:0,max:1,precision:2,extraText:i("无数据渠道的默认速度得分(0-1)"),field:"DefaultSpeedScore",onChange:e=>w({...C,DefaultSpeedScore:e})})}),n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("默认价格得分"),step:.1,min:0,max:1,precision:2,extraText:i("无数据渠道的默认价格得分(0-1)"),field:"DefaultPriceScore",onChange:e=>w({...C,DefaultPriceScore:e})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:R,children:i("保存统一权重系统设置")})})]}),n.jsxs(a.Section,{text:i("归一化策略设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:12,children:n.jsx(a.Switch,{label:i("速度对数归一化"),field:"SpeedLogNormalization",extraText:i("使用 log(1+speed)/log(1+maxSpeed) 归一化速度得分,减缓速度边际递减效应(推荐开启)"),onChange:e=>w({...C,SpeedLogNormalization:e})})}),n.jsx(c,{span:12,children:n.jsx(a.Switch,{label:i("启用 Sigmoid 平滑"),field:"EnableSigmoidSmoothing",extraText:i("对权重/优先级/价格使用 Sigmoid 函数归一化(不推荐,默认关闭使用线性归一化)"),onChange:e=>w({...C,EnableSigmoidSmoothing:e})})})]}),C.EnableSigmoidSmoothing&&n.jsxs(n.Fragment,{children:[n.jsx(o,{gutter:16,style:{marginTop:"16px"},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"12px",backgroundColor:"#f6f7f9",borderRadius:"4px",marginBottom:"16px"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"8px"},children:"💡 Sigmoid 陡峭度说明"}),n.jsxs("div",{children:["• ",n.jsx("strong",{children:"陡峭度 6-8"}),": 平缓过渡,接近线性,适合权重项"]}),n.jsxs("div",{children:["• ",n.jsx("strong",{children:"陡峭度 10"}),": 中等陡峭(推荐),平衡平滑与区分度,适合价格和优先级"]}),n.jsxs("div",{children:["• ",n.jsx("strong",{children:"陡峭度 12-15"}),": 陡峭曲线,中间差异明显,适合速度"]}),n.jsx("div",{style:{marginTop:"8px",color:"#666"},children:"• 陡峭度越大,中间区域(0.3-0.7)的差异越明显,边缘越平缓"})]})})}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:12,children:n.jsx(a.InputNumber,{label:i("价格 Sigmoid 陡峭度"),step:.5,min:4,max:20,precision:1,extraText:i("控制价格归一化曲线的陡峭程度(推荐: 8-12)"),field:"SigmoidPriceSteepness",onChange:e=>w({...C,SigmoidPriceSteepness:e})})}),n.jsx(c,{span:12,children:n.jsx(a.InputNumber,{label:i("优先级 Sigmoid 陡峭度"),step:.5,min:4,max:20,precision:1,extraText:i("控制优先级归一化曲线的陡峭程度(推荐: 8-12)"),field:"SigmoidPrioritySteepness",onChange:e=>w({...C,SigmoidPrioritySteepness:e})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:12,children:n.jsx(a.InputNumber,{label:i("权重 Sigmoid 陡峭度"),step:.5,min:4,max:20,precision:1,extraText:i("控制权重归一化曲线的陡峭程度(推荐: 6-10)"),field:"SigmoidWeightSteepness",onChange:e=>w({...C,SigmoidWeightSteepness:e})})}),n.jsx(c,{span:12,children:n.jsx(a.InputNumber,{label:i("速度 Sigmoid 陡峭度"),step:.5,min:4,max:20,precision:1,extraText:i("控制速度归一化曲线的陡峭程度(推荐: 10-15)"),field:"SigmoidSpeedSteepness",onChange:e=>w({...C,SigmoidSpeedSteepness:e})})})]})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:R,children:i("保存 Sigmoid 设置")})})]}),n.jsxs(a.Section,{text:i("统计周期设置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("短期统计权重"),step:.5,min:0,max:50,precision:1,extraText:i("短期统计数据在计算加权平均值时的权重"),field:"ShortTermStatWeight",onChange:e=>w({...C,ShortTermStatWeight:e})})}),n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("中期统计权重"),step:.5,min:0,max:50,precision:1,extraText:i("中期统计数据在计算加权平均值时的权重"),field:"MediumTermStatWeight",onChange:e=>w({...C,MediumTermStatWeight:e})})}),n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("长期统计权重"),step:.5,min:0,max:50,precision:1,extraText:i("长期统计数据在计算加权平均值时的权重"),field:"LongTermStatWeight",onCh
1ange:e=>w({...C,LongTermStatWeight:e})})})]}),n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("超短期判断时间"),step:30,min:30,max:600,suffix:i("秒"),extraText:i("用于判断数据充足的时间窗口,建议120秒(2分钟)"),field:"UltraShortTermPeriod",onChange:e=>w({...C,UltraShortTermPeriod:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("短期统计时间"),step:60,min:60,max:3600,suffix:i("秒"),extraText:i("短期统计的时间范围,建议300秒(5分钟)"),field:"ShortTermPeriod",onChange:e=>w({...C,ShortTermPeriod:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("中期统计时间"),step:300,min:600,max:7200,suffix:i("秒"),extraText:i("中期统计的时间范围,建议1800秒(30分钟)"),field:"MediumTermPeriod",onChange:e=>w({...C,MediumTermPeriod:e})})}),n.jsx(c,{span:6,children:n.jsx(a.InputNumber,{label:i("长期统计时间"),step:600,min:3600,max:86400,suffix:i("秒"),extraText:i("长期统计的时间范围,建议10800秒(3小时)"),field:"LongTermPeriod",onChange:e=>w({...C,LongTermPeriod:e})})})]}),n.jsx(o,{children:n.jsx(d,{size:"default",onClick:R,children:i("保存统计周期设置")})})]})]})})}function al(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState([]),[h,x]=t.useState(""),[g,y]=t.useState({ModelErrorRequestRateLimitEnabled:!1,ModelErrorRequestRateLimitDurationMinutes:0,ModelErrorRequestRateLimitCount:0,ResponseReorderEnabled:!1,ModelIgnoreThinkWhitelist:""}),j=t.useRef(),[f,b]=t.useState(g),_=()=>{const e=h.trim();e&&!r.includes(e)&&(u([...r,e]),x(""))};return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(g).includes(n)&&(n.endsWith("Enabled")?t[n]=!0===e.options[n]:n.includes("Count")||n.includes("Minutes")?t[n]=parseInt(e.options[n]):t[n]=e.options[n]);if(Object.keys(t).length>0&&(y(t),b(structuredClone(t)),j.current?.setValues(t)),e.options.ModelIgnoreThinkWhitelist){const t=e.options.ModelIgnoreThinkWhitelist.split(/[\n,]/).map(e=>e.trim()).filter(e=>e);u(t)}else u([])},[e.options]),n.jsx(m,{spinning:s,children:n.jsxs(a,{values:g,getFormApi:e=>j.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:i("模型请求高级限制"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{span:8,children:n.jsx(a.Switch,{field:"ModelErrorRequestRateLimitEnabled",label:i("启用错误请求速率限制"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{y({...g,ModelErrorRequestRateLimitEnabled:e})}})})}),n.jsx(o,{children:n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("错误请求限制周期"),step:1,min:0,suffix:i("分钟"),extraText:i("错误请求频率限制的周期(分钟)"),field:"ModelErrorRequestRateLimitDurationMinutes",onChange:e=>y({...g,ModelErrorRequestRateLimitDurationMinutes:String(e)})})})}),n.jsx(o,{children:n.jsx(c,{span:8,children:n.jsx(a.InputNumber,{label:i("相同错误请求次数限制"),step:1,min:0,suffix:i("次"),extraText:i("同样的错误请求在周期内允许失败的次数,0代表不限制"),field:"ModelErrorRequestRateLimitCount",onChange:e=>y({...g,ModelErrorRequestRateLimitCount:String(e)})})})}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:8,children:n.jsx(a.Switch,{field:"ResponseReorderEnabled",label:i("启用返回数据强制排序"),size:"default",checkedText:"|",uncheckedText:"〇",extraText:i("开启后系统将对返回的数据进行强制排序"),onChange:e=>{y({...g,ResponseReorderEnabled:e})}})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:function(){const t=ke(g,f);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=Se(),s=t.map(e=>{let t="";return t="boolean"==typeof g[e.key]?String(g[e.key]):g[e.key],ye.put(n,{key:e.key,value:t})});l(!0),Promise.all(s).then(t=>{if(1===s.length){if(t.includes(void 0))return}else if(s.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存高级限制设置")})})]}),n.jsxs(a.Section,{text:i("模型忽略think处理白名单配置"),children:[n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("已添加的白名单模型")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("点击标签可删除该模型")})]}),n.jsx(p,{value:r,onChange:u,placeholder:i("输入模型名后回车添加"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("添加新的白名单模型")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("输入后点击添加按钮或按回车")})]}),n.jsx(k,{placeholder:i("输入模型名,例如:gpt-4o-thinking"),value:h,onChange:e=>x(e),suffix:n.jsx(d,{onClick:_,children:i("添加")}),onEnterPress:_})]})]}),n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",backgroundColor:"#f0f9ff"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:"💡 白名单说明"}),n.jsxs("div",{style:{fontSize:"12px",color:"#666"},children:["• 在此列表中的模型将跳过所有thinking相关后缀的自动去除处理",
1n.jsx("br",{}),"• 适用场景:需要保留原始thinking输出的思考类模型",n.jsx("br",{}),"• 常见示例:",n.jsx("code",{children:"gpt-4o-thinking"}),"、",n.jsx("code",{children:"claude-3-5-sonnet-thinking"}),"、",n.jsx("code",{children:"deepseek-chat-thinking"})]})]})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async()=>{if(Array.isArray(r)){l(!0);try{const t=Se(),n=r.join(",");await ye.put(t,{key:"ModelIgnoreThinkWhitelist",value:n}),be(i("保存成功")),e.refresh()}catch(t){je(i("保存失败,请重试"))}finally{l(!1)}}else je(i("模型白名单格式不正确"))},children:i("保存模型白名单")})})]})]})})}const{Text:rl}=u,{Text:ol}=u,{Text:cl,Title:dl}=u;function ul(){const{t:e}=ge(),[i,s]=t.useState(!1),[l,o]=t.useState(""),[c,u]=t.useState({global_enabled:!1,default_token_field:"max_tokens",model_limits:[]}),[p,h]=t.useState(null),[y,j]=t.useState(!1),[f,b]=t.useState(null),[_,C]=t.useState(null),[w,T]=t.useState(!1),[R,P]=t.useState(!1),[z,A]=t.useState(""),[M,O]=t.useState(""),D=e=>{b(e),j(!0)},L=[{title:e("模型名称"),dataIndex:"model_name",width:200,render:e=>n.jsx(cl,{strong:!0,children:e})},{title:e("Token字段类型"),dataIndex:"token_field",width:180,render:e=>n.jsx(cl,{type:"max_completion_tokens"===e?"warning":"primary",children:e})},{title:e("输出Token限制"),dataIndex:"output_token_limit",width:150,render:t=>t>0?t.toLocaleString():e("无限制")},{title:e("输入Token限制"),dataIndex:"input_token_limit",width:150,render:t=>t>0?t.toLocaleString():e("无限制")},{title:e("启用状态"),dataIndex:"enabled",width:100,render:e=>n.jsx(cl,{type:e?"success":"tertiary",children:e?"已启用":"已禁用"})},{title:e("操作"),dataIndex:"operation",width:200,render:(t,i,s)=>n.jsxs(g,{children:[n.jsx(d,{type:"primary",icon:n.jsx(at,{size:16}),onClick:()=>D({...i,index:s}),size:"small",children:e("编辑")}),n.jsx(d,{type:"danger",icon:n.jsx(He,{size:16}),onClick:()=>(e=>{const t=c.model_limits.filter((t,n)=>n!==e);u(e=>({...e,model_limits:t})),T(!0)})(s),size:"small",children:e("删除")})]})}];t.useEffect(()=>{B()},[]);const B=async()=>{s(!0);try{const e=Se(),t=await ye.get(e),{success:n,message:i,data:s}=t.data;if(n){const e=s.find(e=>"TokenLimitSettings"===e.key);if(e&&e.value){const t=JSON.parse(e.value);u(t),h(t)}}else je(i)}catch(e){je(e.message)}s(!1)},F=c.model_limits.filter(e=>!l||e.model_name.toLowerCase().includes(l.toLowerCase())||e.token_field.toLowerCase().includes(l.toLowerCase())),W=e=>{A(e);try{const t=JSON.parse(e);if(O(""),(e.match(/\n/g)||[]).length<3&&e.trim().length>50){const e=JSON.stringify(t,null,2);A(e)}}catch(t){O("JSON格式错误: "+t.message)}};return n.jsxs(m,{spinning:i,children:[n.jsxs(g,{vertical:!0,align:"start",style:{width:"100%"},children:[n.jsx(r,{title:n.jsx(dl,{heading:5,children:"🌐 全局设置"}),style:{width:"100%"},children:n.jsxs(g,{vertical:!0,style:{width:"100%"},children:[n.jsxs(g,{children:[n.jsx(cl,{strong:!0,children:e("功能开关:")}),n.jsx(E,{checked:c.global_enabled,onChange:e=>{u(t=>({...t,global_enabled:e})),T(!0)},"aria-label":e("全局Token限制开关")}),n.jsx(cl,{type:c.global_enabled?"success":"tertiary",children:c.global_enabled?"已启用":"已禁用"})]}),n.jsx(I,{margin:"12px"}),n.jsx(g,{wrap:!0,children:n.jsxs(g,{children:[n.jsx(cl,{strong:!0,children:e("默认Token字段:")}),n.jsxs(N,{value:c.default_token_field,onChange:e=>((e,t)=>{u(n=>({...n,[e]:t})),T(!0)})("default_token_field",e),style:{width:200},children:[n.jsx(N.Option,{value:"max_tokens",children:"max_tokens"}),n.jsx(N.Option,{value:"max_completion_tokens",children:"max_completion_tokens"})]})]})})]})}),n.jsxs(r,{title:n.jsx(dl,{heading:5,children:"🤖 模型限制配置"}),style:{width:"100%"},children:[n.jsxs(g,{style:{marginBottom:16},children:[n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>{b({model_name:"",token_field:"max_tokens",output_token_limit:4096,input_token_limit:128e3,enabled:!0}),j(!0)},disabled:!c.global_enabled,children:e("添加模型限制")}),n.jsx(d,{icon:n.jsx(Ze,{size:16}),type:"primary",onClick:async()=>{s(!0);
1try{const t=Se(),n=await ye.put(t,{key:"TokenLimitSettings",value:JSON.stringify(c)}),{success:i,message:s}=n.data;i?(be(e("保存成功")),T(!1),h(c)):je(s)}catch(t){je(t.message)}s(!1)},theme:"solid",disabled:!w,children:e("保存更改")}),n.jsx(d,{icon:n.jsx(et,{size:16}),onClick:()=>{p&&(u(p),T(!1))},disabled:!w,children:e("重置")}),n.jsx(d,{icon:n.jsx(it,{size:16}),onClick:()=>{const e=c||{global_enabled:!1,default_token_field:"max_tokens",model_limits:[]},t=JSON.stringify(e,null,2);A(t),O(""),P(!0)},type:"tertiary",children:e("JSON编辑")}),n.jsx(k,{prefix:e("搜索")+":",placeholder:e("输入模型名称或字段类型"),value:l,onChange:e=>{o(e)},style:{width:300},showClear:!0})]}),n.jsx(v,{columns:L,dataSource:F,pagination:{pageSize:20,showSizeChanger:!0,showTotal:!0},scroll:{x:1200,y:600},size:"small",rowKey:(e,t)=>`${e.model_name}_${t}`,onRow:(e,t)=>({onDoubleClick:()=>D({...e,index:t})}),empty:n.jsx("div",{style:{textAlign:"center",padding:"20px"},children:n.jsx(cl,{type:"tertiary",children:c.global_enabled?'暂无模型限制配置,点击"添加模型限制"开始配置':"请先启用全局开关"})})})]})]}),n.jsx(x,{title:e(void 0!==f?.index?"编辑模型限制":"添加模型限制"),visible:y,onOk:()=>_.submitForm(),onCancel:()=>j(!1),centered:!0,children:n.jsxs(a,{getFormApi:e=>C(e),onSubmit:e=>{const t=[...c.model_limits];if(f&&void 0!==f.index)t[f.index]={...e,output_token_limit:parseInt(e.output_token_limit)||0,input_token_limit:parseInt(e.input_token_limit)||0};else{const n={...e,output_token_limit:parseInt(e.output_token_limit)||0,input_token_limit:parseInt(e.input_token_limit)||0,enabled:!1!==e.enabled};t.unshift(n)}u(e=>({...e,model_limits:t})),T(!0),j(!1)},initValues:f,children:[n.jsx(a.Input,{field:"model_name",label:e("模型名称"),rules:[{required:!0,message:e("请输入模型名称")}],style:{width:"100%"},placeholder:e("例如:gpt-4, claude-3-sonnet")}),n.jsxs(a.Select,{field:"token_field",label:e("Token字段类型"),rules:[{required:!0,message:e("请选择Token字段类型")}],style:{width:"100%"},children:[n.jsx(a.Select.Option,{value:"max_tokens",children:"max_tokens"}),n.jsx(a.Select.Option,{value:"max_completion_tokens",children:"max_completion_tokens"})]}),n.jsx(a.InputNumber,{field:"output_token_limit",label:e("输出Token限制"),rules:[{required:!0,message:e("请输入输出Token限制")}],style:{width:"100%"},placeholder:e("0表示无限制"),min:0}),n.jsx(a.InputNumber,{field:"input_token_limit",label:e("输入Token限制"),rules:[{required:!0,message:e("请输入输入Token限制")}],style:{width:"100%"},placeholder:e("0表示无限制"),min:0}),n.jsx(a.Switch,{field:"enabled",label:e("启用状态"),extraText:e("是否对此模型启用Token限制")})]})}),n.jsx(x,{title:n.jsxs(g,{children:[n.jsx(it,{size:16}),e("JSON配置编辑器")]}),visible:R,onOk:()=>{try{const t=JSON.parse(z);if("boolean"!=typeof t.global_enabled)return void O("global_enabled 字段必须是布尔值");if(!Array.isArray(t.model_limits))return void O("model_limits 字段必须是数组");for(let e=0;e<t.model_limits.length;e++){const n=t.model_limits[e];if(!n.model_name||"string"!=typeof n.model_name)return void O(`模型 ${e+1}: model_name 字段必须是非空字符串`);if(!["max_tokens","max_completion_tokens"].includes(n.token_field))return void O(`模型 ${e+1}: token_field 必须是 max_tokens 或 max_completion_tokens`)}u(t),T(!0),P(!1),be(e("JSON配置已应用"))}catch(t){O("JSON格式错误: "+t.message)}},onCancel:()=>P(!1),centered:!0,okText:e("应用配置"),cancelText:e("取消"),okButtonProps:{disabled:!!M},children:n.jsxs(g,{vertical:!0,style:{width:"100%"},children:[n.jsxs(g,{wrap:!0,children:[n.jsx(d,{onClick:async()=>{try{await navigator.clipboard.writeText(z),be(e("已复制到剪贴板"))}catch(t){je(e("复制失败")+": "+t.message)}},size:"small",children:e("复制到剪贴板")}),n.jsx(d,{onClick:async()=>{try{const n=await navigator.clipboard.readText();try{const t=JSON.parse(n),i=JSON.stringify(t,null,2);A(i),O(""),be(e("已成功从剪贴板导入配置"))}catch(t){O("剪贴板内容不是有效的 JSON 格式: "+t.message),je(e("剪贴板内容不是有效的 JSON 格式"))}}catch(n){je(e("从剪贴板读取失败")+": "+n.message)}},size:"small",children:e("从剪贴板导入")}),n.jsx(d,{onClick:()=>{try{const t=JSON.parse(z),n=JSON.stringify(t,null,2);A(n),be(e("JSON 已格式化"))}catch(t){je(e("无法格式化:JSON 格式错误"))}},size:"small",disabled:!!M,children:e("格式化")}),n.jsx(d,{onClick:()=>{const e=JSON.stringify({global_enabled:!0,default_token_field:"max_tokens",model_limits:[{model_name:"gpt-4",token_field:"max_tokens",output_token_limit:4096,input_token_limit:128e3,enabled:!0},{model_name:"gpt-4o",token_field:"max_tokens",output_token_limit:4096,input_token_limit:128e3,enabled:!0},{model_name:"o1",token_field:"max_completion_tokens",output_token_limit:1e5,input_token_limit:2e5,enabled:!0},{model_name:"claude-3-5-sonnet-20241022",token_field:"max_tokens",output_token_limit:8192,input_token_limit:2e5,enabled:!0}]},null,2);A(e),W(e)},size:"small",type:"tertiary",children:e("加载示例配置")})]}),n.jsx(cl,{type:"tertiary",style:{fontSize:"12px"},children:e("提示:您可以复制此配置分享给朋友,或从朋友那里导入配置")}),M&&n.jsx("div",{style:{padding:"8px 12px",backgroundColor:"#fef2f2",border:"1px solid #fecaca",borderRadius:"6px"},children:n.jsx(cl,{type:"danger",children:M})}),n.jsx(S,{value:z,onChange:W,placeholder:e("请输入JSON配置"),style:{fontFamily:'Consolas, Monaco, "Courier New", monospace',fontSize:"14px",lineHeight:"1.5",minHeight:"400px",
1whiteSpace:"pre-wrap"},autosize:{minRows:20,maxRows:25}}),n.jsx("div",{style:{padding:"8px 12px",backgroundColor:"#f3f4f6",borderRadius:"6px",fontSize:"12px"},children:n.jsxs(cl,{type:"tertiary",children:[n.jsx("strong",{children:e("配置说明")+":"}),n.jsx("br",{}),"• global_enabled: 全局开关 (true/false)",n.jsx("br",{}),'• default_token_field: 默认字段类型 ("max_tokens" 或 "max_completion_tokens")',n.jsx("br",{}),"• model_limits: 模型限制数组,每个模型包含 model_name, token_field, output_token_limit, input_token_limit, enabled 字段"]})})]})})]})}function pl(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,p]=t.useState({GeminiEmptyResponseCheckEnabled:!1,GeminiImageErrorCheckEnabled:!1,GeminiImageErrorCheckModels:[],GeminiImageErrorCheckParams:[]}),[h,x]=t.useState(r),y=t.useRef(),[j,f]=t.useState(""),[b,_]=t.useState(""),S=()=>{const e=j.trim();if(!e)return;if(r.GeminiImageErrorCheckModels.includes(e))return void ve(i("该模型已存在"));const t=[...r.GeminiImageErrorCheckModels,e];p({...r,GeminiImageErrorCheckModels:t}),y.current?.setValue("GeminiImageErrorCheckModels",t),f("")},v=()=>{const e=b.trim();if(!e)return;if(r.GeminiImageErrorCheckParams.includes(e))return void ve(i("该参数已存在"));const t=[...r.GeminiImageErrorCheckParams,e];p({...r,GeminiImageErrorCheckParams:t}),y.current?.setValue("GeminiImageErrorCheckParams",t),_("")};return t.useEffect(()=>{const t={GeminiEmptyResponseCheckEnabled:!1,GeminiImageErrorCheckEnabled:!1,GeminiImageErrorCheckModels:[],GeminiImageErrorCheckParams:[]};for(let n in e.options)"GeminiEmptyResponseCheckEnabled"===n||"GeminiImageErrorCheckEnabled"===n?t[n]=!0===e.options[n]:"GeminiImageErrorCheckModels"!==n&&"GeminiImageErrorCheckParams"!==n||("string"==typeof e.options[n]?t[n]=e.options[n]?e.options[n].split(",").map(e=>e.trim()).filter(e=>e):[]:Array.isArray(e.options[n])?t[n]=e.options[n]:t[n]=[]);p(t),x(structuredClone(t)),y.current?.setValues(t),setTimeout(()=>{y.current?.setValues(t)},100)},[e.options]),n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>y.current=e,style:{marginBottom:15},initValues:r,children:n.jsxs(a.Section,{text:i("Gemini 模型设置"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{span:8,children:n.jsx(a.Switch,{field:"GeminiEmptyResponseCheckEnabled",label:i("启用空回复检测"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{p({...r,GeminiEmptyResponseCheckEnabled:e})}})})}),n.jsx(o,{gutter:16,children:n.jsxs(c,{span:16,children:[n.jsx(u.Text,{type:"secondary",style:{display:"block",marginTop:8},children:i("检测 Gemini 模型返回的空回复(仅有 role 但无内容的响应),并将其视为失败。")}),n.jsx(u.Text,{type:"secondary",style:{display:"block",marginTop:4},children:i("启用后,当 Gemini 返回空候选内容时,系统会返回错误而不是空响应。")})]})}),n.jsx(o,{gutter:16,style:{marginTop:24},children:n.jsx(c,{span:8,children:n.jsx(a.Switch,{field:"GeminiImageErrorCheckEnabled",label:i("启用生图错误检测"),size:"default",checkedText:"|",uncheckedText:"〇",onChange:e=>{p({...r,GeminiImageErrorCheckEnabled:e})}})})}),r.GeminiImageErrorCheckEnabled&&n.jsxs(n.Fragment,{children:[n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsxs(c,{span:24,children:[n.jsx(u.Text,{strong:!0,children:i("检查的模型")}),n.jsxs(g,{style:{width:"100%",marginTop:8},children:[n.jsx(k,{value:j,onChange:f,placeholder:i("请输入模型名称"),style:{width:400},onEnterPress:S}),n.jsx(d,{onClick:S,children:i("添加")})]}),n.jsx(u.Text,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:4},children:i("gemini_hint_001")}),r.GeminiImageErrorCheckModels.length>0&&n.jsx("div",{style:{marginTop:12},children:n.jsx(ae,{tagList:r.GeminiImageErrorCheckModels.map(e=>({tagKey:e,children:e,closable:!0,onClose:()=>(e=>{const t=r.GeminiImageErrorCheckModels.filter(t=>t!==e);p({...r,GeminiImageErrorCheckModels:t}),y.current?.setValue("GeminiImageErrorCheckModels",t)})(e)})),size:"large"})})]})}),n.jsx(o,{gutter:16,style:{marginTop:24},children:n.jsxs(c,{span:24,children:[n.jsx(u.Text,{strong:!0,children:i("检查的 finishReason 参数")}),n.jsxs(g,{style:{width:"100%",marginTop:8},children:[n.jsx(k,{value:b,onChange:_,placeholder:i("请输入 finishReason 值"),style:{width:400},onEnterPress:v}),n.jsx(d,{onClick:v,children:i("添加")})]}),n.jsx(u.Text,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:4},children:i("常见异常:SAFETY, RECITATION, MAX_TOKENS, OTHER, IMAGE_SAFETY, NO_IMAGE")}),r.GeminiImageErrorCheckParams.length>0&&n.jsx("div",{style:{marginTop:12},children:n.jsx(ae,{tagList:r.GeminiImageErrorCheckParams.map(e=>({tagKey:e,children:e,closable:!0,onClose:()=>(e=>{const t=r.GeminiImageErrorCheckParams.filter(t=>t!==e);p({...r,GeminiImageErrorCheckParams:t}),y.current?.setValue("GeminiImageErrorCheckParams",t)})(e)})),size:"large"})})]})}),n.jsx(o,{gutter:16,children:n.jsxs(c,{span:24,children:[n.jsx(u.Text,{type:"secondary",style:{display:"block",marginTop:8},children:i("检测 Gemini 生图模型返回的 finishReason 参数,当检测到选中的异常值时将其视为失败。")}),n.jsx(u.Text,{type:"secondary",style:{display:"block",marginTop:4}
1,children:i("常见异常:SAFETY(安全过滤)、RECITATION(重复内容)、MAX_TOKENS(超出限制)、OTHER(其他错误)")})]})})]}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));l(!0);const n=Se(),s=t.map(e=>{let t=r[e.key];return"boolean"==typeof t?t=String(t):Array.isArray(t)&&(t=t.join(",")),ye.put(n,{key:e.key,value:t})});Promise.all(s).then(t=>{if(1===s.length){if(t.includes(void 0))return}else if(s.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh()}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存 Gemini 设置")})})]})})})}const{Title:hl}=u,xl=e=>[{label:e("对话 (chat)"),value:"chat"},{label:e("图片生成 (image)"),value:"image"},{label:e("视频 (video)"),value:"video"},{label:e("音乐 (music)"),value:"music"},{label:e("其他 (other)"),value:"other"}],ml={rank:1,model_name:"",provider:"",calls:0,tokens:0,pct:0,growth:0,enabled:!0};function gl(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,o]=t.useState(!1),[c,p]=t.useState(!1),[y,j]=t.useState({total_calls:0,total_tokens:0,active_models:0}),[f,b]=t.useState([]),[_,S]=t.useState(!1),[k,C]=t.useState(-1),[w,T]=t.useState(-1),[I,R]=t.useState({...ml}),[P,z]=t.useState(!1),[N,A]=t.useState("chat"),[M,O]=t.useState(0);t.useEffect(()=>{e.options&&p(!!e.options.RankingEnabled)},[e.options]);const D=t.useCallback(async()=>{l(!0);try{const e=await ye.get("/api/ranking/admin");if(e.data.success&&e.data.data){const t=e.data.data;j(t.summary||{total_calls:0,total_tokens:0,active_models:0}),b(t.categories||[])}}catch(e){je(i("加载排行榜数据失败: ")+e.message)}finally{l(!1)}},[i]);t.useEffect(()=>{D()},[D]);const L=[{title:i("排名"),dataIndex:"rank",width:60},{title:i("模型名称"),dataIndex:"model_name",width:180},{title:i("供应商"),dataIndex:"provider",width:120},{title:i("调用次数"),dataIndex:"calls",width:120,render:e=>(e||0).toLocaleString()},{title:i("Token 数"),dataIndex:"tokens",width:120,render:e=>(e||0).toLocaleString()},{title:i("占比(%)"),dataIndex:"pct",width:80,render:e=>(e||0).toFixed(1)},{title:i("增长(%)"),dataIndex:"growth",width:80,render:e=>(e||0).toFixed(1)},{title:i("启用"),dataIndex:"enabled",width:60,render:(e,t)=>n.jsx(E,{size:"small",checked:!1!==e,onChange:e=>{const n=[...f];n[t._catIdx].models[t._modelIdx].enabled=e,b(n)}})},{title:i("操作"),width:100,render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(at,{size:16}),size:"small",theme:"borderless",onClick:()=>{return e=t._catIdx,n=t._modelIdx,C(e),T(n),R({...f[e].models[n]}),void S(!0);var e,n}}),n.jsx(d,{icon:n.jsx(He,{size:16}),size:"small",theme:"borderless",type:"danger",onClick:()=>((e,t)=>{const n=[...f],i={...n[e]},s=[...i.models];s.splice(t,1),s.forEach((e,t)=>e.rank=t+1),i.models=s,n[e]=i,b(n)})(t._catIdx,t._modelIdx)})]})}];return n.jsxs(m,{spinning:s,children:[n.jsxs("div",{style:{marginBottom:24},children:[n.jsxs(g,{align:"center",style:{marginBottom:16},children:[n.jsx(hl,{heading:5,style:{margin:0},children:i("排行榜开关")}),n.jsx(E,{checked:c,onChange:async t=>{try{const n=Se(),s=await ye.put(n,{key:"RankingEnabled",value:String(t)});s.data.success?(p(t),be(i(t?"排行榜已开启":"排行榜已关闭")),e.refresh&&e.refresh()):je(s.data.message||i("保存失败"))}catch(n){je(i("保存失败")+": "+n.message)}}}),n.jsx(u.Text,{type:"tertiary",children:i(c?"已开启 - 首页展示排行榜,后台每12小时自动聚合数据":"已关闭 - 首页不展示,聚合任务暂停")})]}),!c&&n.jsx(h,{type:"info",description:i("排行榜功能已关闭,前端不会展示排行榜,后台聚合任务也不会执行。你仍然可以在下方手动编辑数据,开启后即可生效。"),style:{marginBottom:16}})]}),n.jsxs("div",{style:{marginBottom:24},children:[n.jsx(hl,{heading:5,children:i("汇总数据")}),n.jsx(h,{type:"info",description:i("汇总数据由后台每12小时自动聚合生成,也可以在此手动修改。手动修改将在下一次自动聚合时被覆盖。"),style:{marginBottom:12}}),n.jsxs(g,{style:{gap:24},children:[n.jsx(a.InputNumber,{field:"total_calls",label:i("月调用次数"),value:y.total_calls,onChange:e=>j({...y,total_calls:e||0}),style:{width:200}}),n.jsx(a.InputNumber,{field:"total_tokens",label:i("月 Token 数"),value:y.total_tokens,onChange:e=>j({...y,total_tokens:e||0}),style:{width:200}}),n.jsx(a.InputNumber,{field:"active_models",label:i("活跃模型数"),value:y.active_models,onChange:e=>j({...y,active_models:e||0}),style:{width:200}})]})]}),n.jsxs("div",{style:{marginBottom:16},children:[n.jsxs(g,{align:"center",style:{marginBottom:12},children:[n.jsx(hl,{heading:5,style:{margin:0},children:i("排行数据")}),n.jsx(d,{icon:n.jsx(Ye,{size:16}),size:"small",onClick:()=>z(!0),children:i("添加分类")})]}),f.map((e,t)=>n.jsxs("div",{style:{marginBottom:24,border:"1px solid hsl(var(--border))",borderRadius:8,padding:16},children:[n.jsxs(g,{align:"center",style:{marginBottom:12,justifyContent:"space-between",width:"100%"},children:[n.jsxs(g,{align:"center",children:[n.jsx(hl,{heading:6,style:{margin:0},children:xl(i).find(t=>t.value===e.category)?.label||e.category}),n.jsxs(u.Text,{type:"tertiary",children:[i("增长"),": ",(e.growth||0).toFixed(1),"%"]})]}),n.jsxs(g,{children:[n.jsx(d,{icon:n.jsx(Ye,{size:16}),size:"small",onClick:()=>(e=>{C(e),T(-1);const t=f[e],n=t.models?t.models.length+1:1;R({...ml,rank:n}),S(!0)})(t),children:i("添加模型")}),n.jsx(d,{icon:n.jsx(He,{size:16}),size:"small",type:"danger",theme:"borderless",onClick:()=>(e=>{const t=[...f];t.splice(e,1),b(t)})(t)})]})]}),n.jsx(v,{columns:L,dataSource:(e.models||[]).map((e,n)=>({...e,key:`${t}-${n}`,_catIdx:t,_modelIdx:n})),pagination:!1,size:"small",empty:n.jsx(u.Text,{type:"tertiary",children:i('暂无模型,点击"添加模型"开始配置')})})]},e.category)),0===f.length&&n.jsx(h,{type:"info",description:i("暂无排行分类数据。开启排行榜开关后ï¼
1ŒåŽå°ä¼šè‡ªåŠ¨èšåˆæ•°æ®ï¼›ä¹Ÿå¯ä»¥ç‚¹å‡»ã€Œæ·»åŠ åˆ†ç±»ã€æ‰‹åŠ¨é…ç½®ã€‚"),style:{marginBottom:16}})]}),n.jsx(d,{type:"primary",loading:r,onClick:async()=>{o(!0);try{const e={summary:y,categories:f},t=await ye.put("/api/ranking/admin",e);t.data.success?be(i("排行榜数据已保存")):je(t.data.message||i("保存失败"))}catch(e){je(i("保存失败")+": "+e.message)}finally{o(!1)}},style:{marginTop:8},children:i("保存排行榜数据")}),n.jsx(x,{title:i(w>=0?"编辑模型":"添加模型"),visible:_,onOk:()=>{if(!I.model_name.trim())return void ve(i("模型名称不能为空"));const e=[...f],t={...e[k]},n=[...t.models||[]];w>=0?n[w]={...I}:n.push({...I}),t.models=n,e[k]=t,b(e),S(!1)},onCancel:()=>S(!1),width:480,children:n.jsxs(a,{layout:"vertical",initValues:I,onValueChange:e=>R({...I,...e}),children:[n.jsx(a.Input,{field:"model_name",label:i("模型名称"),placeholder:i("如 gpt-4o")}),n.jsx(a.Input,{field:"provider",label:i("供应商"),placeholder:i("如 OpenAI")}),n.jsx(a.InputNumber,{field:"rank",label:i("排名"),min:1}),n.jsx(a.InputNumber,{field:"calls",label:i("调用次数"),min:0}),n.jsx(a.InputNumber,{field:"tokens",label:i("Token 数"),min:0}),n.jsx(a.InputNumber,{field:"pct",label:i("占比(%)"),min:0,max:100,precision:1}),n.jsx(a.InputNumber,{field:"growth",label:i("增长(%)"),precision:1}),n.jsx(a.Switch,{field:"enabled",label:i("启用")})]})}),n.jsx(x,{title:i("添加分类"),visible:P,onOk:()=>{f.find(e=>e.category===N)?ve(i("该分类已存在")):(b([...f,{category:N,growth:M,models:[]}]),z(!1),A("chat"),O(0))},onCancel:()=>z(!1),width:360,children:n.jsxs(a,{layout:"vertical",children:[n.jsx(a.Select,{field:"category",label:i("分类"),initValue:N,onChange:e=>A(e),optionList:xl(i),style:{width:"100%"}}),n.jsx(a.InputNumber,{field:"growth",label:i("分类增长(%)"),initValue:M,onChange:e=>O(e||0),precision:1})]})})]})}const{Text:yl}=u;function jl(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,d]=t.useState(!1),[u,p]=t.useState({CaptchaLoginEnabled:!1,SMSLoginEnabled:!1,SMSProvider:"",SMSSecretId:"",SMSSecretKey:"",SMSRegion:"",SMSSdkAppId:"",SMSSignName:"",SMSTemplateId:"",SMSCodeExpireMinutes:"5",SMSRateLimitMinutes:"1",SMSRateLimitCount:"1",SMSMosUsername:"",SMSMosPassword:"",SMSMosSignature:"",SMSMosContentTemplate:"您的验证码为{code},{expire}分钟内有效,请勿泄露。",SMSMosBizType:"",SMSMosEndpoint:"https://ns.mosapi.cn:9100",ChannelModelRedirect:""}),h=t.useRef(),[x,m]=t.useState(u),g=async(e,t)=>{try{const n=await ye.put("/api/option/",{key:e,value:t}),{success:s,message:l}=n.data;return s?(be(i("保存成功")),p(n=>({...n,[e]:t})),m(n=>({...n,[e]:t})),h.current&&h.current.setValue(e,t),!0):(je(l),!1)}catch(n){return je(i("保存失败")+": "+n.message),!1}};return t.useEffect(()=>{const t={},n=["CaptchaLoginEnabled","SMSLoginEnabled","SMSProvider","SMSSecretId","SMSSecretKey","SMSRegion","SMSSdkAppId","SMSSignName","SMSTemplateId","SMSCodeExpireMinutes","SMSRateLimitMinutes","SMSRateLimitCount","SMSMosUsername","SMSMosPassword","SMSMosSignature","SMSMosContentTemplate","SMSMosBizType","SMSMosEndpoint","ChannelModelRedirect"];for(let i in e.options)if(n.includes(i)){let n=e.options[i];"CaptchaLoginEnabled"===i||"SMSLoginEnabled"===i?n="true"===n||!0===n:null==n&&(n=""),t[i]=n}Object.keys(t).length>0&&(p(e=>({...e,...t})),m(e=>({...e,...t})),setTimeout(()=>{h.current&&h.current.setValues(t)},100))},[e.options]),n.jsxs(a,{style:{marginBottom:15},getFormApi:e=>h.current=e,autoComplete:"off",children:[n.jsxs("div",{style:{position:"absolute",opacity:0,height:0,overflow:"hidden",pointerEvents:"none"},children:[n.jsx("input",{type:"text",name:"prevent_autofill_username",tabIndex:-1,autoComplete:"username"}),n.jsx("input",{type:"password",name:"prevent_autofill_password",tabIndex:-1,autoComplete:"current-password"})]}),n.jsxs(a.Section,{text:i("扩展功能配置"),children:[n.jsx(o,{gutter:16,children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"60px 40px",textAlign:"center",background:"linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%)",borderRadius:"12px",border:"2px dashed #d0d7de"}
1,children:[n.jsx("div",{style:{fontSize:"48px",marginBottom:"16px"},children:"🚀"}),n.jsx(yl,{strong:!0,style:{fontSize:"18px",display:"block",marginBottom:"12px",color:"#24292e"},children:i("此区域用于添加新的二开扩展功能")}),n.jsx(yl,{type:"tertiary",style:{fontSize:"14px",display:"block",marginBottom:"8px"},children:i("原有功能已拆分至各个独立模块:")})]})})}),n.jsx(o,{gutter:16,style:{marginTop:"24px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"SMSLoginEnabled",label:i("启用短信验证码登录"),initValue:u.SMSLoginEnabled,checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await g("SMSLoginEnabled",String(t))&&e.refresh&&e.refresh()}}),n.jsx(yl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("开启后,用户可以使用手机号+验证码登录系统")}),n.jsx(yl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("⚠️ 需要配置短信服务提供商(如腾讯云短信)才能使用")})]})})]}),u.SMSLoginEnabled&&n.jsxs(a.Section,{text:i("短信服务配置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{span:12,children:n.jsxs(a.Select,{field:"SMSProvider",label:i("短信服务提供商"),placeholder:i("请选择短信服务提供商"),initValue:u.SMSProvider,onChange:async t=>{p(e=>({...e,SMSProvider:t})),await g("SMSProvider",t)&&e.refresh&&await e.refresh()},style:{width:"100%"},children:[n.jsx(a.Select.Option,{value:"tencent",children:i("腾讯云短信")}),n.jsx(a.Select.Option,{value:"aliyun",children:i("阿里云短信")}),n.jsx(a.Select.Option,{value:"huawei",children:i("华为云短信")}),n.jsx(a.Select.Option,{value:"xuanwu",children:i("玄武云MOS短信")})]})}),"xuanwu"!==u.SMSProvider&&n.jsx(c,{span:12,children:n.jsx(a.Input,{field:"SMSRegion",label:i("服务区域"),placeholder:"ap-guangzhou",initValue:u.SMSRegion,onChange:e=>{p(t=>({...t,SMSRegion:e}))},onBlur:async e=>{await g("SMSRegion",e.target.value)}})}),"xuanwu"===u.SMSProvider&&n.jsxs(c,{span:12,children:[n.jsx(a.Input,{field:"SMSMosEndpoint",label:i("接入地址"),placeholder:"https://ns.mosapi.cn:9100",initValue:u.SMSMosEndpoint,onChange:e=>{p(t=>({...t,SMSMosEndpoint:e}))},onBlur:async e=>{await g("SMSMosEndpoint",e.target.value)}}),n.jsx(yl,{type:"tertiary",style:{fontSize:"11px",display:"block",marginTop:"4px"},children:i("默认 https://ns.mosapi.cn:9100,一般无需修改")})]})]}),"xuanwu"!==u.SMSProvider&&n.jsxs(n.Fragment,{children:[n.jsxs(o,{gutter:16,style:{marginTop:"16px"},children:[n.jsx(c,{span:12,children:n.jsx(a.Input,{field:"SMSSecretId",label:i("Secret ID"),placeholder:u.SMSSecretId?i("已配置(输入新值以更新)"):i("请输入 Secret ID"),mode:"password",autoComplete:"new-password",name:"sms_secret_id_setting",onChange:e=>{p(t=>({...t,SMSSecretId:e}))},onBlur:async e=>{const t=e.target.value;t&&await g("SMSSecretId",t)}})}),n.jsx(c,{span:12,children:n.jsx(a.Input,{field:"SMSSecretKey",label:i("Secret Key"),placeholder:u.SMSSecretKey?i("已配置(输入新值以更新)"):i("请输入 Secret Key"),mode:"password",autoComplete:"new-password",name:"sms_secret_key_setting",onChange:e=>{p(t=>({...t,SMSSecretKey:e}))},onBlur:async e=>{const t=e.target.value;t&&await g("SMSSecretKey",t)}})})]}),n.jsxs(o,{gutter:16,style:{marginTop:"16px"},children:[n.jsxs(c,{span:12,children:[n.jsx(a.Input,{field:"SMSSdkAppId",label:i("短信应用 SDK App ID"),placeholder:"1400xxxxxx",initValue:u.SMSSdkAppId,onChange:e=>{p(t=>({...t,SMSSdkAppId:e}))},onBlur:async e=>{await g("SMSSdkAppId",e.target.value)}}),n.jsx(yl,{type:"tertiary",style:{fontSize:"11px",display:"block",marginTop:"4px"},children:i("腾讯云:在短信控制台的应用列表中获取")})]}),n.jsxs(c,{span:12,children:[n.jsx(a.Input,{field:"SMSSignName",label:i("短信签名"),placeholder:i("请输入短信签名"),initValue:u.SMSSignName,onChange:e=>{p(t=>({...t,SMSSignName:e}))},onBlur:async e=>{await g("SMSSignName",e.target.value)}}),n.jsx(yl,{type:"tertiary",style:{fontSize:"11px",display:"block",marginTop:"4px"},children:i("需要在短信控制台创建并审核通过")})]})]}),n.jsx(o,{gutter:16,style:{marginTop:"16px"},children:n.jsxs(c,{span:12,children:[n.jsx(a.Input,{field:"SMSTemplateId",label:i("短信模板 ID"),placeholder:"123456",initV
1alue:u.SMSTemplateId,onChange:e=>{p(t=>({...t,SMSTemplateId:e}))},onBlur:async e=>{await g("SMSTemplateId",e.target.value)}}),n.jsx(yl,{type:"tertiary",style:{fontSize:"11px",display:"block",marginTop:"4px"},children:i("模板格式: 您的验证码是{1},{2}分钟内有效")})]})})]}),"xuanwu"===u.SMSProvider&&n.jsxs(n.Fragment,{children:[n.jsxs(o,{gutter:16,style:{marginTop:"16px"},children:[n.jsx(c,{span:12,children:n.jsx(a.Input,{field:"SMSMosUsername",label:i("MOS 账号"),placeholder:i("请输入玄武云 MOS 账号"),initValue:u.SMSMosUsername,onChange:e=>{p(t=>({...t,SMSMosUsername:e}))},onBlur:async e=>{await g("SMSMosUsername",e.target.value)}})}),n.jsx(c,{span:12,children:n.jsx(a.Input,{field:"SMSMosPassword",label:i("MOS 密码"),placeholder:u.SMSMosPassword?i("已配置(输入新值以更新)"):i("请输入玄武云 MOS 密码"),mode:"password",autoComplete:"new-password",name:"sms_mos_password_setting",onChange:e=>{p(t=>({...t,SMSMosPassword:e}))},onBlur:async e=>{const t=e.target.value;t&&await g("SMSMosPassword",t)}})})]}),n.jsxs(o,{gutter:16,style:{marginTop:"16px"},children:[n.jsxs(c,{span:12,children:[n.jsx(a.Input,{field:"SMSMosSignature",label:i("短信签名"),placeholder:i("如:玄武科技"),initValue:u.SMSMosSignature,onChange:e=>{p(t=>({...t,SMSMosSignature:e}))},onBlur:async e=>{await g("SMSMosSignature",e.target.value)}}),n.jsx(yl,{type:"tertiary",style:{fontSize:"11px",display:"block",marginTop:"4px"},children:i("会自动拼接到短信内容开头,无需写在内容模板里")})]}),n.jsx(c,{span:12,children:n.jsx(a.Input,{field:"SMSMosBizType",label:i("业务类型 ID(bizType,可选)"),placeholder:"100",initValue:u.SMSMosBizType,onChange:e=>{p(t=>({...t,SMSMosBizType:e}))},onBlur:async e=>{await g("SMSMosBizType",e.target.value)}})})]}),n.jsx(o,{gutter:16,style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"SMSMosContentTemplate",label:i("验证码内容模板"),placeholder:"您的验证码为{code},{expire}分钟内有效,请勿泄露。",initValue:u.SMSMosContentTemplate,onChange:e=>{p(t=>({...t,SMSMosContentTemplate:e}))},onBlur:async e=>{await g("SMSMosContentTemplate",e.target.value)}}),n.jsx(yl,{type:"tertiary",style:{fontSize:"11px",display:"block",marginTop:"4px"},children:i("占位符 {code} 为验证码,{expire} 为有效期分钟数;必须包含 {code}")})]})})]}),n.jsx(o,{gutter:16,style:{marginTop:"16px"},children:n.jsx(c,{span:12,children:n.jsx(a.InputNumber,{field:"SMSCodeExpireMinutes",label:i("验证码有效期(分钟)"),placeholder:"5",min:1,max:30,initValue:Number(u.SMSCodeExpireMinutes)||5,onChange:async t=>{p(e=>({...e,SMSCodeExpireMinutes:String(t)})),await g("SMSCodeExpireMinutes",String(t))&&e.refresh&&e.refresh()},style:{width:"100%"}})})}),n.jsxs(o,{gutter:16,style:{marginTop:"16px"},children:[n.jsx(c,{span:12,children:n.jsx(a.InputNumber,{field:"SMSRateLimitMinutes",label:i("发送频率限制周期(分钟)"),placeholder:"1",min:1,max:60,initValue:Number(u.SMSRateLimitMinutes)||1,onChange:async t=>{p(e=>({...e,SMSRateLimitMinutes:String(t)})),await g("SMSRateLimitMinutes",String(t))&&e.refresh&&e.refresh()},style:{width:"100%"}})}),n.jsx(c,{span:12,children:n.jsx(a.InputNumber,{field:"SMSRateLimitCount",label:i("周期内最大发送次数"),placeholder:"1",min:1,max:10,initValue:Number(u.SMSRateLimitCount)||1,onChange:async t=>{p(e=>({...e,SMSRateLimitCount:String(t)})),await g("SMSRateLimitCount",String(t))&&e.refresh&&e.refresh()},style:{width:"100%"}})})]}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"12px",background:"#fff7e6",border:"1px solid #ffd591",borderRadius:"6px"},children:[n.jsxs(yl,{style:{fontSize:"13px",color:"#ad6800"},children:["💡 ",n.jsx("strong",{children:i("配置提示")})]}),n.jsxs("ul",{style:{margin:"8px 0 0 0",paddingLeft:"20px"},children:[n.jsxs("li",{style:{fontSize:"12px",color:"#ad6800",marginTop:"4px"},children:[i("腾讯云:需要在"),n.jsx("a",{href:"https://console.cloud.tencent.com/smsv2",target:"_blank",rel:"noopener noreferrer",children:i("短信控制台")}),i("创建应用、签名和模板")]}),n.jsxs("li",{style:{fontSize:"12px",color:"#ad6800",marginTop:"4px"},children:[i("Secret ID/Key 在"),n.jsx("a",{href:"https://console.cloud.tencent.com/cam/capi",target:"_blank",rel:"noopener noreferrer",children:i("访问管理-API密钥")}),i("中获取")]}),n.jsx("li",{style:{fontSize:"12px",color:"#ad6800",marginTop:"4px"}
1,children:i("建议启用滑块验证码防止恶意刷短信")})]})]})})})]}),n.jsx(a.Section,{text:i("渠道模型重定向"),children:n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.TextArea,{field:"ChannelModelRedirect",label:i("模型重定向配置(多维字符串数组)"),placeholder:'[\n  ["deepseek-chat", "deepseek-v3", "deepseek-v3-250324"],\n  ["deepseek-r1", "deepseek-reasoner", "deepseek-r1-250120"],\n  ["gpt-4", "gpt-4-turbo", "gpt-4-0613"]\n]',autosize:{minRows:6,maxRows:15},onChange:async e=>{p(t=>({...t,ChannelModelRedirect:e}))}}),n.jsx(yl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("💡 说明:每个子数组是一个等价模型组,组内的模型可以互相重定向")}),n.jsx(yl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i('📝 格式:[["model1","model2"],["model3","model4"]],支持多行书写')})]})})})]})}function fl(e){const{t:i}=ge(),[s,l]=t.useState(!1),[h,x]=t.useState([]),[g,y]=t.useState([]),[j,f]=t.useState(""),[b,_]=t.useState(""),[S,v]=t.useState([]),[C,w]=t.useState(""),[T,I]=t.useState([]),[R,P]=t.useState(""),[z,N]=t.useState([]),[A,O]=t.useState(""),[D,L]=t.useState([]),[B,F]=t.useState(""),[W,J]=t.useState([]),[U,V]=t.useState(""),[K,G]=t.useState(!1),[q,$]=t.useState([]),[H,Q]=t.useState([]),[X,Y]=t.useState(0),[Z,ee]=t.useState(null),[te,ne]=t.useState({enabled_menus:[],enabled_side_menus:[],log_query_limit:"100000",fixed_log_total_enabled:!0}),ie=[{label:i("首页"),value:"home"},{label:i("控制台"),value:"console"},{label:i("OpenClaw 一键部署"),value:"openclaw"},{label:i("模型价格"),value:"pricing"},{label:i("代理加盟"),value:"affiliate"},{label:i("关于"),value:"about"},{label:i("公告"),value:"announcement"},{label:i("教程"),value:"tutorial"},{label:i("语言切换"),value:"language"},{label:i("登录"),value:"login"},{label:i("注册"),value:"register"},{label:i("联系我们"),value:"customersupport"},{label:i("文章资讯"),value:"news"},{label:i("技能中心"),value:"skills"}],se=[{label:i("控制台"),value:"console"},{label:i("实验室"),value:"playground"},{label:i("渠道管理"),value:"channel"},{label:i("聊天/绘画"),value:"chat"},{label:i("API令牌"),value:"token"},{label:i("兑换码"),value:"redemption"},{label:i("余额充值"),value:"topup"},{label:i("联系我们"),value:"customersupport"},{label:i("用户管理"),value:"user"},{label:i("日志管理"),value:"logs"},{label:i("个人设置"),value:"personal"},{label:i("系统设置"),value:"setting"},{label:i("推送管理"),value:"push_manage"},{label:i("OpenClaw 部署"),value:"openclaw"}],le=async e=>{l(!0);try{const t=Se(),n=e.map(e=>ye.put(t,{key:e.key,value:"boolean"==typeof e.value?e.value.toString():e.value})),s=(await Promise.all(n)).filter(e=>!e.data.success);s.length>0?s.forEach(e=>{je(e.data.message)}):be(i("更新成功"))}catch(t){je(i("更新失败"))}l(!1)},ae=()=>{const e=R.trim();e&&!T.includes(e)&&(I([...T,e]),P(""))},re=()=>{const e=A.trim();e&&!z.includes(e)&&(N([...z,e]),O(""))},oe=()=>{const e=B.trim();e&&!D.includes(e)&&(L([...D,e]),F(""))},ce=()=>{const e=U.trim();e&&!W.includes(e)&&(J([...W,e]),V(""))},de=()=>{j&&!h.includes(j)&&(x([...h,j]),f(""))},ue=()=>{b&&!g.includes(b)&&(y([...g,b]),_(""))},pe=()=>{C&&!S.includes(C)&&(v([...S,C]),w(""))},he=(e,t,n)=>{const i=[...q];i[e]={...i[e],[t]:n},$(i)},xe=(e,t,n)=>{const i=[...H];i[e]={...i[e],[t]:n},Q(i)};return t.useEffect(()=>{if(e.options,e.options.RedirectRequestCodes&&x(e.options.RedirectRequestCodes.split(",").filter(e=>e)),e.options.RedirectErrorMessages&&y(e.options.RedirectErrorMessages.split(",").filter(e=>e)),e.options.ErrorLogWhitelist?v(e.options.ErrorLogWhitelist.split("\n").filter(e=>e.trim())):v([]),e.options.AutomaticDisableKeywords){const t=e.options.AutomaticDisableKeywords.split("\n").map(e=>e.trim()).filter(e=>e);I(t)}else I([]);if(e.options.NoRetryErrors){const t=e.options.NoRetryErrors.split("\n").map(e=>e.trim()).filter(e=>e);N(t)}else N([]);if(e.options.AutoSortChannelWhitelist){const t=e.options.AutoSortChannelWhitelist.split("\n").map(e=>e.trim()).filter(e=>e);L(t)}else L([]);if(e.options.ErrorCountWhitelist){const t=e.options.ErrorCountWhitelist.split("\n").map(e=>e.trim()).filter(e=>e);J(t)}else J([]);const t=e.options.EnabledMenus?e.options.EnabledMenus.split(",").filter(e=>e):[],n=e.options.EnabledSideMenus?e.options.EnabledSideMenus.split(",").filter(e=>e):[],i=e.options.LogQueryLimit||"100000",s="true"===e.options.FixedLogTotalEnabled||!0===e.options.FixedLogTotalEnabled;if(e.options.AccountDailyLimitSettings)try{const t=JSON.parse(e.options.AccountDailyLimitSettings);G(t.enabled||!1);const n=Ne(),i=(t.groups||[]).map(e=>({accounts:e.accounts,limit:parseFloat((e.limit/n).toFixed(2))}));$(i)}catch(a){console.error("解析账号每日消耗限制设置失败:",a),G(!1),$([])}if(e.options.CustomMenuLinks)try{const t=JSON.parse(e.options.CustomMenuLinks);Q(Array.isArray(t)?t:[])}catch(a){console.error("解析自定义菜单链接设置失败:",a),Q([])}else Q([]);const l={enabled_menus:t,enabled_side_menus:n,log_query_limit:i,fixed_log_total_enabled:s};ne(l),Z&&Z.setValues(l)},[e.options,Z]),n.jsx(m,{spinning:s,children:n.jsxs(a,{initValues:te,getFormApi:e=>{ee(e),(te.enabled_menus.length||te.enabled_side_menus.length)&&setTimeout(()=>{e.setValues(te)},0)},onValueChange:e=>{},style:{marginBottom:15},children:[n.jsxs(a.Section,{text:i("日志查询设置"),children:[n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"log_query_limit",label:i("日志查询记录限制"),placeholder:i("默认值:100000"),helpText:i("设置日志查询时的最大记录数限制,用于提升大数据量查询性能。如果设置为0或负数,将使用默认值100000"),style:{width:"100%"}})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Switch,{field:"fixed_log_total_enabled",label:i("启用固定日志总数"),checkedText:i("开"),uncheckedText:i("关"),helpText:i("开启后使用固定数量作为日志总数,不执行COUNT查询以提升性能;关闭后将显示真实的日志总数")})})]}),n.jsx(d,{onClick:async()=>
1{if(!Z)return;const t=Z.getValues(),n=parseInt(t.log_query_limit,10);isNaN(n)?je(i("请输入有效的数字")):(await le([{key:"LogQueryLimit",value:t.log_query_limit},{key:"FixedLogTotalEnabled",value:t.fixed_log_total_enabled?"true":"false"}]),e.refresh())},style:{marginTop:16},children:i("保存日志查询设置")})]}),n.jsxs(a.Section,{text:i("错误日志详细记录白名单"),children:[n.jsx(u.Text,{type:"tertiary",style:{display:"block",marginBottom:16},children:i("如果错误日志包含白名单中的关键词,将在日志content字段记录这条错误信息,展现给用户查看")}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(p,{value:S,onChange:v,placeholder:i("输入关键词后回车"),style:{width:"100%"}})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{placeholder:i("输入新的白名单关键词"),value:C,onChange:e=>w(e),suffix:n.jsx(d,{onClick:pe,children:i("添加")}),onEnterPress:pe})})]}),n.jsx(d,{onClick:async()=>{Array.isArray(S)?(await le([{key:"ErrorLogWhitelist",value:S.join("\n")}]),e.refresh()):je(i("错误日志白名单格式不正确"))},style:{marginTop:16},children:i("保存错误日志白名单")})]}),n.jsxs(a.Section,{text:i("用户每日消耗限制"),children:[n.jsx(u.Text,{type:"tertiary",style:{display:"block",marginBottom:16},children:i("控制用户的每日总消耗上限。同一组内的用户共享消耗上限,达到上限后该组用户的请求将被拒绝。")}),n.jsx(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:n.jsx(c,{xs:24,children:n.jsxs("div",{style:{display:"flex",alignItems:"center",marginBottom:16},children:[n.jsx("span",{style:{marginRight:8},children:i("启用用户每日消耗限制")}),n.jsx(E,{checked:K,onChange:G,checkedText:i("开"),uncheckedText:i("关")})]})})}),K&&n.jsxs(n.Fragment,{children:[q.map((e,t)=>n.jsx(r,{style:{marginBottom:16},title:`${i("配置组")} ${t+1}`,headerExtraContent:n.jsx(d,{type:"danger",theme:"borderless",icon:n.jsx(He,{size:16}),onClick:()=>(e=>{const t=[...q];t.splice(e,1),$(t)})(t),children:i("删除")}),children:n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsxs(c,{xs:24,sm:24,md:16,lg:16,xl:16,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx(u.Text,{strong:!0,children:i("用户名列表")}),n.jsx(u.Text,{type:"tertiary",style:{marginLeft:8},children:i("输入用户名后回车添加")})]}),n.jsx(p,{value:e.accounts,onChange:e=>he(t,"accounts",e),placeholder:i("输入用户名后回车,例如:hw-1"),style:{width:"100%"}})]}),n.jsxs(c,{xs:24,sm:24,md:8,lg:8,xl:8,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx(u.Text,{strong:!0,children:i("每日消耗上限")}),n.jsx(u.Text,{type:"tertiary",style:{marginLeft:8},children:i("单位:美元")})]}),n.jsx(M,{value:e.limit,onChange:e=>he(t,"limit",e),min:.01,step:.1,precision:2,style:{width:"100%"},placeholder:i("例如:10 表示 $10"),prefix:"$"})]})]})},t)),n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>{$([...q,{accounts:[],limit:10}])},style:{marginBottom:16},children:i("添加配置组")})]}),n.jsx("div",{children:n.jsx(d,{onClick:async()=>{for(let e=0;e<q.length;e++){const t=q[e];if(!t.accounts||0===t.accounts.length)return void je(i("用户每日消耗限制配置")+` ${e+1}: `+i("用户名列表不能为空"));if(!t.limit||t.limit<=0)return void je(i("用户每日消耗限制配置")+` ${e+1}: `+i("消耗上限必须大于0"))}const t=Ne(),n=q.map(e=>({accounts:e.accounts,limit:Math.round(e.limit*t)})),s={enabled:K,groups:n};await le([{key:"AccountDailyLimitSettings",value:JSON.stringify(s)}]),e.refresh()},style:{marginTop:16},children:i("保存用户每日消耗限制设置")})})]}),n.jsxs(a.Section,{text:i("菜单显示设置"),children:[n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Select,{field:"enabled_menus",label:i("顶部菜单"),placeholder:i("选择要显示的顶部菜单"),multiple:!0,style:{width:"100%"},optionList:ie.map(e=>({label:e.label,value:e.value}))})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Select,{field:"enabled_side_menus",label:i("侧边栏菜单"),placeholder:i("选择要显示的侧边栏菜单"),multiple:!0,style:{width:"100%"},optionList:se.map(e=>({label:e.label,value:e.value}))})})]}),n.jsx(d,{onClick:async()=>
1{if(!Z)return;const t=Z.getValues();await le([{key:"EnabledMenus",value:(t.enabled_menus||[]).join(",")},{key:"EnabledSideMenus",value:(t.enabled_side_menus||[]).join(",")}]),e.refresh()},style:{marginTop:16},children:i("保存菜单设置")})]}),n.jsxs(a.Section,{text:i("自定义菜单链接"),children:[n.jsx(u.Text,{type:"tertiary",style:{display:"block",marginBottom:16},children:i("添加自定义菜单链接,将在顶部导航栏和侧边栏中显示,点击后跳转到指定地址")}),H.map((e,t)=>n.jsx(r,{style:{marginBottom:16},title:`${i("链接")} ${t+1}`,headerExtraContent:n.jsx(d,{type:"danger",theme:"borderless",icon:n.jsx(He,{size:16}),onClick:()=>(e=>{const t=[...H];t.splice(e,1),Q(t)})(t),children:i("删除")}),children:n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsxs(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx(u.Text,{strong:!0,children:i("名称")}),n.jsx(u.Text,{type:"tertiary",style:{marginLeft:8},children:i("显示在菜单中的名称")})]}),n.jsx(k,{value:e.name,onChange:e=>xe(t,"name",e),placeholder:i("例如:帮助中心"),style:{width:"100%"}})]}),n.jsxs(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx(u.Text,{strong:!0,children:i("链接地址")}),n.jsx(u.Text,{type:"tertiary",style:{marginLeft:8},children:i("点击后跳转的URL")})]}),n.jsx(k,{value:e.url,onChange:e=>xe(t,"url",e),placeholder:i("例如:https://help.example.com"),style:{width:"100%"}})]})]})},t)),n.jsx(d,{icon:n.jsx(Ye,{size:16}),onClick:()=>{Q([...H,{name:"",url:""}])},style:{marginBottom:16},children:i("添加链接")}),n.jsx("div",{children:n.jsx(d,{onClick:async()=>{for(let e=0;e<H.length;e++){const t=H[e];if(!t.name||""===t.name.trim())return void je(i("自定义菜单链接")+` ${e+1}: `+i("名称不能为空"));if(!t.url||""===t.url.trim())return void je(i("自定义菜单链接")+` ${e+1}: `+i("链接地址不能为空"))}await le([{key:"CustomMenuLinks",value:JSON.stringify(H)}]),e.refresh()},style:{marginTop:16},children:i("保存自定义菜单链接")})})]}),n.jsxs(a.Section,{text:i("重定向错误码设置"),children:[n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},style:{marginTop:16},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(p,{value:h,onChange:x,placeholder:i("输入错误码后回车"),style:{width:"100%"}})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{placeholder:i("输入新的重定向错误码"),value:j,onChange:e=>f(e),suffix:n.jsx(d,{onClick:de,children:i("添加")}),onEnterPress:de})})]}),n.jsx(d,{onClick:async()=>{Array.isArray(h)?(await le([{key:"RedirectRequestCodes",value:h.join(",")}]),e.refresh()):je(i("重定向错误码格式不正确"))},style:{marginTop:16},children:i("保存重定向错误码设置")})]}),n.jsxs(a.Section,{text:i("敏感错误信息屏蔽设置"),children:[n.jsx(u.Text,{type:"tertiary",style:{display:"block",marginBottom:16},children:i("屏蔽包含敏感关键词的错误信息,防止敏感信息(如余额不足、API密钥等)泄露给用户")}),n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("已添加的屏蔽关键词")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("点击标签可删除该关键词")})]}),n.jsx(p,{value:g,onChange:y,placeholder:i("输入关键词后回车添加"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("添加新的屏蔽关键词")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("输入后点击添加按钮或按回车")})]}),n.jsx(k,{placeholder:i("输入关键词,例如:余额不足"),value:b,onChange:e=>_(e),suffix:n.jsx(d,{onClick:ue,children:i("添加")}),onEnterPress:ue})]})]}),n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",backgroundColor:"#fff1f0"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:i("sensitive_info_shield_title")}),n.jsx("div",{style:{fontSize:"12px",color:"#666"},children:n.jsx(ln,{i18nKey:"sensitive_info_shield_desc",components:{br:n.jsx("br",{}),code:n.jsx("code",{})}})})]})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async()=>{Array.isArray(g)?(await le([{key:"RedirectErrorMessages",value:g.join(",")}]),e.refresh()):je(i("重定向错误消息格式不正确"))},children:i("保存敏感信息屏蔽设置")})})]}),n.jsxs(a.Section,{text:i("渠道失败统计豁免白名单"),children:[n.jsx(u.Text,{type:"tertiary",style:{display:"block",marginBottom:16},children:i("当请求失败时,如果错误码或错误消息包含白名单中的任何一项ï¼
1Œåˆ™ä¸ä¼šè®°å½•为渠道失败")}),n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("已添加的豁免关键词")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("点击标签可删除该关键词")})]}),n.jsx(p,{value:W,onChange:J,placeholder:i("输入关键词后回车添加"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("添加新的豁免关键词")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("输入后点击添加按钮或按回车")})]}),n.jsx(k,{placeholder:i("输入关键词,例如:invalid_request_error"),value:U,onChange:e=>V(e),suffix:n.jsx(d,{onClick:ce,children:i("添加")}),onEnterPress:ce})]})]}),n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",backgroundColor:"#f0f9ff"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:i("error_count_whitelist_title")}),n.jsx("div",{style:{fontSize:"12px",color:"#666"},children:n.jsx(ln,{i18nKey:"error_count_whitelist_desc",components:{br:n.jsx("br",{}),code:n.jsx("code",{}),strong:n.jsx("strong",{})}})})]})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async()=>{Array.isArray(W)?(await le([{key:"ErrorCountWhitelist",value:W.join("\n")}]),e.refresh()):je(i("错误计数白名单格式不正确"))},children:i("保存渠道失败统计豁免白名单")})})]}),n.jsxs(a.Section,{text:i("智能排序跳过分组白名单"),children:[n.jsx(u.Text,{type:"tertiary",style:{display:"block",marginBottom:16},children:i("在白名单中的分组将跳过智能排序,直接按照优先级和权重选择渠道")}),n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("已添加的分组名")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("点击标签可删除该分组")})]}),n.jsx(p,{value:D,onChange:L,placeholder:i("输入分组名后回车添加"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("添加新的分组名")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("输入后点击添加按钮或按回车")})]}),n.jsx(k,{placeholder:i("输入分组名,例如:default"),value:B,onChange:e=>F(e),suffix:n.jsx(d,{onClick:oe,children:i("添加")}),onEnterPress:oe})]})]}),n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",backgroundColor:"#fffbe6"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:i("auto_sort_whitelist_title")}),n.jsx("div",{style:{fontSize:"12px",color:"#666"},children:n.jsx(ln,{i18nKey:"auto_sort_whitelist_desc",components:{br:n.jsx("br",{}),code:n.jsx("code",{})}})})]})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async()=>{Array.isArray(D)?(await le([{key:"AutoSortChannelWhitelist",value:D.join("\n")}]),e.refresh()):je(i("智能排序白名单格式不正确"))},children:i("保存智能排序跳过分组白名单")})})]}),n.jsxs(a.Section,{text:i("请求失败不重试错误配置"),children:[n.jsx(u.Text,{type:"tertiary",style:{display:"block",marginBottom:16},children:i("当上游通道返回错误中包含这些错误时,不重试其他渠道,直接返回错误给用户")}),n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("已添加的错误关键词")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("点击标签可删除该关键词")})]}),n.jsx(p,{value:z,onChange:N,placeholder:i("输入错误关键词后回车添加"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("添加新的错误关键词")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("输入后点击添加按钮或按回车")})]}),n.jsx(k,{placeholder:i("输入错误关键词,例如:content_filter"),value:A,onChange:e=>O(e),suffix:n.jsx(d,{onClick:re,children:i("添加")}),onEnterPress:re})]})]}),n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",backgroundColor:"#f6ffed"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:i("no_retry_error_title")}),n.jsx("div",{style:{fontSize:"12px",color:"#666"},children:n.jsx(ln,{i18nKey:"no_retry_error_desc",components:{br:n.jsx("br",{}),code:n.jsx("code",{})}})})]})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async()=>{Array.isArray(z)?(await le([{key:"NoRetryErrors",value:z.join("\n")}]),e.refresh()):je(i("不重试错误格式不正确"))},children:i("保存不重试错误设置")})})]}),n.jsxs(a.Section,{text:i("渠道禁用触发关键词配置"),children:[n.jsx(u.Text,{type:"tertiary",style:{display:"block",marginBottom:16},children:i("当上游通道返回错误中包含这些关键词时(不区分大小写),将自动禁用该渠道")}),n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("strong",{children:i("已添加的触发关键词")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("点击标签可删除该关键词")})]}),n.jsx(p,{value:T,onChange:I,placeholder:i("输入关键词后回车添加"),style:{width:"100%"}})]}),n.jsxs(c,{span:12,children:[n.jsxs("div",{style:{marginBottom:8}
1,children:[n.jsx("strong",{children:i("添加新的触发关键词")}),n.jsx("div",{style:{fontSize:"12px",color:"#666",marginTop:4},children:i("输入后点击添加按钮或按回车")})]}),n.jsx(k,{placeholder:i("输入关键词,例如:invalid_api_key"),value:R,onChange:e=>P(e),suffix:n.jsx(d,{onClick:ae,children:i("添加")}),onEnterPress:ae})]})]}),n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"10px",border:"1px solid #e8e8e8",borderRadius:"4px",backgroundColor:"#fff7e6"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:i("auto_disable_title")}),n.jsx("div",{style:{fontSize:"12px",color:"#666"},children:n.jsx(ln,{i18nKey:"auto_disable_desc",components:{br:n.jsx("br",{}),code:n.jsx("code",{})}})})]})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async()=>{Array.isArray(T)?(await le([{key:"AutomaticDisableKeywords",value:T.join("\n")}]),e.refresh()):je(i("自动禁用关键词格式不正确"))},children:i("保存渠道禁用触发关键词")})})]})]},X)})}function bl(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({WxPusherToken:"",WxPusherUid:"",WxPusherNotificationEnabled:!1,EmailNotificationEnabled:!1,ServerAddress:""}),p=t.useRef(null),h=async(e,t)=>{const n=t.target.checked,i={...r};i[e]=n,u(i),p.current&&p.current.setValue(e,n)};return t.useEffect(()=>{e.options;const t={WxPusherToken:e.options.WxPusherToken||"",WxPusherUid:e.options.WxPusherUid||"",WxPusherNotificationEnabled:!0===e.options.WxPusherNotificationEnabled,EmailNotificationEnabled:!0===e.options.EmailNotificationEnabled,ServerAddress:e.options.ServerAddress||""};u(t),p.current&&p.current.setValues(t)},[e.options]),n.jsx(m,{spinning:s,children:n.jsx(a,{initValues:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("通知推送设置"),children:[n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Checkbox,{field:"WxPusherNotificationEnabled",noLabel:!0,onChange:e=>h("WxPusherNotificationEnabled",e),children:i("启用微信推送通知")})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Checkbox,{field:"EmailNotificationEnabled",noLabel:!0,onChange:e=>h("EmailNotificationEnabled",e),children:i("启用邮件通知")})})]}),n.jsxs(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:[n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"WxPusherToken",label:i("微信推送Token"),placeholder:i("请输入WxPusher的Token"),style:{width:"100%"}})}),n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"WxPusherUid",label:i("微信推送UID"),placeholder:i("请输入WxPusher的UID"),style:{width:"100%"}})})]}),n.jsx(a.Label,{children:i("回调地址")}),n.jsx(k,{readOnly:!0,suffix:n.jsx(d,{icon:"copy",onClick:()=>{navigator.clipboard.writeText(`${r.ServerAddress}/api/push/wxpusher_callback`),be(i("回调地址已复制到剪贴板"))},children:i("复制")}),value:`${r.ServerAddress||""}/api/push/wxpusher_callback`,style:{marginTop:8,marginBottom:16}}),n.jsx(d,{onClick:async()=>{const t=p.current.getValues();await(async e=>{l(!0);try{const t=Se(),n=e.map(e=>ye.put(t,{key:e.key,value:"boolean"==typeof e.value?e.value.toString():e.value})),s=(await Promise.all(n)).filter(e=>!e.data.success);s.length>0?s.forEach(e=>{je(e.data.message)}):be(i("更新成功"))}catch(t){je(i("更新失败"))}l(!1)})([{key:"WxPusherToken",value:t.WxPusherToken||""},{key:"WxPusherUid",value:t.WxPusherUid||""},{key:"WxPusherNotificationEnabled",value:t.WxPusherNotificationEnabled},{key:"EmailNotificationEnabled",value:t.EmailNotificationEnabled}]),e.refresh()},style:{marginTop:16},children:i("保存通知设置")}),n.jsxs("div",{style:{marginTop:8,fontSize:"12px",color:"#666"},children:[i("微信推送: ")+(r.WxPusherNotificationEnabled?i("已启用"):i("未启用")),n.jsx("br",{}),i("邮件通知")+": "+(r.EmailNotificationEnabled?i("已启用"):i("未启用"))]})]})})})}function _l(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({RatioChangeNotifyEnabled:!1,RatioChangeNotifyWebhookURL:""}),p=t.useRef(null);return t.useEffect(()=>{const t={RatioChangeNotifyEnabled:!0===e.options.RatioChangeNotifyEnabled,RatioChangeNotifyWebhookURL:e.options.RatioChangeNotifyWebhookURL||""};u(t),p.current&&p.current.setValues(t)},[e.options]),n.jsx(m,{spinning:s,children:n.jsx(a,{initValues:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("模型倍率变更通知"),children:[n.jsx(h,{type:"info",description:i("开启后,当模型倍率、补全倍率或模型固定价格被修改并实际发生变化æ—
1¶ï¼Œç³»ç»Ÿä¼šè‡ªåŠ¨å°†å˜æ›´çš„æ¨¡åž‹ï¼ˆæ—§å€¼â†’æ–°å€¼ï¼‰åˆå¹¶æŽ¨é€åˆ°ä¼ä¸šå¾®ä¿¡ç¾¤ã€‚"),style:{marginBottom:16}}),n.jsx(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:n.jsx(c,{xs:24,sm:24,md:12,lg:12,xl:12,children:n.jsx(a.Checkbox,{field:"RatioChangeNotifyEnabled",noLabel:!0,onChange:e=>((e,t)=>{const n=t.target.checked,i={...r};i[e]=n,u(i),p.current&&p.current.setValue(e,n)})("RatioChangeNotifyEnabled",e),children:i("启用模型倍率变更通知")})})}),n.jsx(o,{gutter:{xs:8,sm:16,md:24,lg:24,xl:24,xxl:24},children:n.jsx(c,{xs:24,sm:24,md:24,lg:18,xl:18,children:n.jsx(a.Input,{field:"RatioChangeNotifyWebhookURL",label:i("企业微信群机器人 Webhook 地址"),placeholder:"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx",style:{width:"100%"}})})}),n.jsx(d,{onClick:async()=>{const t=p.current.getValues();await(async e=>{l(!0);try{const t=Se(),n=e.map(e=>ye.put(t,{key:e.key,value:"boolean"==typeof e.value?e.value.toString():e.value})),s=(await Promise.all(n)).filter(e=>!e.data.success);s.length>0?s.forEach(e=>{je(e.data.message)}):be(i("更新成功"))}catch(t){je(i("更新失败"))}l(!1)})([{key:"RatioChangeNotifyEnabled",value:!!t.RatioChangeNotifyEnabled},{key:"RatioChangeNotifyWebhookURL",value:t.RatioChangeNotifyWebhookURL||""}]),e.refresh()},style:{marginTop:16},children:i("保存设置")}),n.jsxs("div",{style:{marginTop:8,fontSize:"12px",color:"#666"},children:[i("倍率变更通知")+": ",r.RatioChangeNotifyEnabled?i("已启用"):i("未启用")]})]})})})}const{Text:Sl}=u,kl=e=>{const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({Keywords:"",BaiduOcpcToken:"",StatisticsCode:"",SEOPageConfigs:"[]",SeoTitle:"",Disclaimer:""}),p=t.useRef(),[h,g]=t.useState(r),[y,f]=t.useState([]),[b,_]=t.useState(!1),[S,k]=t.useState({path:"",title:"",description:"",keywords:""}),[C,w]=t.useState(-1);function T(e){return t=>{u(n=>({...n,[e]:t}))}}t.useEffect(()=>{const t={};for(let s in e.options)Object.keys(r).includes(s)&&(t[s]=e.options[s]);const n={...r,...t};u(n),g(structuredClone(n)),p.current&&p.current.setValues(n);try{const t=e.options?.SEOPageConfigs||"[]",n=JSON.parse(t).map(e=>({path:e.path||"",title:e.title||"",description:e.description||"",keywords:e.keywords||""}));f(n)}catch(i){console.error("解析SEO配置失败:",i),f([])}},[e.options]);const I=(e,t)=>{k(n=>({...n,[e]:t}))},E=[{title:i("页面路径"),dataIndex:"path",render:e=>e.endsWith("*")?n.jsxs(n.Fragment,{children:[e," ",n.jsx(j,{color:"blue",children:i("前缀匹配")})]}):e},{title:i("标题"),dataIndex:"title",width:200},{title:i("描述"),dataIndex:"description",width:300,ellipsis:!0},{title:i("关键词"),dataIndex:"keywords",width:200,ellipsis:!0},{title:i("操作"),width:120,render:(e,t,s)=>n.jsxs(n.Fragment,{children:[n.jsx(d,{theme:"light",type:"primary",style:{marginRight:8},onClick:()=>((e,t)=>{k({path:e.path||"",title:e.title||"",description:e.description||"",keywords:e.keywords||""}),w(t),_(!0)})(t,s),children:i("编辑")}),n.jsx(d,{theme:"light",type:"danger",onClick:()=>(e=>{const t=[...y];t.splice(e,1),f(t)})(s),children:i("删除")})]})}];return n.jsxs(n.Fragment,{children:[n.jsx(m,{spinning:s,children:n.jsxs(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:i("网站基础设置"),children:[n.jsx(o,{children:n.jsx(c,{span:24,children:n.jsx(a.Input,{field:"SeoTitle",label:i("网站SEO标题"),placeholder:i("在此输入网站的SEO标题,将显示在浏览器标签页和搜索结果中"),onChange:T("SeoT
1itle")})})}),n.jsx(o,{children:n.jsx(c,{span:24,children:n.jsx(a.TextArea,{field:"Disclaimer",label:i("用户协议/免责声明"),placeholder:i("在此输入用户协议内容,支持 Markdown & HTML 代码"),onChange:T("Disclaimer"),style:{fontFamily:"JetBrains Mono, Consolas"},autosize:{minRows:4,maxRows:8}})})})]}),n.jsxs(a.Section,{text:i("SEO全局设置"),children:[n.jsx(o,{children:n.jsx(c,{span:24,children:n.jsx(a.TextArea,{field:"Keywords",label:i("全局关键词"),placeholder:i("请输入关键词,多个关键词用英文逗号分隔"),onChange:T("Keywords")})})}),n.jsx(o,{style:{marginTop:16},children:n.jsxs(c,{span:24,children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16},children:[n.jsx(Sl,{strong:!0,children:i("页面SEO设置")}),n.jsx(d,{icon:n.jsx(Ye,{size:16}),type:"primary",onClick:()=>{k({path:"",title:"",description:"",keywords:""}),w(-1),_(!0)},children:i("添加页面")})]}),n.jsx(v,{columns:E,dataSource:y,pagination:!1,size:"small",empty:i("暂无页面SEO配置")})]})})]}),n.jsxs(a.Section,{text:i("统计代码"),children:[n.jsx(o,{children:n.jsx(c,{span:24,children:n.jsx(a.Input,{field:"BaiduOcpcToken",label:i("百度 OCPC Token"),placeholder:i("请输入百度 OCPC Token(例如:_f7L2XwGXjyszb4d1e2oxPybgD)"),onChange:T("BaiduOcpcToken")})})}),n.jsx(o,{children:n.jsx(c,{span:24,children:n.jsx(a.TextArea,{field:"StatisticsCode",label:i("统计代码"),placeholder:i("请输入统计代码(如Google Analytics、百度统计等)"),onChange:T("StatisticsCode"),style:{fontFamily:"JetBrains Mono, Consolas"},autosize:{minRows:3,maxRows:6}})})})]}),n.jsx(o,{style:{marginTop:8},children:n.jsx(d,{size:"default",onClick:function(){const t=JSON.stringify(y),n={...r,SEOPageConfigs:t},s=t!==(h.SEOPageConfigs||"[]"),a=ke(n,h);if(!a.length&&!s)return ve(i("你似乎并没有修改什么"));const o=[],c=Se();if(a.forEach(e=>{let t="";t="boolean"==typeof n[e.key]?String(n[e.key]):n[e.key],o.push(ye.put(c,{key:e.key,value:t}))}),s&&o.push(ye.put(c,{key:"SEOPageConfigs",value:t})),0===o.length)return ve(i("你似乎并没有修改什么"));l(!0),Promise.all(o).then(t=>{if(1===o.length){if(t.includes(void 0))return}else if(o.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh(),u(n),g({...n})}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存SEO与网站设置")})})]})}),n.jsx(x,{title:i(C>=0?"编辑页面SEO":"添加页面SEO"),visible:b,onOk:()=>{if(S.path){if(C>=0){const e=[...y];e[C]={...S},f(e)}else{if(y.some(e=>e.path===S.path))return void je(i("该页面路径已存在"));f([...y,{...S}])}_(!1)}else je(i("页面路径不能为空"))},onCancel:()=>{_(!1)},closeOnEsc:!0,width:600,children:b&&n.jsxs(a,{initValues:S,children:[n.jsx(a.Input,{field:"path",label:i("页面路径"),placeholder:i("例如: /chat 或 /chat/* (通配符匹配所有chat子页面)"),onChange:e=>I("path",e),help:i("以/开头的路径。使用*作为通配符可以匹配以相同前缀开头的所有页面"),required:!0}),n.jsx(a.Input,{field:"title",label:i("页面标题"),placeholder:i("页面标题"),onChange:e=>I("title",e),help:i("不需要包含系统名称,系统会自动添加")}),n.jsx(a.TextArea,{field:"description",label:i("页面描述"),placeholder:i("页面描述"),onChange:e=>I("description",e),rows:3}
1),n.jsx(a.TextArea,{field:"keywords",label:i("页面关键词"),placeholder:i("页面关键词,多个关键词用英文逗号分隔"),onChange:e=>I("keywords",e),rows:3}),n.jsx("div",{style:{marginTop:8},children:n.jsxs(Sl,{type:"tertiary",children:[i("当前值"),": ",JSON.stringify(S)]})})]})})]})},vl=e=>{const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({DetailLogEnabled:!1,DetailLogBodyEnabled:!0,StreamTruncationLogEnabled:!1,StreamTruncationLogRetentionDays:7,DetailLogExcludeUserIds:"",SecurityAuditEnabled:!1,SecurityAuditMonitorUserIds:"",MaxDetailLogNum:1e4,BigDataThreshold:2e4,LogBodyMaxLength:5e4,LogPageSizeLimit:5e3,DefaultLabGroup:"default",MaxPromptTokens:1e6,ProporTions:"",InviteRewardEnabled:!1,RequestBodySizeLimitEnabled:!1,MaxRequestBodySizeMB:20,RegisterRateLimitEnabled:!1,RegisterRateLimitPerHour:20,RegisterRateLimitPerDay:50,SysLoadShedEnabled:!1,SysLoadCPUThreshold:85,SysLoadMemThreshold:85,SysLoadSampleInterval:5,ExportGlobalConcurrencyLimit:100,ExportPerUserConcurrencyLimit:1,"hongming_sso.show_agent_domains":"",ExternalDisableChannelEnabled:!1,ExternalDisableChannelSecret:""}),p=t.useRef(),[h,x]=t.useState(r);function g(e){return t=>{u(n=>({...n,[e]:t}))}}return t.useEffect(()=>{const t={};for(let i in e.options)if(Object.keys(r).includes(i)){const n=e.options[i];"boolean"==typeof r[i]?t[i]=!0===n||"true"===n:t[i]=n}const n={...r,...t};u(n),x(structuredClone(n)),p.current&&p.current.setValues(n)},[e.options]),n.jsx(m,{spinning:s,children:n.jsxs(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:[n.jsxs(a.Section,{text:i("系统日志配置"),children:[n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"DetailLogEnabled",label:i("启用详细日志记录"),size:"large",checkedText:"|",uncheckedText:"〇",onChange:g("DetailLogEnabled")})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"DetailLogBodyEnabled",label:i("存储请求/响应体"),size:"large",checkedText:"|",uncheckedText:"〇",onChange:g("DetailLogBodyEnabled"),extraText:i("关闭后不存储请求体与响应体,仅保留错误日志")})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"StreamTruncationLogEnabled",label:i("启用流式截断日志"),size:"large",checkedText:"|",uncheckedText:"〇",onChange:g("StreamTruncationLogEnabled"),extraText:i("记录上游/本服务侧导致的异常流式中断(不含用户主动断开)")})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"StreamTruncationLogRetentionDays",label:i("流式截断日志保留天数"),placeholder:i("请输入保留天数"),onChange:g("StreamTruncationLogRetentionDays"),extraText:i("超过该天数的流式截断日志将被定时清理"),showClear:!0})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"DetailLogExcludeUserIds",label:i("详细日志排除用户ID"),placeholder:i("输入用户ID,多个用逗号分隔"),onChange:g("DetailLogExcludeUserIds"),extraText:i("这些用户不记录详细日志(仍记录消费日志),用于减少同步用户的日志量"),showClear:!0})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"MaxDetailLogNum",label:i("详细日志记录最大条数"),placeholder:i("请输入详细日志记录最大条数"),onChange:g("MaxDetailLogNum"),showClear:!0})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"BigDataThreshold",label:i("大数据字段过滤阈值(字节)"),placeholder:i("请输入大数据字段过滤阈值"),onChange:g("BigDataThreshold"),extraText:i("设置为0表示存储时不过滤,查看时使用默认值20000字节"),showClear:!0})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"LogBodyMaxLength",label:i("日志体最大长度(字符数)"),placeholder:i("请输入日志体最大长度"),onChange:g("LogBodyMaxLength"),extraText:i("设置为0表示不限制,仅在存储时生效,查看时不限制"),showClear:!0})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"LogPageSizeLimit",label:i("日志查询单页最大记录数"),placeholder:i("请输入日志查询单页最大记录数"),onChange:g("LogPageSizeLimit"),showClear:!0})})]}),n.jsx(o,{gutter:16,style:{marginTop:16},children:n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"MaxPromptTokens",label:i("最大允许的提示词Token数"),placeholder:i("请输入最大允许的提示词Token数"),onChange:g("MaxPromptTokens"),showClear:!0})})}),n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsx(c,{xs:24,sm:8,md:6,lg:6,xl:6,children:n.jsx(a.Switch,{field:"SecurityAuditEnabled",label:i("启用涉密审计采集"),size:"large",checkedText:"|",uncheckedText:"〇",onChange:g("SecurityAuditEnabled"),extraText:i("总开关,默认关闭。关闭后无论是否配置监控用户ID
1都不采集;开启后仅采集右侧监控用户ID")})}),n.jsx(c,{xs:24,sm:16,md:18,lg:18,xl:18,children:n.jsx(a.Input,{field:"SecurityAuditMonitorUserIds",label:i("涉密审计监控用户ID"),placeholder:i("输入用户ID,多个用逗号分隔"),onChange:g("SecurityAuditMonitorUserIds"),extraText:i("仅这些用户的请求体/响应体会被采集到独立库表(需开启左侧总开关、配置环境变量 SECURITY_AUDIT_SQL_DSN 且开启详细日志采集)"),showClear:!0})})]})]}),n.jsx(a.Section,{text:i("实验室分组设置"),children:n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Select,{field:"DefaultLabGroup",label:i("实验室默认分组"),placeholder:i("请选择实验室默认分组"),onChange:g("DefaultLabGroup"),children:Object.entries((()=>{try{const t=e.options?.UserUsableGroups||"{}";return JSON.parse(t)}catch(t){return{}}})()).map(([e,t])=>n.jsx(a.Select.Option,{value:e,children:t},e))})})})}),n.jsx(a.Section,{text:i("用户奖励设置"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"InviteRewardEnabled",label:i("启用邀请奖励功能"),size:"large",checkedText:"|",uncheckedText:"〇",onChange:g("InviteRewardEnabled")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Input,{field:"ProporTions",label:i("奖励比例"),placeholder:i("请输入奖励比例(百分比)"),onChange:g("ProporTions"),showClear:!0})})]})}),n.jsx(a.Section,{text:i("请求体大小限制"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"RequestBodySizeLimitEnabled",label:i("启用请求体大小限制"),size:"large",checkedText:"|",uncheckedText:"〇",onChange:g("RequestBodySizeLimitEnabled")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"MaxRequestBodySizeMB",label:i("最大请求体大小(MB)"),placeholder:i("请输入最大请求体大小(MB)"),onChange:g("Max
1RequestBodySizeMB"),min:1,max:1024,style:{width:"100%"}})})]})}),n.jsx(a.Section,{text:i("注册频率限制"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.Switch,{field:"RegisterRateLimitEnabled",label:i("启用注册频率限制"),size:"large",checkedText:"|",uncheckedText:"〇",onChange:g("RegisterRateLimitEnabled"),extraText:i("限制同一IP的注册频率,防止机器人批量刷号")})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"RegisterRateLimitPerHour",label:i("同IP每小时注册上限"),placeholder:"20",onChange:g("RegisterRateLimitPerHour"),min:1,max:1e3,style:{width:"100%"},extraText:i("建议值:20(历史数据:正常VPN峰值约10次/小时)")})}),n.jsx(c,{xs:24,sm:8,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"RegisterRateLimitPerDay",label:i("同IP每日注册上限"),placeholder:"50",onChange:g("RegisterRateLimitPerDay"),min:1,max:1e4,style:{width:"100%"},extraText:i("建议值:50(历史数据:正常VPN峰值约15次/天)")})})]})}),n.jsx(a.Section,{text:i("服务器负载熔断"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:8,md:6,lg:6,xl:6,children:n.jsx(a.Switch,{field:"SysLoadShedEnabled",label:i("启用负载熔断"),size:"large",checkedText:"|",uncheckedText:"〇",onChange:g("SysLoadShedEnabled"),extraText:i("CPU 或内存超阈值时自动拒绝新请求,返回 503")})}),n.jsx(c,{xs:24,sm:8,md:6,lg:6,xl:6,children:n.jsx(a.InputNumber,{field:"SysLoadCPUThreshold",label:i("CPU 熔断阈值(%)"),placeholder:"85",onChange:g("SysLoadCPUThreshold"),min:50,max:99,style:{width:"100%"},extraText:i("建议值:80,留 5% 余量防止 GC 抖动误触")})}),n.jsx(c,{xs:24,sm:8,md:6,lg:6,xl:6,children:n.jsx(a.InputNumber,{field:"SysLoadMemThreshold",label:i("内存熔断阈值(%)"),placeholder:"85",onChange:g("SysLoadMemThreshold"),min:50,max:99,style:{width:"100%"},extraText:i("建议值:80,超过后 GC 压力急剧上升")})}),n.jsx(c,{xs:24,sm:8,md:6,lg:6,xl:6,children:n.jsx(a.InputNumber,{field:"SysLoadSampleInterval",label:i("采集间隔(秒)"),placeholder:"5",onChange:g("SysLoadSampleInterval"),min:1,max:60,style:{width:"100%"},extraText:i("负载数据更新频率,默认 5 秒")})})]})}),n.jsx(a.Section,{text:i("导出任务并发限制"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"ExportGlobalConcurrencyLimit",label:i("单台服务器同时进行的导出任务上限"),placeholder:"100",onChange:g("ExportGlobalConcurrencyLimit"),min:1,max:1e3,style:{width:"100%"},extraText:i("每台服务器(节点)进程内同时处理的导出任务上限。集群下导出任务在接收请求的节点执行,按单节点内存控制;值越大该节点内存压力越高,负载高时建议调小")})}),n.jsx(c,{xs:24,sm:12,md:8,lg:8,xl:8,children:n.jsx(a.InputNumber,{field:"ExportPerUserConcurrencyLimit",label:i("单用户同时进行的导出任务上限"),placeholder:"1",onChange:g("ExportPerUserConcurrencyLimit"),min:1,max:100,style:{width:"100%"},extraText:i("单个用户同时进行(等待中/处理中)的导出任务数量上限")})})]})}),n.jsx(a.Section,{text:i("外部渠道禁用接口"),children:n.jsxs(o,{gutter:16,children:[n.jsx(c,{xs:24,sm:8,md:6,lg:6,xl:6,children:n.jsx(a.Switch,{field:"ExternalDisableChannelEnabled",label:i("启用外部渠道禁用接口"),size:"large",checkedText:"|",uncheckedText:"〇",onChange:g("ExternalDisableChannelEnabled"),extraText:i("开启后,第三方平台可通过 HMAC-SHA256 签名调用接口禁用渠道")})}),n.jsx(c,{xs:24,sm:16,md:12,lg:12,xl:12,children:n.jsx(a.Input,{field:"ExternalDisableChannelSecret",label:i("接口签名密钥"),placeholder:i("留空则不修改现有密钥"),mode:"password",onChange:g("ExternalDisableChannelSecret"),extraText:i("第三方平台使用此密钥对请求做 HMAC-SHA256 签名,建议使用 32 位以上随机字符串"),showClear:!0})})]})}),n.jsx(a.Section,{text:i("鸿溟SSO显示控制"),children:n.jsx(o,{gutter:16,children:n.jsx(c,{xs:24,sm:24,md:16,lg:16,xl:16,children:n.jsx(a.TextArea,{field:"hongming_sso.show_agent_domains",label:i("允许显示鸿溟SSO设置的代理站域名"),placeholder:i("多个域名用英文逗号分隔,例如:a.example.com,b.example.com"),rows:3,onChange:g("hongming_sso.show_agent_domains")})})})}),n.jsx(o,{style:{marginTop:8},children:n.jsx(d,{size:"default",onClick:function(){const t=ke(r,h);if(!t.length)return ve(i("你似乎并没有修改什么"));const n=Se(),s=t.map(e=>{let t="";return t="boolean"==typeof r[e.key]||"number"==typeof r[e.key]?String(r[e.key]):r[e.key],ye.put(n,{key:e.key,value:t})});l(!0),Promise.all(s).then(t=>{if(1===s.length){if(t.includes(void 0))return}else if(s.length>1&&t.includes(void 0))return je(i("部分保存失败,请重试"));be(i("保存成功")),e.refresh();const n=structuredClone(r);n.ExternalDisableChannelSecret="",u(e=>
1({...e,ExternalDisableChannelSecret:""})),x(n),p.current&&p.current.setValue("ExternalDisableChannelSecret","")}).catch(()=>{je(i("保存失败,请重试"))}).finally(()=>{l(!1)})},children:i("保存服务器配置")})})]})})},Cl={[Ft.EMAIL]:"CustomerSupportEmail",[Ft.PHONE]:"CustomerSupportPhone",[Ft.ONLINE_TIME]:"CustomerSupportOnlineTime",[Ft.WEIXIN]:"CustomerSupportWeixinLink",[Ft.WHATSAPP]:"CustomerSupportWhatsApp",[Ft.QRCODE]:"QRCodeUrl"};function wl(e){const t={};for(const[n,i]of Object.entries(Cl))t[n]=e[i]||"";return t}function Tl(e,t){const n=Wt(e.CustomerSupportContactOrder),i=Object.keys(Cl),s=t.map(e=>e.id);return Jt(n||Vt,i,s)}function Il(e){if(!e)return!0;try{const t=new URL(e);return"http:"===t.protocol||"https:"===t.protocol}catch{return!1}}const El=["email","phone","qrcode","link"],Rl=e=>{const{t:i}=ge(),[s,l]=t.useState(!1),[a,r]=t.useState({QRCodeUrl:"",CustomerSupportEmail:"",CustomerSupportPhone:"",CustomerSupportOnlineTime:"",CustomerSupportWeixinLink:"",CustomerSupportWhatsApp:"",CustomerSupportCustomEntries:"[]",CustomerSupportContactOrder:""}),[p,h]=t.useState(a),y=t.useRef(p);y.current=p;const[j,f]=t.useState(!1),[b,_]=t.useState("email"),[S,k]=t.useState(""),[v,C]=t.useState(""),[w,T]=t.useState(""),[I,E]=t.useState(""),[R,P]=t.useState(""),[z,N]=t.useState(""),A=an(e.options?.["translation_setting.enabled"]),M=hs(a.CustomerSupportCustomEntries),O=Tl(a,M);function D(e){r(t=>({...t,CustomerSupportContactOrder:JSON.stringify(e)}))}function L(e){r(t=>({...t,CustomerSupportCustomEntries:JSON.stringify(e)}))}t.useEffect(()=>{r(t=>{const n=y.current,i={...t},s=e.options||{};for(const e in s){if(!Object.prototype.hasOwnProperty.call(t,e))continue;const l=t[e]!==n[e];i[e]=l?t[e]:s[e]}i.CustomerSupportCustomEntries||(i.CustomerSupportCustomEntries="[]"),i.CustomerSupportContactOrder||(i.CustomerSupportContactOrder="");const l=Object.keys(t).some(e=>t[e]!==n[e]);return queueMicrotask(()=>{l||h(structuredClone(i))}),i})},[e.options]);const B=e=>({email:i("自定义联系分类_email"),phone:i("自定义联系分类_phone"),qrcode:i("自定义联系分类_qrcode"),link:i("自定义联系分类_link")}[e]||e);return n.jsxs(m,{spinning:s,children:[n.jsxs(g,{align:"center",style:{marginBottom:12},children:[n.jsx(u.Title,{heading:6,style:{margin:0},children:i("联系客服设置")}),n.jsx(d,{icon:n.jsx(Ye,{size:16}),type:"tertiary",size:"small",onClick:()=>{_("email"),k(""),C(""),T(""),E(""),P(""),N(""),f(!0)},children:i("添加自定义联系条目")})]}),n.jsx(bs,{order:O,builtinValues:wl(a),customEntries:M,onOrderChange:function(e){D(e)},onBuiltinChange:function(e,t){const n=Cl[e];n&&r(e=>({...e,[n]:t}))},onCustomEntriesChange:function(e){L(e);const t=new Set(e.map(e=>e.id));D(Tl(a,M).filter(e=>e.startsWith("builtin:")||t.has(e)))},translationEnabled:A}),A&&n.jsx(o,{style:{marginTop:8},children:n.jsx(c,{children:n.jsx(u.Text,{type:"warning",size:14,children:i("已开启自动翻译:保存设置时由后端并发翻译为 6 种语言(耗时取决于条目数与模型,通常 30 秒~2 分钟)")})})}),n.jsx(o,{style:{marginTop:16},children:n.jsx(d,{size:"default",onClick:async function(){const t=M.find(e=>"link"===e.category&&!Il(e.payload?.url||""));if(t)x.error({title:i("提示"),content:i("请输入有效的URL地址")+`(${t.title})`});else{l(!0);try{const t={...a,CustomerSupportCustomEntries:xs(a.CustomerSupportCustomEntries),CustomerSupportContactOrder:a.CustomerSupportContactOrder||JSON.stringify(O)},n=ke(t,p);if(!n.length)return void ve(i("你似乎并没有修改什么"));const s=Se(),l=n.map(e=>{const n="boolean"==typeof t[e.key]?String(t[e.key]):t[e.key];return ye.put(s,{key:e.key,value:n})}),o=await Promise.all(l);if(1===l.length&&o.includes(void 0))return;if(l.length>1&&o.includes(void 0))return void je(i("部分保存失败,请重试"));be(i("保存成功")),r(t),h(structuredClone(t)),e.refresh&&e.refresh()}catch(n){je(n?.message||i("保存失败,请重试"))}finally{l(!1)}}},children:i("保存客服设置")})}),n.jsx(x,{title:i("添加自定义联系条目"),visible:j,onOk:function(){const e=S.trim();if(!e)return void x.error({title:i("提示"),content:i("请输入展示标题")});let t={};if("email"===b)t={address:v.trim()};else if("phone"===b)t={number:w.trim()};else if("qrcode"===b)t={image_url:I.trim()},R.trim()&&(t.subtitle=R.trim());else if("link"===b){const e=z.trim();if(!Il(e))return void x.error({title:i("提示"),content:i("请输入有效的URL地址")});t={url:e}}const n={id:"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():`ce-${Date.now()}-${Math.random().toString(36).slice(2,11)}`,category:b,title:e,payload:t};L([...M,n]);const s=Tl(a,M);D(Ut(s,n.id)),f(!1),k(""),C(""),T(""),E(""),P(""),N("")},onCancel:()=>f(!1),width:520,children:n.jsxs(g,{vertical:!0,align:"start",style:{width:"100%"},spacing:"loose",children:[n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:i("联系条目分类")}),n.jsx("select",{value:b,onChange:e=>_(e.target.value),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)"},children:El.map(e=>n.jsx("option",{value:e,children:B(e)},e))})]}),n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:i("展示标题")}),n.jsx("input",{value:S,onChange:e=>k(e.target.value),placeholder:i("请输入展示标题"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]}),"email"===b&&n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:i("邮箱地址")}
1),n.jsx("input",{value:v,onChange:e=>C(e.target.value),placeholder:i("请输入邮箱地址"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]}),"phone"===b&&n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:i("电话号码")}),n.jsx("input",{value:w,onChange:e=>T(e.target.value),placeholder:i("请输入电话号码"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]}),"qrcode"===b&&n.jsxs(n.Fragment,{children:[n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:i("图片URL")}),n.jsx("input",{value:I,onChange:e=>E(e.target.value),placeholder:i("请输入二维码图片URL"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]}),n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:i("副文案")}),n.jsx("input",{value:R,onChange:e=>P(e.target.value),placeholder:i("可选副文案"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]})]}),"link"===b&&n.jsxs("div",{style:{width:"100%"},children:[n.jsx(u.Text,{strong:!0,style:{display:"block",marginBottom:8},children:i("链接地址")}),n.jsx("input",{value:z,onChange:e=>N(e.target.value),placeholder:i("请输入链接地址,如 https://example.com"),style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid var(--semi-color-border)",boxSizing:"border-box"}})]})]})})]})},{Text:Pl}=u,{Text:zl}=u,Nl=[{value:"slide-basic",label:"滑块拼图"},{value:"rotate",label:"旋转验证"},{value:"click-text",label:"文字点选"},{value:"click-shape",label:"图形点选"}];function Al(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,d]=t.useState({CaptchaLoginEnabled:!1,CaptchaCheckinEnabled:!1,CaptchaSendCodeEnabled:!1,CaptchaType:"slide-basic"}),u=t.useRef(),p=async(e,t)=>{try{const n=Se(),s=await ye.put(n,{key:e,value:t}),{success:l,message:a}=s.data;return l?(be(i("保存成功")),d(n=>({...n,[e]:t})),!0):(je(a),!1)}catch(n){return je(i("保存失败")+": "+n.message),!1}};return t.useEffect(()=>{(async()=>{l(!0);try{const e=Se(),t=await ye.get(e),{success:n,message:i,data:s}=t.data;if(n){let e={};s.forEach(t=>{"CaptchaLoginEnabled"===t.key||"CaptchaCheckinEnabled"===t.key||"CaptchaSendCodeEnabled"===t.key?e[t.key]="true"===t.value:"CaptchaType"===t.key&&(e[t.key]=t.value||"slide-basic")});const t={...r,...e};d(t),u.current&&u.current.setValues(t)}else je(i)}catch(e){je(i("加载失败")+": "+e.message)}l(!1)})().then()},[]),n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>u.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("登录安全设置"),children:[n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.Label,{children:i("验证码类型")}),n.jsx(L,{value:r.CaptchaType,onChange:async t=>{const n=t.target.value;await p("CaptchaType",n)&&e.refresh&&e.refresh()},style:{marginTop:"8px",marginBottom:"4px"},children:Nl.map(e=>n.jsx(B,{value:e.value,children:i(e.label)},e.value))}),n.jsx(zl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px",marginBottom:"20px"},children:i("选择前端展示的验证码交互方式,修改后即时生效")})]})}),n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"CaptchaLoginEnabled",label:i("启用滑块验证码登录"),checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await p("CaptchaLoginEnabled",String(t))&&e.refresh&&e.refresh()}}),n.jsx(zl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("开启后,所有登录方式(密码登录、OAuth、Telegram等)都需要先完成滑块验证码验证")}),n.jsx(zl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 验证码数据存储在MySQL数据库中,自动过期清理")})]})}),n.jsx(o,{style:{marginTop:"20px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"CaptchaCheckinEnabled",label:i("启用滑块验证码签到"),checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await p("CaptchaCheckinEnabled",String(t))&&e.refresh&&e.refresh()}}),n.jsx(zl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("开启后,用户签到时需要先完成滑块验证码验证,有效防止批量签到")}),n.jsx(zl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 建议在发现恶意批量签到行为时启用此功能")})]})}),n.jsx(o,{style:{marginTop:"20px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"CaptchaSendCodeEnabled",label:i("启用滑块验证码发送邮件"),checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await p("CaptchaSendCodeEnabled",String(t))&&e.refresh&&e.refresh()}}),n.jsx(zl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("开启后,发送邮箱验证码(注册/找回密码等)需要先完成滑块验证码验证,有效防止刷邮件")}),n.jsx(zl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 每次点击发送均需重新滑动,token 一次性使用")})]})})]})})})}const{Text:Ml}=u;function Ol(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState(!1),[p,h]=t.useState(null),[x,g]=t.useState(null),[y,j]=t.useState("smart"),[f,S]=t.useState({ChannelModelRedirect:"",GlobalModelMapping:""}),k=t.useRef(),v=t.useRef(null),C=t.useRef(null),w=async(e,t)=>{try{const n=Se(),s=await ye.put(n,{key:e,value:t}),{success:l,message:a}=s.data;return l?(be(i("保存成功")),S(n=>({...n,[e]:t}
1)),!0):(je(a),!1)}catch(n){return je(i("保存失败")+": "+n.message),!1}};return t.useEffect(()=>((async()=>{l(!0);try{const e=Se(),t=await ye.get(e),{success:n,message:i,data:s}=t.data;if(n){let e={};s.forEach(t=>{"ChannelModelRedirect"!==t.key&&"GlobalModelMapping"!==t.key||(e[t.key]=t.value||"")});const t={...f,...e};S(t),k.current&&k.current.setValues(t)}else je(i)}catch(e){je(i("加载失败")+": "+e.message)}l(!1)})().then(),()=>{v.current&&(clearTimeout(v.current),v.current=null),C.current&&(clearTimeout(C.current),C.current=null)}),[]),n.jsx(m,{spinning:s,children:n.jsxs(a,{values:f,getFormApi:e=>k.current=e,style:{marginBottom:15},children:[n.jsx(a.Section,{text:i("全局模型重定向"),children:n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.TextArea,{field:"GlobalModelMapping",label:i("全局模型重定向配置(JSON 对象)"),placeholder:'{\n  "gpt-4": "gpt-4o",\n  "gpt-3.5-turbo": "gpt-4o-mini",\n  "claude-3-opus": "claude-sonnet-4-20250514"\n}',autosize:{minRows:6,maxRows:15},onChange:async e=>{S(t=>({...t,GlobalModelMapping:e}))}}),n.jsx(Ml,{type:"warning",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("⚠️ 优先级最高:全局重定向会在渠道级别重定向之前生效,命中后不再走渠道的 model_mapping")}),n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("📝 格式:JSON 对象,键为用户请求的模型名,值为实际转发的模型名")}),n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 适用场景:统一将某个模型名重定向到新版本,无需逐个渠道配置")}),n.jsx("div",{style:{marginTop:"16px"},children:n.jsx(d,{type:"primary",onClick:async()=>{if(f.GlobalModelMapping)try{JSON.parse(f.GlobalModelMapping)}catch(t){return void je(i("JSON 格式不正确,请检查配置"))}await w("GlobalModelMapping",f.GlobalModelMapping)&&e.refresh&&e.refresh()},children:i("保存全局重定向配置")})})]})})}),n.jsx(a.Section,{text:i("渠道模型重定向"),children:n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.TextArea,{field:"ChannelModelRedirect",label:i("模型重定向配置(多维字符串数组)"),placeholder:'[\n  ["deepseek-chat", "deepseek-v3", "deepseek-v3-250324"],\n  ["deepseek-r1", "deepseek-reasoner", "deepseek-r1-250120"],\n  ["gpt-4", "gpt-4-turbo", "gpt-4-0613"]\n]',autosize:{minRows:6,maxRows:15},onChange:async e=>{S(t=>({...t,ChannelModelRedirect:e}))}}),n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("💡 说明:每个子数组是一个等价模型组,组内的模型可以互相重定向")}),n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i('📝 格式:[["model1","model2"],["model3","model4"]],支持多行书写')}),n.jsx("div",{style:{marginTop:"16px"},children:n.jsx(d,{type:"primary",onClick:async()=>{await w("ChannelModelRedirect",f.ChannelModelRedirect)&&e.refresh&&e.refresh()},children:i("保存配置")})})]})})}),n.jsx(a.Section,{text:i("渠道模型自动检测与更新"),children:n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsxs("div",{style:{marginBottom:"16px"},children:[n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block",marginBottom:"12px"},children:i("📌 自动检测所有启用渠道支持的模型变体,并更新模型列表和模型映射")}),n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block",marginBottom:"8px"},children:i("✅ 功能说明:")}),n.jsxs("ul",{style:{fontSize:"12px",color:"#666",marginLeft:"20px",marginBottom:"12px"},children:[n.jsx("li",{children:i("自动检测渠道支持的模型变体(如 deepseek-chat、deepseek-v3 等)")}),n.jsx("li",{children:i("根据检测结果更新渠道的模型列表")}),n.jsx("li",{children:i("自动生成模型映射关系(不支持的变体 → 支持的变体)")}),n.jsx("li",{children:i("支持并发处理,默认5个并发,最大20个")}),n.jsx("li",{children:i("采用异步任务模式,可实时查看处理进度")})]})]}
1),n.jsxs("div",{style:{marginBottom:"16px",padding:"12px",background:"#f6f8fa",borderRadius:"6px",border:"1px solid #e1e4e8"},children:[n.jsxs(Ml,{strong:!0,style:{display:"block",marginBottom:"8px",fontSize:"13px"},children:["🎯 ",i("选择检测模式")]}),n.jsxs(L,{type:"button",value:y,onChange:e=>j(e.target.value),disabled:r,children:[n.jsx(B,{value:"smart",children:n.jsxs("div",{style:{padding:"4px 0"},children:[n.jsxs(Ml,{strong:!0,children:["🚀 ",i("智能模式")]}),n.jsx(Ml,{type:"tertiary",style:{display:"block",fontSize:"11px",marginTop:"2px"},children:i("找到第一个支持的模型即停止,节省50-66%资源(推荐)")})]})}),n.jsx(B,{value:"fast",children:n.jsxs("div",{style:{padding:"4px 0"},children:[n.jsxs(Ml,{strong:!0,children:["⚡ ",i("快速模式")]}),n.jsx(Ml,{type:"tertiary",style:{display:"block",fontSize:"11px",marginTop:"2px"},children:i("不实际测试,直接应用规则,最快但可能不准确")})]})}),n.jsx(B,{value:"full",children:n.jsxs("div",{style:{padding:"4px 0"},children:[n.jsxs(Ml,{strong:!0,children:["🔍 ",i("完整模式")]}),n.jsx(Ml,{type:"tertiary",style:{display:"block",fontSize:"11px",marginTop:"2px"},children:i("测试所有变体,最精确但耗时长、消耗配额多")})]})})]})]}),n.jsx(d,{type:"primary",loading:r,onClick:async()=>{try{v.current&&(clearTimeout(v.current),v.current=null),C.current&&(clearTimeout(C.current),C.current=null),u(!0),h(null),g(null);const e=await ye.post(`/api/channel/detect_and_update_all?async=true&concurrency=5&delay_ms=100&mode=${y}`),{success:t,message:n,data:s}=e.data;if(!t)return je(n||i("启动更新任务失败")),void u(!1);const l=s?.task_id;if(!l)return je(i("未获取到任务ID")),void u(!1);be(i("批量更新任务已启动,正在后台处理..."));const a=async()=>{try{const e=await ye.get(`/api/channel/detect_and_update_all/progress/${l}`),{success:t,data:n}=e.data;if(!t)return u(!1),void h(null);const{is_completed:s,processed:r,total:o,success_count:c,fail_count:d,skip_count:p}=n;if(h({processed:r,total:o,success_count:c,fail_count:d,skip_count:p,percentage:o>0?Math.round(r/o*100):0}),s)return u(!1),g({total:o,processed:r,success_count:c,fail_count:d,skip_count:p,results:n.results||[],start_time:n.start_time,end_time:n.end_time,duration:n.end_time-n.start_time}),void be(i(`🎉 自动更新完成!总计: ${o}, 成功: ${c}, 失败: ${d}, 跳过: ${p}`));v.current=setTimeout(a,2e3)}catch(e){console.error("查询进度失败:",e),u(!1),h(null),je(i("查询进度失败")+": "+(e.message||e))}};v.current=setTimeout(a,2e3)}catch(e){u(!1),h(null),je(i("自动更新失败")+": "+(e.message||e))}},style:{marginBottom:"16px"},children:i(r?"正在检测更新中...":"🔄 自动更新所有渠道模型")}),p&&n.jsxs("div",{style:{marginTop:"16px",marginBottom:"16px"},children:[n.jsx(re,{percent:p.percentage,showInfo:!0,stroke:100===p.percentage?"#52c41a":"#1890ff"}),n.jsx("div",{style:{marginTop:"8px",fontSize:"13px",color:"#666"},children:n.jsxs(Ml,{type:"secondary",children:[i("已处理"),": ",p.processed,"/",p.total," |",n.jsxs("span",{style:{color:"#52c41a",marginLeft:"8px"},children:[i("成功"),": ",p.success_count]})," |",n.jsxs("span",{style:{color:"#f5222d",marginLeft:"8px"},children:[i("失败"),": ",p.fail_count]})," |",n.jsxs("span",{style:{color:"#faad14",marginLeft:"8px"},children:[i("跳过"),": ",p.skip_count]})]})})]}),x&&n.jsxs("div",{style:{marginTop:"20px",padding:"20px",background:"#f6f8fa",borderRadius:"8px",border:"1px solid #e1e4e8"},children:[n.jsx("div",{style:{marginBottom:"16px"},children:n.jsxs(Ml,{strong:!0,style:{fontSize:"15px",color:"#24292e"},children:["📊 ",i("执行结果摘要")]})}),n.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(200px, 1fr))",gap:"12px",marginBottom:"16px"},children:[n.jsxs("div",{style:{padding:"12px",background:"#fff",borderRadius:"6px",border:"1px solid #e1e4e8"},children:[n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block"},children:i("总渠道数")}),n.jsx(Ml,{strong:!0,style:{fontSize:"20px",color:"#0969da"},children:x.total})]}),n.jsxs("div",{style:{padding:"12px",background:"#fff",borderRadius:"6px",border:"1px solid #e1e4e8"},children:[n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block"},children:i("成功更新")}),n.jsx(Ml,{strong:!0,style:{fontSize:"20px",color:"#1a7f37"},children:x.success_count})]}),n.jsxs("div",{style:{padding:"12px",background:"#fff",borderRadius:"6px",border:"1px solid #e1e4e8"},children:[n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block"},children:i("更新失败")}),n.jsx(Ml,{strong:!0,style:{fontSize:"20px",color:"#cf222e"},children:x.fail_count})]}),n.jsxs("div",{style:{padding:"12px",background:"#fff",borderRadius:"6px",border:"1px solid #e1e4e8"},children:[n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block"},children:i("跳过处理")}),n.jsx(Ml,{strong:!0,style:{fontSize:"20px",color:"#bf8700"},children:x.skip_count})]}),n.jsxs("div",{style:{padding:"12px",background:"#fff",borderRadius:"6px",border:"1px solid #e1e4e8"},children:[n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",display:"block"},children:i("执行耗时")}),n.jsx(Ml,{strong:!0,style:{fontSize:"20px",color:"#6e7781"},children:x.duration?`${x.duration}${i("秒")}`:"-"})]})]}),x.results&&x.results.length>0&&n.jsxs("div",{style:{marginTop:"16px"},children:[n.jsxs(Ml,{strong:!0,style:{fontSize:"14px",display:"block",marginBottom:"12px"},children:["📝 ",i("详细结果")]}),n.jsxs(b,{type:"line",style:{background:"#fff",borderRadius:"6px",border:"1px solid #e1e4e8",padding:"8px"},children:[n.jsx(_,{tab:n.jsxs("span",{children:[i("全部")," ",n.jsx(oe,{count:x.results.length,type:"primary"})]}),itemKey:"all",children:n.jsx("div",{style:{maxHeight:"300px",overflowY:"auto"},children:x.results.map((e,t)=>n.jsx("div",{style:{padding:"10px 14px",borderBottom:t<x.results.length-1?"1px solid #e1e4e8":"none",fontSize:"13px"},children:n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[1===e.status&&n.jsx("span",{style:{color:"#1a7f37",fontSize:"16px"},children:"✓"}),2===e.status&&n.jsx("span",{style:{color:"#cf222e",fontSize:"16px"},children:"✗"}),3===e.status&&n.jsx("span",{style:{color:"#bf8700",fontSize:"16px"},children:"○"}),0===e.status&&n.jsx("span",{style:{color:"#6e7781",fontSize:"16px"},children:"-"}),n.jsxs(Ml,{strong:!0,style:{color:"#24292e"},children:["#",e.channel_id," ",e.channel_name]}),n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px"},children:e.message})]})},t))})}),n.jsx(_,{tab:n.jsxs("span",{style:{color:"#1a7f37"},children:[i("成功更新")," ",n.jsx(oe,{count:x.success_count,style:{backgroundColor:"#1a7f37"}})]}),itemKey:"success",children:n.jsxs("div",{style:{maxHeight:"300px",overflowY:"auto"},children:[x.results.filter(e=>1===e.status).map((e,t,i)=>n.jsx("div",{style:{padding:"10px 14px",borderBottom:t<i.length-1?"1px solid #e1e4e8":"none",fontSize:"13px",background:t%2==0?"#f6fff8":"#fff"},children:n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[n.jsx("span",{style:{color:"#1a7f37",fontSize:"16px"},children:"✓"}),n.jsxs(Ml,{strong:!0,style:{color:"#24292e"},children:["#",e.channel_id," ",e.channel_name]}),n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px"},children:e.message})]})},t)),0===x.results.filter(e=>1===e.status).length&&n.jsx("div",{style:{padding:"20px",textAlign:"center",color:"#6e7781"},children:i("暂无成功更新的渠道")})]})}),n.jsx(_,{tab:n.jsxs("span",{style:{color:"#cf222e"},children:[i("更新失败")," ",n.jsx(oe,{count:x.fail_count,style:{backgroundColor:"#cf222e"}})]}),itemKey:"fail",children:n.jsxs("div",{style:{maxHeight:"300px",overflowY:"auto"},children:[x.results.filter(e=>2===e.status).map((e,t,i)=>n.jsx("div",{style:{padding:"10px 14px",borderBottom:t<i.length-1?"1px solid #e1e4e8":"none",fontSize:"13px",background:t%2==0?"#fff5f5":"#fff"},children:n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[n.jsx("span",{style:{color:"#cf222e",fontSize:"16px"},children:"✗"}),n.jsxs(Ml,{strong:!0,style:{color:"#24292e"},children:["#",e.channel_id," ",e.channel_name]}),n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px",color:"#cf222e"},children:e.message})]})},t)),0===x.results.filter(e=>2===e.status).length&&n.jsx("div",{style:{padding:"20px",textAlign:"center",color:"#6e7781"},children:i("暂无失败的渠道")})]})}),n.jsx(_,{tab:n.jsxs("span",{style:{color:"#bf8700"},children:[i("跳过处理")," ",n.jsx(oe,{count:x.skip_count,style:{backgroundColor:"#bf8700"}})]}),itemKey:"skip",children:n.jsxs("div",{style:{maxHeight:"300px",overflowY:"auto"},children:[x.results.filter(e=>3===e.status||0===e.status).map((e,t,i)=>n.jsx("div",{style:{padding:"10px 14px",borderBottom:t<i.length-1?"1px solid #e1e4e8":"none",fontSize:"13px",background:t%2==0?"#fffbf0":"#fff"},children:n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[3===e.status&&n.jsx("span",{style:{color:"#bf8700",fontSize:"16px"},children:"○"}),0===e.status&&n.jsx("span",{style:{color:"#6e7781",fontSize:"16px"},children:"-"}),n.jsxs(Ml,{strong:!0,style:{color:"#24292e"},children:["#",e.channel_id," ",e.channel_name]}),n.jsx(Ml,{type:"tertiary",style:{fontSize:"12px"},children:e.message})]})},t)),0===x.results.filter(e=>3===e.status||0===e.status).length&&n.jsx("div",{style:{padding:"20px",textAlign:"center",color:"#6e7781"},children:i("暂无跳过的渠道")})]})})]})]}),n.jsx("div",{style:{marginTop:"16px",textAlign:"right"},children:n.jsx(d,{size:"small",onClick:()=>{g(null),h(null)},children:i("关闭结果")})})]})]})})})]})})}const{Text:Dl}=u;function Ll(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({"aliyun_setting.access_key_id":"","aliyun_setting.access_key_secret":"","aliyun_setting.personal_auth_code":"","aliyun_setting.enterprise_auth_code":""}),p=t.useRef(),h=async(e,t)=>{try{const n=Se(),s=await ye.put(n,{key:e,value:t}),{success:l,message:a}=s.data;return l?(be(i("保存成功")),u(n=>({...n,[e]:t}
1)),!0):(je(a),!1)}catch(n){return je(i("保存失败")+": "+n.message),!1}};return t.useEffect(()=>{(async()=>{l(!0);try{const e=Se(),t=await ye.get(e),{success:n,message:i,data:s}=t.data;if(n){let e={};s.forEach(t=>{"aliyun_setting.access_key_id"!==t.key&&"aliyun_setting.access_key_secret"!==t.key&&"aliyun_setting.personal_auth_code"!==t.key&&"aliyun_setting.enterprise_auth_code"!==t.key||(e[t.key]=t.value||"")});const t={...r,...e};u(t),p.current&&p.current.setValues(t)}else je(i)}catch(e){je(i("加载失败")+": "+e.message)}l(!1)})().then()},[]),n.jsx(m,{spinning:s,children:n.jsx(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},children:n.jsxs(a.Section,{text:i("阿里云实名验证配置"),children:[n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"aliyun_setting.access_key_id",label:i("阿里云 AccessKeyId"),placeholder:i("请输入阿里云AccessKeyId"),autoComplete:"off",onChange:async e=>{u(t=>({...t,"aliyun_setting.access_key_id":e}))}}),n.jsx(Dl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("在阿里云控制台获取AccessKey")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"aliyun_setting.access_key_secret",label:i("阿里云 AccessKeySecret"),placeholder:i("请输入阿里云AccessKeySecret"),mode:"password",autoComplete:"new-password",onChange:async e=>{u(t=>({...t,"aliyun_setting.access_key_secret":e}))}}),n.jsx(Dl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("AccessKeySecret将加密存储")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"aliyun_setting.personal_auth_code",label:i("个人二要素验证授权码"),placeholder:i("请输入个人二要素验证授权码"),autoComplete:"off",onChange:async e=>{u(t=>({...t,"aliyun_setting.personal_auth_code":e}))}}),n.jsx(Dl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("用于个人实名验证(验证姓名 + 身份证号)")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"aliyun_setting.enterprise_auth_code",label:i("企业三要素验证授权码"),placeholder:i("请输入企业三要素验证授权码"),autoComplete:"off",onChange:async e=>{u(t=>({...t,"aliyun_setting.enterprise_auth_code":e}))}}),n.jsx(Dl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("用于企业实名验证(验证企业名称 + 法人姓名 + 统一社会信用代码)")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsx(c,{span:24,children:n.jsx(d,{type:"primary",onClick:async()=>{const t=await h("aliyun_setting.access_key_id",r["aliyun_setting.access_key_id"]),n=await h("aliyun_setting.access_key_secret",r["aliyun_setting.access_key_secret"]),i=await h("aliyun_setting.personal_auth_code",r["aliyun_setting.personal_auth_code"]),s=await h("aliyun_setting.enterprise_auth_code",r["aliyun_setting.enterprise_auth_code"]);t&&n&&i&&s&&e.refresh&&e.refresh()},children:i("保存阿里云配置")})})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(Dl,{type:"tertiary",style:{fontSize:"12px"},children:i("⚠️ 注意事项:")}),n.jsxs("ul",{style:{fontSize:"12px",color:"hsl(var(--muted-foreground))",marginTop:"8px"},children:[n.jsx("li",{children:i("个人二要素验证:验证姓名 + 身份证号")}),n.jsx("li",{children:i("企业三要素验证:验证企业名称 + 法人姓名 + 统一社会信用代码")}),n.jsx("li",{children:i("每个用户每天有3次验证机会(个人和企业分别计算)")}),n.jsx("li",{children:i("需要在阿里云控制台获取AccessKey和授权码")}),n.jsx("li",{children:i("授权码需在阿里云号码认证服务中购买")})]})]})})]})})})}const{Text:Bl}=u;function Fl(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState([]),[h,x]=t.useState(""),g=t.useRef(),y=()=>{if(h&&""!==h.trim()){const e=h.trim();if(r.includes(e))return void je(i("该模型已存在于白名单中"));u([...r,e]),x(""),be(i("已添加到白名单"))}};return t.useEffect(()=>{(async()=>
1{l(!0);try{const e=Se(),t=await ye.get(e),{success:n,message:i,data:s}=t.data;n?s.forEach(e=>{"ModelIgnoreThinkWhitelist"===e.key&&e.value&&u(e.value.split(",").filter(e=>""!==e.trim()))}):je(i)}catch(e){je(i("加载失败")+": "+e.message)}l(!1)})().then()},[]),n.jsx(m,{spinning:s,children:n.jsx(a,{getFormApi:e=>g.current=e,style:{marginBottom:15},children:n.jsx(a.Section,{text:i("模型忽略Think处理白名单"),children:n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(Bl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginBottom:"16px"},children:i("配置该白名单后,白名单中的模型将跳过所有think相关的后缀处理(如 -thinking-数字)")}),n.jsx(Bl,{strong:!0,style:{display:"block",marginBottom:"8px"},children:i("已添加的白名单项")}),n.jsx(p,{value:r,onChange:u,placeholder:i("输入模型名称后回车"),style:{width:"100%",marginBottom:"16px"}}),n.jsx(a.Input,{placeholder:i("输入要添加的模型名称(如:qwen3-vl-32b-thinking)"),value:h,onChange:e=>x(e),style:{marginBottom:"16px"},suffix:n.jsx(d,{theme:"solid",type:"primary",onClick:y,children:i("添加")}),onEnterPress:y}),n.jsx(d,{type:"primary",onClick:async()=>{Array.isArray(r)?await(async(e,t)=>{try{const e=Se(),n=await ye.put(e,{key:"ModelIgnoreThinkWhitelist",value:t}),{success:s,message:l}=n.data;return s?(be(i("保存成功")),!0):(je(l),!1)}catch(n){return je(i("保存失败")+": "+n.message),!1}})(0,r.join(","))&&e.refresh&&e.refresh():je(i("模型白名单格式不正确"))},children:i("保存模型白名单设置")})]})})})})})}const{Text:Wl}=u;function Jl(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState({SyncMainEnabled:!1,SyncToken:"",SyncSourceURL:"",SyncAccountId:"",SyncInterval:"600",SyncWhitelistUserIds:"",SyncRatioEnabled:!1,SyncSquareEnabled:!1,SyncGroupEnabled:!1,SyncChannelEnabled:!1}),p=t.useRef(),[h,x]=t.useState(r),g=async(e,t)=>{try{const n=Se(),s=await ye.put(n,{key:e,value:t}),{success:l,message:a}=s.data;return l?(be(i("保存成功")),u(n=>({...n,[e]:t})),x(n=>({...n,[e]:t})),!0):(je(a),!1)}catch(n){return je(i("保存失败")+": "+n.message),!1}};return t.useEffect(()=>{const t={};for(let n in e.options)Object.keys(r).includes(n)&&(t[n]=e.options[n]||"");Object.keys(t).length>0&&(u(t),x(structuredClone(t)),p.current?.setValues(t))},[e.options]),n.jsx(m,{spinning:s,children:n.jsxs(a,{values:r,getFormApi:e=>p.current=e,style:{marginBottom:15},autoComplete:"off",children:[n.jsxs(a.Section,{text:i("同步功能总控制"),children:[n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"SyncMainEnabled",label:i("启用同步功能总开关"),checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await g("SyncMainEnabled",String(t))&&e.refresh&&e.refresh()}}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("开启后,将启用所有同步功能,关闭则所有同步功能均不生效")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 这是所有同步功能的主开关,其他同步开关需要此开关开启才能生效")})]})}),n.jsx(o,{style:{marginTop:"20px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"SyncToken",label:i("同步 Token"),mode:"password",placeholder:i("请输入同步 Token"),autoComplete:"new-password",onChange:e=>{u(t=>({...t,SyncToken:e}))},style:{width:"100%"}}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("用于验证同步功能的身份凭证,保存后后端将加密存储")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("🔒 Token 将以加密方式存储,请妥善保管")}),n.jsx("div",{style:{marginTop:"12px"},children:n.jsx(d,{type:"primary",onClick:async()=>{r.SyncToken&&""!==r.SyncToken.trim()?await g("SyncToken",r.SyncToken)&&e.refresh&&e.refresh():je(i("Token 不能为空"))},children:i("保存 Token")})})]})}),n.jsx(o,{style:{marginTop:"20px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"SyncSourceURL",label:i("同步源URL"),placeholder:i("请输入同步源URL,例如:https://source.yunwu.ai"),onChange:e=>{u(t=>({...t,SyncSourceURL:e}))},style:{width:"100%"}}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("源系统的API地址,用于获取同步数据")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 示例:https://source.yunwu.ai(不要在末尾添加斜杠)")}),n.jsx("div",{style:{marginTop:"12px"},children:n.jsx(d,{type:"primary",onClick:async()=>{r.SyncSourceURL&&""!==r.SyncSourceURL.trim()?await g("SyncSourceURL",r.SyncSourceURL)&&e.refresh&&e.refresh():je(i("同步源URL不能为空"))},children:i("保存URL")})})]})}),n.jsx(o,{style:{marginTop:"20px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"SyncAccountId",label:i("账户ID"),placeholder:i("请输入账户Id"),onChange:e=>{u(t=>({...t,SyncAccountId:e}))},style:{width:"100%"}}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("用于标识同步账户的唯一ID")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 可选参数,如果源系统需要账户ID才能同步数据,请填写此项")}),n.jsx("div",{style:{marginTop:"12px"},children:n.jsx(d,{type:"primary",onClick:async()=>{await g("SyncAccountId",r.SyncAccountId||"")&&e.refresh&&e.refresh()},children:i("保存账户Id")})})]})}),n.jsx(o,{style:{marginTop:"20px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.InputNumber,{field:"SyncInterval",label:i("同步间隔(秒)"),placeholder:i("请输入同步间隔"),min:60,max:86400,step:60,onChange:e=>{u(t=>({...t,SyncInterval:String(e)}))},style:{width:"100%"}}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("自动同步的时间间隔,单位为秒(最小60秒,最大86400秒/24小时)")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 推荐设置:600秒(10分钟),默认值:600秒")}),n.jsx("div",{style:{marginTop:"12px"},children:n.jsx(d,{type:"primary",onClick:async()=>{const t=parseInt(r.SyncInterval);isNaN(t)||t<60?je(i("同步间隔不能小于60秒")):await g("SyncInterval",String(t))&&e.refresh&&e.refresh()},children:i("保存间隔")})})]})}),n.jsx(o,{style:{marginTop:"20px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.TextArea,{field:"SyncWhitelistUserIds",label:i("同步功能白名单用户ID"),placeholder:i("一行一个用户ID"),onChange:e=>{u(t=>({...t,SyncWhitelistUserIds:e}))},style:{fontFamily:"JetBrains Mono, Consolas"},autosize:{minRows:4,maxRows:12}}
1),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("只有白名单中的用户才能通过同步接口获取数据,一行一个用户ID")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("此配置在源站设置,用于控制哪些用户的 Access Token 可以调用同步接口")}),n.jsx("div",{style:{marginTop:"12px"},children:n.jsx(d,{type:"primary",onClick:async()=>{await g("SyncWhitelistUserIds",r.SyncWhitelistUserIds||"")&&e.refresh&&e.refresh()},children:i("保存白名单")})})]})})]}),n.jsx(a.Section,{text:i("倍率同步"),children:n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"SyncRatioEnabled",label:i("启用倍率同步开关"),checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await g("SyncRatioEnabled",String(t))&&e.refresh&&e.refresh()}}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("开启后,将同步倍率相关的配置和数据")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 需要同步功能总开关开启")})]})})}),n.jsx(a.Section,{text:i("广场同步"),children:n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"SyncSquareEnabled",label:i("启用广场同步开关"),checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await g("SyncSquareEnabled",String(t))&&e.refresh&&e.refresh()}}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("开启后,将同步广场相关的配置和数据")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 需要同步功能总开关开启")})]})})}),n.jsx(a.Section,{text:i("分组同步"),children:n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"SyncGroupEnabled",label:i("启用分组同步开关"),checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await g("SyncGroupEnabled",String(t))&&e.refresh&&e.refresh()}}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("开启后,将同步分组相关的配置和数据")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 需要同步功能总开关开启")})]})})}),n.jsx(a.Section,{text:i("渠道同步"),children:n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"SyncChannelEnabled",label:i("启用渠道同步开关"),checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await g("SyncChannelEnabled",String(t))&&e.refresh&&e.refresh()}}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("开启后,将同步渠道相关的配置和数据")}),n.jsx(Wl,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"4px"},children:i("💡 需要同步功能总开关开启")})]})})})]})})}const{Text:Ul}=u,Vl=["api_storage_setting.enabled","api_storage_setting.endpoint","api_storage_setting.token"],Kl=new Set(["api_storage_setting.enabled"]),Gl={api_storage_setting:{enabled:!1,endpoint:"",token:""}};function ql(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState(!1),p=t.useRef(),x=e=>{if(!p.current)return"";return p.current.getValue(e)??""},g=async(e,t)=>{try{const n=await ye.put(Se(),{key:e,value:t}),{success:i,message:s}=n.data;return!!i||(je(s),!1)}catch(n){return je(i("保存失败")+": "+n.message),!1}};return t.useEffect(()=>{(async()=>{l(!0);try{const e=await ye.get(Se()),{success:t,message:n,data:i}=e.data;if(t){let e={};i.forEach(t=>{Vl.includes(t.key)&&(Kl.has(t.key)?e[t.key]="true"===t.value:e[t.key]=t.value||"")});const t=function(e,t){const n=JSON.parse(JSON.stringify(t));for(const[i,s]of Object.entries(e)){const e=i.split(".");2===e.length&&(n[e[0]]||(n[e[0]]={}),n[e[0]][e[1]]=s)}return n}(e,Gl);p.current&&p.current.setValues(t)}else je(n)}catch(e){je(i("加载失败")+": "+e.message)}l(!1)})()},[]),n.jsx(m,{spinning:s,children:n.jsxs(a,{initValues:Gl,getFormApi:e=>p.current=e,style:{marginBottom:15,marginTop:24},autoComplete:"off",children:[n.jsxs("div",{style:{position:"absolute",opacity:0,height:0,overflow:"hidden",pointerEvents:"none"},children:[n.jsx("input",{type:"text",name:"prevent_autofill_username",tabIndex:-1,autoComplete:"username"}),n.jsx("input",{type:"password",name:"prevent_autofill_password",tabIndex:-1,autoComplete:"current-password"})]}),n.jsx(h,{type:"info",description:i("API 上传存储用于文章图片粘贴上传、发票 PDF 上传等场景,通过 HTTP POST + Bearer Token 将文件上传到外部存储服务。此配置独立于上方的 S3/GCP 对象存储。"),style:{marginBottom:20}}),n.jsxs(a.Section,{text:i("API 上传存储配置"),children:[n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"api_storage_setting.enabled",label:i("启用 API 上传存储")}),n.jsx(Ul,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("启用后,文章粘贴图片和发票 PDF 上传将使用此存储服务")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"api_storage_setting.endpoint",label:i("上传接口地址 
1(Endpoint)"),placeholder:i("例如:https://image.zhongzhuan.chat/upload"),autoComplete:"new-password",name:"api_endpoint_url_setting"}),n.jsx(Ul,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("文件上传的 API 地址,使用 multipart/form-data 格式 POST 上传,字段名为 file")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"api_storage_setting.token",label:i("Bearer Token"),placeholder:i("请输入认证 Token"),autoComplete:"new-password",name:"api_bearer_token_setting",mode:"password",onChange:()=>u(!0)}),n.jsx(Ul,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("请求头中 Authorization: Bearer <Token> 的认证令牌")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsx(c,{span:24,children:n.jsx(d,{type:"primary",onClick:async()=>{l(!0);try{const t=!!x("api_storage_setting.enabled"),n=[g("api_storage_setting.enabled",String(t)),g("api_storage_setting.endpoint",String(x("api_storage_setting.endpoint")))];r&&n.push(g("api_storage_setting.token",String(x("api_storage_setting.token")))),(await Promise.all(n)).every(Boolean)?(be(i("保存成功")),e.refresh&&e.refresh()):je(i("部分配置保存失败,请重试"))}catch(t){je(i("保存失败")+": "+t.message)}l(!1)},loading:s,children:i("保存配置")})})})]})]})})}const{Text:$l}=u,Hl=["s3_storage_setting.enabled","s3_storage_setting.access_key","s3_storage_setting.secret_key","s3_storage_setting.endpoint","s3_storage_setting.bucket_name","s3_storage_setting.region","s3_storage_setting.use_path_style","s3_storage_setting.presign_expire_hours","gcp_storage_setting.enabled","gcp_storage_setting.project_id","gcp_storage_setting.bucket_name","gcp_storage_setting.region","gcp_storage_setting.service_account_json","gcp_storage_setting.presign_expire_hours"],Ql=new Set(["s3_storage_setting.enabled","s3_storage_setting.use_path_style","gcp_storage_setting.enabled"]),Xl=new Set(["s3_storage_setting.presign_expire_hours","gcp_storage_setting.presign_expire_hours"]),Yl={s3_storage_setting:{enabled:!1,access_key:"",secret_key:"",endpoint:"",bucket_name:"",region:"",use_path_style:!0,presign_expire_hours:24},gcp_storage_setting:{enabled:!1,project_id:"",bucket_name:"",region:"",service_account_json:"",presign_expire_hours:24}};function Zl(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,u]=t.useState(!1),[p,x]=t.useState("disabled"),g=t.useRef(),y=e=>{if(!g.current)return"";return g.current.getValue(e)??""},j=async(e,t)=>{try{const n=await ye.put(Se(),{key:e,value:t}),{success:i,message:s}=n.data;return!!i||(je(s),!1)}catch(n){return je(i("保存失败")+": "+n.message),!1}};return t.useEffect(()=>{(async()=>{l(!0);try{const t=await ye.get(Se()),{success:n,message:i,data:s}=t.data;if(n){let t={};s.forEach(e=>{Hl.includes(e.key)&&(Ql.has(e.key)?t[e.key]="true"===e.value:Xl.has(e.key)?t[e.key]=parseInt(e.value,10)||24:t[e.key]=e.value||"")});const n=function(e,t){const n=JSON.parse(JSON.stringify(t));for(const[i,s]of Object.entries(e)){const e=i.split(".");2===e.length&&(n[e[0]]||(n[e[0]]={}),n[e[0]][e[1]]=s)}return n}(t,Yl);x((e=n,e?.s3_storage_setting?.enabled?"s3":e?.gcp_storage_setting?.enabled?"gcp":"disabled")),g.current&&g.current.setValues(n)}else je(i)}catch(t){je(i("加载失败")+": "+t.message)}var e;l(!1)})()},[]),n.jsxs(n.Fragment,{children:[n.jsx(m,{spinning:s,children:n.jsxs(a,{initValues:Yl,getFormApi:e=>g.current=e,style:{marginBottom:15},autoComplete:"off",children:[n.jsxs("div",{style:{position:"absolute",opacity:0,height:0,overflow:"hidden",pointerEvents:"none"},children:[n.jsx("input",{type:"text",name:"prevent_autofill_username",tabIndex:-1,autoComplete:"username"}),n.jsx("input",{type:"password",name:"prevent_autofill_password",tabIndex:-1,autoComplete:"current-password"})]}),n.jsx(h,{type:"info",description:i("object_storage_hint_002"),style:{marginBottom:20}}),n.jsxs(a.Section,{text:i("对象存储配置"),children:[n.jsx(o,{children:n.jsxs(c,{span:24,children:[n.jsx("div",{style:{marginBottom:"8px",fontWeight:600}
1,children:i("存储类型")}),n.jsxs(L,{value:p,onChange:e=>x(e.target.value),direction:"horizontal",children:[n.jsx(B,{value:"disabled",children:i("关闭")}),n.jsx(B,{value:"s3",children:i("S3 兼容协议")}),n.jsx(B,{value:"gcp",children:i("GCP Cloud Storage")})]}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i('同一时间只能启用一种对象存储,切换类型后请点击"保存配置"生效')})]})}),n.jsx("div",{style:{display:"s3"===p?void 0:"none"},children:n.jsxs(n.Fragment,{children:[n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"s3_storage_setting.access_key",label:i("Access Key"),placeholder:i("请输入 Access Key"),autoComplete:"new-password",name:"s3_access_key_setting"}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("S3 兼容存储的访问密钥 ID")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"s3_storage_setting.secret_key",label:i("Secret Key"),placeholder:i("请输入 Secret Key"),autoComplete:"new-password",name:"s3_secret_key_setting",mode:"password"}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("S3 兼容存储的秘密访问密钥")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"s3_storage_setting.endpoint",label:i("端点"),placeholder:i("例如:https://s3.amazonaws.com 或 https://storage.googleapis.com"),autoComplete:"new-password",name:"s3_endpoint_url_setting"}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("S3 兼容服务的端点地址,AWS S3 可填 https://s3.amazonaws.com")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"s3_storage_setting.bucket_name",label:i("存储桶名称"),placeholder:i("请输入存储桶名称"),autoComplete:"new-password"}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("存储桶需要提前在对应的存储服务控制台中创建")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"s3_storage_setting.region",label:i("区域"),placeholder:i("例如:us-east-1、auto"),autoComplete:"new-password"}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("存储桶所在区域,不确定可填 auto")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"s3_storage_setting.use_path_style",label:i("使用 Path Style")}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("object_storage_hint_001")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.InputNumber,{field:"s3_storage_setting.presign_expire_hours",label:i("预签名 URL 有效时长(小时)"),placeholder:"24",min:1,max:168,style:{width:"200px"}}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("生成的预签名下载链接的有效时长,默认 24 小时。AWS S3 最大 168 小时(7天)")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx($l,{type:"tertiary",style:{fontSize:"12px"},children:i("配置说明")+":"}),n.jsxs("ul",{style:{fontSize:"12px",color:"hsl(var(--muted-foreground))",marginTop:"8px"},children:[n.jsx("li",{children:i("1. 在对应的云服务控制台创建存储桶")}),n.jsx("li",{children:i("2. 获取 Access Key 和 Secret Key 凭证")}),n.jsx("li",{children:i("3. 填写正确的 Endpoint 地址")}),n.jsx("li",{children:i("4. MinIO、GCS 等自建/兼容服务需要开启 Path Style")}),n.jsx("li",{children:i('5. 保存配置后点击"测试连接"验证配置是否正确')})]})]})})]})}),n.jsx("div",{style:{display:"gcp"===p?void 0:"none"},children:n.jsxs(n.Fragment,{children:[n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"gcp_storage_setting.project_id",label:i("GCP 项目 ID"),placeholder:i("请输入 GCP 项目 ID,例如:my-project-123456"),autoComplete:"new-password"}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("在 GCP Console 中查看您的项目 ID")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"gcp_storage_setting.bucket_name",label:i("存储桶名称"),placeholder:i("请输入存储桶名称,例如:my-app-invoices"),autoComplete:"new-password"}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"}
1,children:i("存储桶需要提前在 GCP Console 中创建")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.Input,{field:"gcp_storage_setting.region",label:i("区域(可选)"),placeholder:i("例如:asia-east1"),autoComplete:"new-password"}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("存储桶所在区域,可选填")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.TextArea,{field:"gcp_storage_setting.service_account_json",label:i("Service Account JSON 凭证"),placeholder:i("请粘贴完整的 Service Account JSON 内容"),autoComplete:"new-password",name:"gcp_service_account_json_setting",rows:8}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("在 GCP Console > IAM & Admin > Service Accounts 中创建服务账号并下载 JSON 密钥文件")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(a.InputNumber,{field:"gcp_storage_setting.presign_expire_hours",label:i("预签名 URL 有效时长(小时)"),placeholder:"24",min:1,max:168,style:{width:"200px"}}),n.jsx($l,{type:"tertiary",style:{fontSize:"12px",display:"block",marginTop:"8px"},children:i("生成的签名下载链接的有效时长,默认 24 小时。GCS V4 签名最大 168 小时(7天)")})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx($l,{type:"tertiary",style:{fontSize:"12px"},children:i("配置说明")+":"}),n.jsxs("ul",{style:{fontSize:"12px",color:"hsl(var(--muted-foreground))",marginTop:"8px"},children:[n.jsx("li",{children:i("1. 在 GCP Console 创建 Cloud Storage 存储桶")}),n.jsx("li",{children:i('2. 创建 Service Account 并授予 "Storage Object Admin" 角色')}),n.jsx("li",{children:i("3. 下载 Service Account 的 JSON 密钥文件")}),n.jsx("li",{children:i("4. 将 JSON 文件内容完整粘贴到上方文本框中")}),n.jsx("li",{children:i('5. 保存配置后点击"测试连接"验证配置是否正确')})]})]})})]})}),n.jsx(o,{style:{marginTop:"16px"},children:n.jsxs(c,{span:24,children:[n.jsx(d,{type:"primary",onClick:async()=>{l(!0);try{const t=[];"s3"===p?(t.push(j("s3_storage_setting.enabled","true")),t.push(j("s3_storage_setting.access_key",String(y("s3_storage_setting.access_key")))),t.push(j("s3_storage_setting.secret_key",String(y("s3_storage_setting.secret_key")))),t.push(j("s3_storage_setting.endpoint",String(y("s3_storage_setting.endpoint")))),t.push(j("s3_storage_setting.bucket_name",String(y("s3_storage_setting.bucket_name")))),t.push(j("s3_storage_setting.region",String(y("s3_storage_setting.region")))),t.push(j("s3_storage_setting.use_path_style",String(y("s3_storage_setting.use_path_style")))),t.push(j("s3_storage_setting.presign_expire_hours",String(y("s3_storage_setting.presign_expire_hours")||24))),t.push(j("gcp_storage_setting.enabled","false"))):"gcp"===p?(t.push(j("gcp_storage_setting.enabled","true")),t.push(j("gcp_storage_setting.project_id",String(y("gcp_storage_setting.project_id")))),t.push(j("gcp_storage_setting.bucket_name",String(y("gcp_storage_setting.bucket_name")))),t.push(j("gcp_storage_setting.region",String(y("gcp_storage_setting.region")))),t.push(j("gcp_storage_setting.service_account_json",String(y("gcp_storage_setting.service_account_json")))),t.push(j("gcp_storage_setting.presign_expire_hours",String(y("gcp_storage_setting.presign_expire_hours")||24))),t.push(j("s3_storage_setting.enabled","false"))):(t.push(j("s3_storage_setting.enabled","false")),t.push(j("gcp_storage_setting.enabled","false"))),(await Promise.all(t)).every(Boolean)&&(be(i("保存成功")),e.refresh&&e.refresh())}catch(t){je(i("保存失败")+": "+t.message)}l(!1)},loading:s,style:{marginRight:"10px"},children:i("保存配置")}),n.jsx(d,{type:"secondary",onClick:async()=>{u(!0);try{const e=Se(),t=await ye.post(e.replace(/\/(admin)?$/,"/admin/storage/test-connection")),{success:n,message:s}=t.data;n?be(i("连接测试成功!对象存储配置正确")):je(i("连接测试失败")+": "+s)}catch(e){je(i("连接测试失败")+": "+e.message)}u(!1)},loading:r,disabled:"disabled"===p,children:i("测试连接")})]})})]})]})}),n.jsx(ql,{options:e.options,refresh:e.refresh})]})}const{Text:ea}=u,ta={default:1800,"sora-2-pro":4200,veo:4200};function na(e){const{t:i}=ge(),[s,l]=t.useState(!1),[a,r]=t.useState(""),[u,p]=t.useState("");return t.useEffect(()=>{const t=e.options?.TaskTimeoutConfig;if(t)try{const e=JSON.parse(t);r(JSON.stringify(e,null,2))}catch{r(JSON.stringify(ta,null,2))}else r(JSON.stringify(ta,null,2));p("")},[e.options]),n.jsxs(m,{spinning:s,children:[n.jsx(o,{gutter:16,children:n.jsxs(c,{span:24,children:[n.jsx("div",{style:{marginBottom:8}
1,children:n.jsx(ea,{strong:!0,children:i("异步任务超时配置(JSON)")})}),n.jsxs("div",{style:{marginBottom:8,fontSize:13,color:"#666"},children:[i("key 为任务 ID 前缀(按前缀匹配),value 为超时秒数(整数)。"),n.jsx("br",{}),i('"default" 为默认超时,未匹配到任何前缀时使用。'),n.jsx("br",{}),i("示例:sora-2-pro → 4200秒(70分钟),veo → 4200秒,default → 1800秒(30分钟)")]}),n.jsx(S,{value:a,onChange:function(e){r(e);try{JSON.parse(e),p("")}catch(t){p(t.message)}},autosize:{minRows:8,maxRows:20},style:{fontFamily:"monospace",fontSize:13,borderColor:u?"#ff4d4f":void 0}}),u&&n.jsxs("div",{style:{color:"#ff4d4f",fontSize:12,marginTop:4},children:[i("JSON 错误:"),u]})]})}),n.jsx(o,{gutter:16,style:{marginTop:12},children:n.jsx(c,{span:24,children:n.jsxs("div",{style:{padding:"10px 14px",border:"1px solid #e8e8e8",borderRadius:4,backgroundColor:"#f6f7f9",fontSize:12,color:"#555"},children:[n.jsx("div",{style:{fontWeight:"bold",marginBottom:6},children:i("配置说明")}),n.jsxs("div",{children:["• ",n.jsx("code",{children:"default"}),":",i("默认超时,未匹配到前缀时生效,单位秒")]}),n.jsxs("div",{children:["• ",i('其他 key 按任务 ID 前缀匹配,越长越精确(如 "sora-2-pro" 会匹配包含此前缀的任务 ID)')]}),n.jsx("div",{style:{marginTop:4},children:i("常用换算:30分钟=1800,50分钟=3000,70分钟=4200,90分钟=5400")})]})})}),n.jsxs(o,{style:{marginTop:16},gutter:8,children:[n.jsx(c,{children:n.jsx(d,{onClick:async function(){if(u)return void ve(i("JSON 格式不正确,请修复后再保存"));let t;try{t=JSON.parse(a)}catch(n){return void ve(i("JSON 格式不正确:")+n.message)}for(const[e,s]of Object.entries(t))if("number"!=typeof s||!Number.isInteger(s)||s<=0)return void ve(i(`"${e}" 的值必须是正整数(单位:秒)`));l(!0);try{const n=Se();await ye.put(n,{key:"TaskTimeoutConfig",value:JSON.stringify(t)}),be(i("保存成功")),e.refresh()}catch{je(i("保存失败,请重试"))}finally{l(!1)}},type:"primary",disabled:!!u,children:i("保存超时配置")})}),n.jsx(c,{children:n.jsx(d,{onClick:function(){r(JSON.stringify(ta,null,2)),p("")},theme:"light",children:i("恢复默认值")})})]})]})}const{Text:ia,Paragraph:sa}=u,la=[{value:"ErrorCountWhitelist",label:"渠道失败统计豁免",desc:"命中后不计入渠道失败率,不影响智能排序(最常用)",color:"green"},{value:"NoRetryErrors",label:"请求失败不重试",desc:"命中后不会重试其他渠道,直接把错误返回给用户",color:"orange"},{value:"ErrorLogWhitelist",label:"错误日志详细记录",desc:"命中后会把错误详情写入日志 content 字段展现给用户",color:"blue"},{value:"RedirectErrorMessages",label:"敏感错误信息屏蔽",desc:"命中后屏蔽敏感信息(密钥、余额等),不暴露给用户",color:"red"}];function aa(e){if(!e)return"-";const t=new Date(1e3*e),n=(Date.now()-t.getTime())/1e3;return n<60?`${Math.floor(n)}秒前`:n<3600?`${Math.floor(n/60)}分钟前`:n<86400?`${Math.floor(n/3600)}小时前`:t.toLocaleString()}function ra(e){return e&&8===e.length?`${e.slice(4,6)}-${e.slice(6,8)}`:e}function oa(e){const{t:i}=ge(),[s,l]=t.useState(!0),[u,p]=t.useState(7),[h,y]=t.useState(!1),[b,_]=t.useState([]),[k,C]=t.useState(""),[w,T]=t.useState([]),[I,R]=t.useState(0),[P,z]=t.useState(1),[N,A]=t.useState(50),[D,F]=t.useState(!1),[W,J]=t.useState(!1),[U,V]=t.useState(null),[K,G]=t.useState(""),[q,$]=t.useState("ErrorCountWhitelist"),[H,Q]=t.useState(!1);t.useEffect(()=>{if(!e.options)return;const t=e.options.ErrorCandidateRecordEnabled;void 0!==t&&l(!0===t||"true"===t);const n=e.options.ErrorCandidateRetentionDays;if(void 0!==n&&""!==n){const e=parseInt(n,10);!isNaN(e)&&e>0&&p(e)}},[e.options]);const X=async(e,t=1,n=50,s=!1)=>{if(e){y(!0);try{const l=await ye.get(`/api/error_candidates/?date=${e}&page=${t}&size=${n}&include_ignored=${s}`),{success:a,data:r,message:o}=l.data;a&&r?(T(r.items||[]),R(r.total||0)):(je(o||i("加载错误候选失败")),T([]),R(0))}catch(l){je(i("加载失败")+": "+l.message),T([]),R(0)}finally{y(!1)}}};t.useEffect(()=>{(async()=>{try{const e=await ye.get("/api/error_candidates/dates"),{success:t,data:n,message:s}=e.data;t&&Array.isArray(n)?(_(n),!k&&n.length>0&&C(n[0].date)):t||je(s||i("加载日期列表失败"))}catch(e){je(i("加载日期列表失败")+": "+e.message)}})()},[]),t.useEffect(()=>{k&&X(k,P,N,D)},[k,P,N,D]);const Y=async(t,n)=>{try{const s=Se(),l=await ye.put(s,{key:t,value:String(n)}),{success:a,message:r}=l.data;return a?(be(i("保存成功")),e.refresh&&e.refresh(),!0):(je(r),!1)}catch(s){return je(i("保存失败")+": "+s.message),!1}},Z=t.useMemo(()=>[{title:i("状态码"),dataIndex:"status_code",width:80,render:e=>e?n.jsx(j,{color:"blue",children:e}):"-"},{title:i("错误码"),dataIndex:"error_code",width:200,render:e=>
1e?n.jsx(ia,{code:!0,style:{fontSize:12},children:e}):"-"},{title:i("错误消息"),dataIndex:"message_sample",render:e=>n.jsx(f,{content:e,children:n.jsx(sa,{ellipsis:{rows:2,showTooltip:!1},style:{margin:0,fontSize:12},children:e})})},{title:i("频次"),dataIndex:"count",width:80,sorter:(e,t)=>e.count-t.count,render:e=>n.jsx(j,{color:e>=100?"red":e>=10?"orange":"grey",children:e})},{title:i("渠道"),dataIndex:"channels",width:150,render:e=>{if(!e||0===e.length)return"-";const t=e.slice(0,3).join(", "),i=e.length>3?" +"+(e.length-3):"";return n.jsx(f,{content:e.join(", "),children:n.jsxs(ia,{style:{fontSize:12},children:[t,i]})})}},{title:i("模型"),dataIndex:"models",width:180,render:e=>{if(!e||0===e.length)return"-";const t=e.slice(0,2).join(", "),i=e.length>2?" +"+(e.length-2):"";return n.jsx(f,{content:e.join(", "),children:n.jsxs(ia,{style:{fontSize:12},children:[t,i]})})}},{title:i("最后出现"),dataIndex:"last_at",width:110,render:e=>n.jsx(ia,{style:{fontSize:12},children:aa(e)})},{title:i("操作"),width:220,fixed:"right",render:(e,t)=>n.jsxs(g,{children:[n.jsx(d,{size:"small",type:"primary",theme:"solid",disabled:t.ignored,onClick:()=>(e=>{V(e),G(e.message_sample||""),$("ErrorCountWhitelist"),J(!0)})(t),children:i("加入白名单")}),t.ignored?n.jsx(d,{size:"small",onClick:()=>(async e=>{try{const t=await ye.post("/api/error_candidates/unignore",{fingerprint:e.fingerprint}),{success:n,message:s}=t.data;n?(be(i("已恢复")),X(k,P,N,D)):je(s)}catch(t){je(i("操作失败")+": "+t.message)}})(t),children:i("取消忽略")}):n.jsx(O,{title:i("确定忽略这条错误吗?"),content:i('忽略后将不再展示,可在"显示已忽略"中找回。'),onConfirm:()=>(async e=>{try{const t=await ye.post("/api/error_candidates/ignore",{fingerprint:e.fingerprint}),{success:n,message:s}=t.data;n?(be(i("已忽略")),X(k,P,N,D)):je(s)}catch(t){je(i("操作失败")+": "+t.message)}})(t),children:n.jsx(d,{size:"small",type:"tertiary",children:i("忽略")})})]})}],[k,P,N,D]),ee=la.find(e=>e.value===q);return n.jsxs(m,{spinning:h,children:[n.jsx(r,{style:{marginBottom:16},bodyStyle:{padding:16},children:n.jsx(a,{labelPosition:"left",labelAlign:"left",labelWidth:140,children:n.jsxs(o,{gutter:24,children:[n.jsx(c,{span:12,children:n.jsxs(a.Slot,{label:i("启用错误候选采集"),children:[n.jsx(E,{checked:s,checkedText:i("开"),uncheckedText:i("关"),onChange:async e=>{await Y("ErrorCandidateRecordEnabled",e)&&l(e)}}),n.jsx(ia,{type:"tertiary",style:{marginLeft:12,fontSize:12},children:i('开启后会自动收集"被判定为渠道失败但未命中白名单"的错误')})]})}),n.jsx(c,{span:12,children:n.jsx(a.Slot,{label:i("数据保留天数"),children:n.jsx(M,{value:u,min:1,max:30,onBlur:async e=>{const t=parseInt(e.target.value,10);!isNaN(t)&&t>0&&t!==u&&await Y("ErrorCandidateRetentionDays",t)&&p(t)},onChange:e=>p(e),suffix:i("天")})})})]})})}),n.jsxs(r,{bodyStyle:{padding:16},children:[n.jsxs(o,{type:"flex",align:"middle",justify:"space-between",style:{marginBottom:16,flexWrap:"wrap",gap:8},children:[n.jsx(c,{children:n.jsxs(g,{wrap:!0,children:[n.jsx(ia,{strong:!0,children:i("日期:")}),b.map(e=>n.jsxs(j,{color:e.date===k?"blue":"white",type:e.date===k?"solid":"light",onClick:()=>{C(e.date),z(1)},style:{cursor:"pointer"},children:[ra(e.date)," (",e.count,")"]},e.date))]})}),n.jsx(c,{children:n.jsxs(g,{children:[n.jsx(E,{size:"small",checked:D,checkedText:i("含忽略"),uncheckedText:i("隐藏忽略"),onChange:e=>{F(e),z(1)}}),n.jsx(d,{onClick:()=>X(k,P,N,D),children:i("刷新")})]})})]}),n.jsx(v,{rowKey:"fingerprint",columns:Z,dataSource:w,scroll:{x:1300},pagination:{currentPage:P,pageSize:N,total:I,showSizeChanger:!0,pageSizeOpts:[20,50,100,200],onPageChange:z,onPageSizeChange:e=>{A(e),z(1)},showTotal:!0},empty:n.jsx("div",{style:{padding:32,textAlign:"center",color:"#999"},children:i("暂无数据。可能原因:今天还没有未覆盖的错误,或采集开关未启用。")})})]}),n.jsx(x,{title:i("加入白名单"),visible:W,onCancel:()=>J(!1),onOk:async()=>{if(K.trim()){Q(!0);try{const t=await ye.post("/api/error_candidates/whitelist",{fingerprint:U?.f
1ingerprint||"",date:k,whitelist_type:q,keyword:K.trim()}),{success:n,message:s}=t.data;n?(be(i("已加入白名单")),J(!1),e.refresh&&e.refresh()):je(s||i("加入失败"))}catch(t){je(i("加入失败")+": "+t.message)}finally{Q(!1)}}else je(i("关键词不能为空"))},confirmLoading:H,okText:i("确认加入"),width:680,children:U&&n.jsxs("div",{children:[n.jsxs(r,{bodyStyle:{padding:12,background:"#fafafa"},style:{marginBottom:16},children:[n.jsxs("div",{style:{marginBottom:6},children:[n.jsx(j,{color:"blue",children:U.status_code||"-"}),n.jsx(ia,{code:!0,style:{fontSize:12,marginLeft:8},children:U.error_code||"-"}),n.jsxs(j,{style:{marginLeft:8},color:"orange",children:[i("频次"),": ",U.count]})]}),n.jsx(ia,{type:"tertiary",style:{fontSize:12},children:i("原始消息样本")}),n.jsx(sa,{style:{margin:"4px 0 0",fontSize:12},children:U.message_sample})]}),n.jsx("div",{style:{marginBottom:12},children:n.jsx(ia,{strong:!0,children:i("选择白名单类型")})}),n.jsx(L,{value:q,onChange:e=>$(e.target.value),direction:"vertical",style:{marginBottom:16,width:"100%"},children:la.map(e=>n.jsx(B,{value:e.value,children:n.jsxs("div",{children:[n.jsx(j,{color:e.color,style:{marginRight:8},children:i(e.label)}),n.jsx(ia,{type:"tertiary",style:{fontSize:12},children:i(e.desc)})]})},e.value))}),n.jsx("div",{style:{marginBottom:8},children:n.jsx(ia,{strong:!0,children:i("实际加入的关键词(可编辑,建议截取稳定的特征片段)")})}),n.jsx(S,{value:K,onChange:G,autosize:{minRows:3,maxRows:6},maxLength:500,showClear:!0,placeholder:i("从原始消息中截取一段能稳定匹配的关键词")}),n.jsxs(ia,{type:"tertiary",style:{fontSize:12,marginTop:8,display:"block"},children:[i("提示:关键词太长可能匹配不到,太短可能误伤其他错误。建议截取错误中独特的英文片段。"),"RedirectErrorMessages"===ee?.value&&i(" RedirectErrorMessages 使用逗号分隔,关键词内不能包含逗号。")]})]})})]})}const{Text:ca}=u;function da(e){const{t:i}=ge(),[s,l]=t.useState(!1),[r,d]=t.useState(!1);return t.useEffect(()=>{if(!e.options)return;const t=e.options.TopupStarLevelEnabled;void 0!==t&&l(!0===t||"true"===t)},[e.options]),n.jsxs(m,{spinning:r,children:[n.jsx(h,{type:"info",bordered:!0,closeIcon:null,style:{marginBottom:16},description:i("总开关关闭时,用户充值星级相关功能全部不生效(含计价与个人充值页展示),已绑定星级的用户按普通/代理/系统价充值;星级单价配置数据仍保留,开启后自动恢复。")}),n.jsx(a,{labelPosition:"left",labelAlign:"left",labelWidth:200,children:n.jsx(o,{gutter:16,children:n.jsxs(c,{span:24,children:[n.jsx(a.Switch,{field:"TopupStarLevelEnabled",label:i("启用用户充值星级功能"),checked:s,checkedText:i("开"),uncheckedText:i("关"),onChange:async t=>{await(async(t,n)=>{try{d(!0);const t=Se(),s=await ye.put(t,{key:"TopupStarLevelEnabled",value:String(n)}),{success:l,message:a}=s.data;return l?(be(i("保存成功")),e.refresh&&e.refresh(),!0):(je(a),!1)}catch(s){return je(i("保存失败")+": "+s.message),!1}finally{d(!1)}})(0,t)&&l(t)}}),n.jsx(ca,{type:"tertiary",style:{fontSize:12,display:"block",marginTop:8},children:i("星级名称与单价在「运营设置 - 用户星级单价设置」中配置;用户与星级的绑定在「用户管理 - 编辑用户」中操作。")})]})})})]})}function ua(e){const{t:i}=ge(),[,s]=t.useContext(Te),[l,a]=t.useState(!1),[r,d]=t.useState({InvoiceEnabled:!0,InvoicePersonalEnabled:!0,PersonalVerifyEnabled:!0,InvoiceEnterpriseEnabled:!0,InvoiceMinAmount:0,InvoiceMaxAmount:0});t.useEffect(()=>{if(!e.options)return;const t=e=>{const t=parseFloat(e);return Number.isFinite(t)&&t>=0?t:0};d({InvoiceEnabled:!0===e.options.InvoiceEnabled||"true"===e.options.InvoiceEnabled,InvoicePersonalEnabled:void 0===e.options.InvoicePersonalEnabled||!0===e.options.InvoicePersonalEnabled||"true"===e.options.InvoicePersonalEnabled,PersonalVerifyEnabled:void 0===e.options.PersonalVerifyEnabled||!0===e.options.PersonalVerifyEnabled||"true"===e.options.PersonalVerifyEnabled,InvoiceEnterpriseEnabled:void 0===e.options.InvoiceEnterpriseEnabled||!0===e.options.InvoiceEnterpriseEnabled||"true"===e.options.InvoiceEnterpriseEnabled,InvoiceMinAmount:t(e.options.InvoiceMinAmount),InvoiceMaxAmount:t(e.options.InvoiceMaxAmount)})},[e.options]);const p=(e,t)=>{if("InvoiceMinAmount"!==e&&"InvoiceMaxAmount"!==e)return String(t);const n=Number(t);return!Number.isFinite(n)||n<0?"0":n.toFixed(2)},h=async(t,n)=>{const l=r[t];d(e=>({...e,[t]:n})),a(!0);try{const a=await ye.put(Se(),{key:t,value:p(t,n)}),{success:r,message:c}=a.data;if(r){be(i("设置保存成功"));try{const e=await ye.get("/api/status");e.data?.success&&s({type:"set",payload:e.data.data})}catch(o){}e.refresh&&e.refresh()}else je(c),d(e=>({...e,[t]:l}))}catch(c){je(i("设置保存失败")),d(e=>({...e,[t]:l}))}finally{a(!1)}},x=({field:e,label:t,description:i})=>n.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:4},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[n.jsx(E,{checked:r[e],onChange:t=>h(e,t),disabled:l}),n.jsx(u.Text,{children:t})]}),i&&n.jsx(u.Text,{type:"tertiary",style:{marginLeft:44},children:i})]});return n.jsxs(m,{spinning:l,children:[n.jsx(u.Title,{heading:6,style:{marginBottom:16},children:i("发票设置")}),n.jsx(o,{gutter:16,children:n.jsx(c,{span:8,children:n.jsx(x,{field:"InvoiceEnabled",label:i("启用发票功能"),description:i("开启后,用户可以在充值页面申请开具发票,并查看开票记录。")})})}),r.InvoiceEnabled&&n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsx(c,{span:8,children:n.jsx(x,{field:"InvoicePersonalEnabled",label:i("允许个人开票"),description:i("关闭后,用户将无法以个人名义申请开票。")})}),n.jsx(c,{span:8,children:n.jsx(x,{field:"PersonalVerifyEnabled",label:i("允许个人实名认证"),description:i("关闭后,用户将无法进行个人实名认证,仅可进行企业认证。")})}),n.jsx(c,{span:8,children:n.jsx(x,{field:"InvoiceEnterpriseEnabled",label:i("允许企业开票"),description:i("关闭后,用户将无法以企业名义申请开票。")})})]}),r.InvoiceEnabled&&n.jsxs(o,{gutter:16,style:{marginTop:16},children:[n.jsx(c,{span:8,children:n.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[n.jsx(u.Text,{children:i("单笔开票最小金额(元)")}),n.jsx(M,{min:0,precision:2,value:r.InvoiceMinAmount,disabled:l,onChange:e=>d(t=>({...t,InvoiceMinAmount:null==e?0:Number(e)})),onBlur:()=>h("InvoiceMinAmount",r.InvoiceMinAmount)}),n.jsx(u.Text,{type:"tertiary",children:i("填 0 表示不限制最小金额。")})]})}),n.jsx(c,{span:8,children:n.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[n.jsx(u.Text,{children:i("单笔开票最大金额(元)")}),n.jsx(M,{min:0,precision:2,value:r.InvoiceMaxAmount,disabled:l,onChange:e=>d(t=>({...t,InvoiceMaxAmount:null==e?0:Number(e)})),onBlur:()=>h("InvoiceMaxAmount",r.InvoiceMaxAmount)}),n.jsx(u.Text,{type:"tertiary",children:i("填 0 表示不限制最大金额。")})]})})]})]})}const pa=e=>{const{t:i}=ge(),[s,l]=t.useState("seoAndWebsite"),[a,o]=t.useState("modelRateLimit"),[c,d]=t.useState("notification"),[u,p]=t.useState("imageProxy");return n.jsx(r,{style:{marginBottom:20},children:n.jsxs(b,{type:"line",activeKey:s,onChange:e=>
1l(e),children:[n.jsx(_,{tab:i("🌐 SEO与网站"),itemKey:"seoAndWebsite",style:{marginTop:20},children:n.jsx(kl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("🖥️ 服务器配置"),itemKey:"serverConfig",style:{marginTop:20},children:n.jsx(vl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("🤖 模型与渠道"),itemKey:"modelAndChannel",style:{marginTop:20},children:n.jsxs(b,{type:"card",activeKey:a,onChange:e=>o(e),style:{marginTop:10},children:[n.jsx(_,{tab:i("🚦 模型限制"),itemKey:"modelRateLimit",style:{marginTop:20},children:n.jsx(al,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("📊 渠道排序"),itemKey:"channelSort",style:{marginTop:20},children:n.jsx(ll,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("🚦 模型输入输出限制"),itemKey:"tokenLimit",style:{marginTop:20},children:n.jsx(ul,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("💎 Gemini 设置"),itemKey:"geminiSettings",style:{marginTop:20},children:n.jsx(pl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("🏆 热门排行榜"),itemKey:"ranking",style:{marginTop:20},children:n.jsx(gl,{options:e.options,refresh:e.refresh})})]})}),n.jsx(_,{tab:i("👤 用户体验"),itemKey:"userExperience",style:{marginTop:20},children:n.jsx(fl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("📞 通知客服"),itemKey:"notification",style:{marginTop:20},children:n.jsxs(b,{type:"card",activeKey:c,onChange:e=>d(e),style:{marginTop:10},children:[n.jsx(_,{tab:i("🔔 推送通知"),itemKey:"notification",style:{marginTop:20},children:n.jsx(bl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("💬 客服设置"),itemKey:"customerSupport",style:{marginTop:20},children:n.jsx(Rl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("💱 倍率变更通知"),itemKey:"ratioNotify",style:{marginTop:20},children:n.jsx(_l,{options:e.options,refresh:e.refresh})})]})}),n.jsx(_,{tab:i("⚡ 高级功能"),itemKey:"advanced",style:{marginTop:20},children:n.jsxs(b,{type:"card",activeKey:u,onChange:e=>p(e),style:{marginTop:10},children:[n.jsx(_,{tab:i("🖼️ 图片代理"),itemKey:"imageProxy",style:{marginTop:20},children:n.jsx(sl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("🔐 登录安全"),itemKey:"loginSecurity",style:{marginTop:20},children:n.jsx(Al,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("🔄 渠道模型管理"),itemKey:"channelModel",style:{marginTop:20},children:n.jsx(Ol,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("☁️ 阿里云实名验证"),itemKey:"aliyunVerify",style:{marginTop:20},children:n.jsx(Ll,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("🎯 模型白名单"),itemKey:"modelWhitelist",style:{marginTop:20},children:n.jsx(Fl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("☁️ 对象存储"),itemKey:"objectStorage",style:{marginTop:20},children:n.jsx(Zl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("⏱️ 任务超时"),itemKey:"taskTimeout",style:{marginTop:20},children:n.jsx(na,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("📡 错误候选分析"),itemKey:"errorCandidate",style:{marginTop:20},children:n.jsx(oa,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("⭐ 充值星级"),itemKey:"topupStarLevel",style:{marginTop:20},children:n.jsx(da,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("🔧 其他扩展"),itemKey:"otherSettings",style:{marginTop:20},children:n.jsx(jl,{options:e.options,refresh:e.refresh})})]})}),n.jsx(_,{tab:i("🔄 同步功能"),itemKey:"syncSettings",style:{marginTop:20},children:n.jsx(Jl,{options:e.options,refresh:e.refresh})}),n.jsx(_,{tab:i("🧾 发票管理"),itemKey:"invoiceSettings",style:{marginTop:20},children:n.jsx(ua,{options:e.options,refresh:e.refresh})})]})})},ha=()=>{const{t:e}=ge(),[i,s]=t.useState(!1),[l,a]=t.useState({});async function o(){try{s(!0),await(async()=>{const t=Ee()?"/api/option/":"/api/option/admin";try{const e=await ye.get(t),{success:n,message:i,data:s}=e.data;if(n){let e={};s.forEach(t=>
1{t.key.endsWith("Enabled")?e[t.key]="true"===t.value:e[t.key]=t.value}),a(e),Object.keys(e).length}else je(i),console.error("CustomSettingsWrapper - API返回失败:",i)}catch(n){console.error("CustomSettingsWrapper - API调用异常:",n),je(e("加载配置失败,请检查权限"))}})()}catch(t){je(e("刷新失败")),console.error("CustomSettingsWrapper - 刷新失败:",t)}finally{s(!1)}}return t.useEffect(()=>{const t=Ee()||Pe();Ee(),Pe(),t?o():je(e("您没有访问此页面的权限"))},[]),Ee()||Pe()?n.jsx(m,{spinning:i,size:"large",children:n.jsxs(r,{style:{marginBottom:"10px"},children:[n.jsx(r.Meta,{title:e("二开扩展功能设置")}),n.jsx("div",{style:{marginTop:"16px"},children:n.jsx(pa,{options:l,refresh:o})})]})}):n.jsx(r,{style:{marginBottom:"10px"},children:n.jsx(h,{type:"warning",description:e("您没有访问二开功能设置的权限,需要管理员或超级管理员角色。")})})},xa=()=>{const{t:e}=ge(),i=s(),a=l(),[r,o]=t.useState("1");let c=[];Ee()&&(c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(it,{size:18}),e("运营设置")]}),content:n.jsx(Jn,{}),itemKey:"operation"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(vt,{size:18}),e("仪表盘设置")]}),content:n.jsx(Ri,{}),itemKey:"dashboard"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(Ct,{size:18}),e("聊天设置")]}),content:n.jsx(Qi,{}),itemKey:"chats"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(wt,{size:18}),e("绘图设置")]}),content:n.jsx(Yi,{}),itemKey:"drawing"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(ft,{size:18}),e("支付设置")]}),content:n.jsx(ss,{}),itemKey:"payment"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(Tt,{size:18}),e("倍率设置")]}),content:n.jsx($i,{}),itemKey:"ratio"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(It,{size:18}),e("速率限制设置")]}),content:n.jsx(Vn,{}),itemKey:"ratelimit"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(Et,{size:18}),e("模型相关设置")]}),content:n.jsx(xi,{}),itemKey:"models"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(Rt,{size:18}),e("系统设置")]}),content:n.jsx(on,{}),itemKey:"system"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(Pt,{size:18}),e("其他设置")]}),content:n.jsx(Rn,{}),itemKey:"other"}),c.push({tab:e("二开功能设置"),content:n.jsx(ha,{}),itemKey:"custom"})),Pe()&&!Ee()&&(c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(vt,{size:18}),e("仪表盘设置")]}),content:n.jsx(En,{}),itemKey:"dashboard"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(Tt,{size:18}),e("倍率设置")]}),content:n.jsx($i,{}),itemKey:"ratio"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(Rt,{size:18}),e("系统设置")]}),content:n.jsx(un,{}),itemKey:"system"}),c.push({tab:n.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"5px"},children:[n.jsx(Pt,{size:18}),e("二开功能设置")]}),content:n.jsx(ha,{}),itemKey:"custom"})),De()&&c.push({tab:e("站点管理"),content:n.jsx(il,{}),itemKey:"agent"});const d=e=>{o(e),i(`/console/setting?tab=${e}`,{replace:!0})},u=t.useRef(c);u.current=c;const p=()=>Ee()?"operation":Pe()?"dashboard":De()?"agent":"operation";return t.useEffect(()=>{if(!a.pathname.startsWith("/console/setting"))return;const e=new URLSearchParams(a.search).get("tab");e&&u.current.find(t=>t.itemKey===e)?o(e):d(p())},[a.pathname,a.search]),n.jsx("div",{className:"px-2",children:n.jsx(le,{children:n.jsx(le.Content,{children:n.jsx(b,{type:"card",collapsible:!0,activeKey:r,onChange:e=>d(e),children:c.map(e=>n.jsx(_,{itemKey:e.itemKey,tab:e.tab,children:r===e.itemKey&&e.content},e.itemKey))})})})})};export{xa 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.