Files
jizhi/backend/MiaoJiZhang.Api/wwwroot/assets/Settings-DerxQWe0.js
T

1 line
10 KiB
JavaScript

import{$ as e,F as t,L as n,M as r,R as i,b as a,bt as o,g as s,h as c,m as l,p as u,q as d,s as f,t as p,v as m,y as h}from"./api-DftvpHMa.js";import{a as g}from"./config-provider-DjHSmQsy.js";var _={key:0,style:{"text-align":`center`,padding:`60px`}},v={style:{"font-weight":`600`}},y={style:{"font-size":`11px`,color:`#999`,"margin-top":`2px`,"white-space":`normal`}},b={style:{"font-size":`10px`,color:`#bbb`,"margin-top":`2px`,"font-family":`monospace`}},x={style:{"margin-left":`10px`,color:`#8c8c8c`}},S=a({__name:`Settings`,setup(a){let S=e({}),C=e(!0),w=e(!1),T=e(null),E=e(``),D=[`llm.protocol`,`llm.base_url`,`llm.model`,`llm.max_tokens`,`llm.temperature`],O=[`limit.daily_ai_messages`,`limit.daily_ai_messages_per_user`,`limit.max_monthly_budget`],k=[`feature.ocr_enabled`,`feature.voice_enabled`,`feature.ai_auto_book`,`feature.sticker_enabled`],A=[`permission.default.ai_enabled`],j=[`quota.default_ai_chat_limit`,`quota.default_ai_chat_period`],M=[`system.default_ledger_name`,`system.max_ledgers_per_user`,`brand.app_name`,`brand.slogan`,`brand.logo_url`],N=[{value:`chat_completions`,label:`Chat Completions`,desc:`OpenAI Chat Completions API。POST /v1/chat/completions`,endpoint:`/chat/completions`},{value:`responses`,label:`Responses`,desc:`OpenAI Responses API(新版)。POST /v1/responses`,endpoint:`/responses`},{value:`messages`,label:`Messages`,desc:`Anthropic Messages API。POST /v1/messages,用于 Claude 系列`,endpoint:`/messages`}],P={"llm.protocol":{label:`API 协议`,desc:``,type:`protocol`},"llm.base_url":{label:`API 地址`,desc:``,type:`url`},"llm.model":{label:`模型名称`,desc:``,type:`text`},"llm.max_tokens":{label:`最大输出 Token`,desc:`单次请求上限`,type:`number`},"llm.temperature":{label:`温度 (Temperature)`,desc:`0=确定 1=创意`,type:`number`},"limit.daily_ai_messages":{label:`全站每日 AI 消息上限`,desc:``,type:`number`},"limit.daily_ai_messages_per_user":{label:`每人每日 AI 消息上限`,desc:``,type:`number`},"limit.max_monthly_budget":{label:`最大月预算金额`,desc:``,type:`number`},"feature.ocr_enabled":{label:`OCR 小票识别`,desc:`拍照记账功能`,type:`switch`},"feature.voice_enabled":{label:`语音记账`,desc:`语音输入转文字`,type:`switch`},"feature.ai_auto_book":{label:`AI 自动入账`,desc:`AI 识别记账意图直接入账`,type:`switch`},"feature.sticker_enabled":{label:`表情包功能`,desc:`聊天表情包面板 + AI 表情回复`,type:`switch`},"permission.default.ai_enabled":{label:`新用户默认启用 AI`,desc:`仅影响保存后注册的新用户,现有用户权限不变`,type:`switch`},"quota.default_ai_chat_limit":{label:`新用户默认 AI 对话次数`,desc:`0 表示不限次数`,type:`number`},"quota.default_ai_chat_period":{label:`新用户默认额度周期`,desc:`按上海时区自然周期重置`,type:`period`},"system.default_ledger_name":{label:`新用户默认账本名`,desc:``,type:`text`},"system.max_ledgers_per_user":{label:`每人最多账本数`,desc:``,type:`number`},"brand.app_name":{label:`App 名称`,desc:``,type:`text`},"brand.slogan":{label:`App 标语`,desc:``,type:`text`},"brand.logo_url":{label:`Logo URL`,desc:``,type:`url`}};r(async()=>{try{let e=await p.configs(),t={};for(let n of e)t[n.key]=n;S.value=t,t[`llm.protocol`]||I(`llm.protocol`,`chat_completions`),t[`quota.default_ai_chat_limit`]||I(`quota.default_ai_chat_limit`,50),t[`quota.default_ai_chat_period`]||I(`quota.default_ai_chat_period`,`day`),L.value=F(`llm.protocol`)||`chat_completions`}finally{C.value=!1}});function F(e){let t=S.value[e];if(!t)return``;let n=P[e];return n?.type===`number`?Number(t.value)||0:n?.type===`switch`?t.value===`true`:t.value}function I(e,t){let n=String(t);S.value[e]?S.value[e].value=n:S.value[e]={id:0,key:e,value:n,version:0}}let L=e(`chat_completions`);async function R(e){I(`llm.protocol`,L.value);let t=e.filter(e=>S.value[e]).map(async e=>{let t=S.value[e];try{if(t.id>0){let e=await p.updateConfig(t.id,t.value);t&&(t.id=e.id)}else{let e=await p.createConfig(t.key,t.value);t&&(t.id=e.id)}}catch(t){g.error(e+` 保存失败: `+(t?.response?.data?.detail||t?.response?.data?.error||t.message))}});if(t.length===0){g.warning(`没有可保存的配置`);return}await Promise.all(t),g.success(`已保存 `+t.length+` 项配置`)}async function z(){w.value=!0,T.value=null,E.value=``;try{let e=await p.testLlm();T.value=e.ok,E.value=e.detail||e.error||``,e.ok?g.success(`LLM 连接正常`):g.error(e.error||`连接失败`)}catch(e){T.value=!1;let t=e?.response?.data;E.value=t?.detail||t?.error||t?.message||e.message||`未知错误`,g.error(`连接失败`)}finally{w.value=!1}}return(e,r)=>{let a=i(`a-spin`),p=i(`a-button`),g=i(`a-space`),S=i(`a-alert`),B=i(`a-radio`),V=i(`a-col`),H=i(`a-row`),U=i(`a-radio-group`),W=i(`a-descriptions-item`),G=i(`a-input`),K=i(`a-input-number`),q=i(`a-descriptions`),J=i(`a-card`),Y=i(`a-switch`),X=i(`a-select-option`),Z=i(`a-select`);return C.value?(t(),s(`div`,_,[h(a,{size:`large`})])):(t(),s(f,{key:1},[r[25]||=u(`h2`,{style:{"margin-bottom":`18px`}},`系统设置`,-1),h(J,{title:`LLM 大模型配置`,size:`small`,style:{"margin-bottom":`14px`}},{extra:d(()=>[h(g,null,{default:d(()=>[h(p,{size:`small`,onClick:z,loading:w.value},{default:d(()=>[...r[13]||=[m(`测试连接`,-1)]]),_:1},8,[`loading`]),h(p,{size:`small`,type:`primary`,onClick:r[0]||=e=>R(D)},{default:d(()=>[...r[14]||=[m(`保存`,-1)]]),_:1})]),_:1})]),default:d(()=>[T.value===null?c(``,!0):(t(),l(S,{key:0,type:T.value?`success`:`error`,message:T.value?`连接成功`:`连接失败`,description:E.value,"show-icon":``,style:{"margin-bottom":`14px`},closable:``},null,8,[`type`,`message`,`description`])),h(q,{column:2,size:`small`,bordered:``},{default:d(()=>[h(W,{label:`API 协议`,span:2},{default:d(()=>[h(U,{value:L.value,"onUpdate:value":r[1]||=e=>L.value=e,style:{width:`100%`}},{default:d(()=>[h(H,{gutter:[8,8]},{default:d(()=>[(t(),s(f,null,n(N,e=>h(V,{key:e.value,span:8},{default:d(()=>[h(B,{value:e.value,style:{display:`block`}},{default:d(()=>[u(`span`,v,o(e.label),1),u(`div`,y,o(e.desc),1),u(`div`,b,o(e.endpoint),1)]),_:2},1032,[`value`])]),_:2},1024)),64))]),_:1})]),_:1},8,[`value`])]),_:1}),h(W,{label:`API 地址`,span:2},{default:d(()=>[h(G,{value:F(`llm.base_url`),onChange:r[2]||=e=>I(`llm.base_url`,e.target.value),placeholder:`https://api.openai.com/v1`},null,8,[`value`]),r[15]||=u(`div`,{style:{color:`#999`,"font-size":`11px`,"margin-top":`2px`}},`会自动拼上协议路径`,-1)]),_:1}),h(W,{label:`API Key`,span:2},{default:d(()=>[h(S,{type:`info`,message:`API Key 仅通过服务器环境变量 LLM_API_KEY 配置,后台不会读取或显示完整密钥。`,"show-icon":``})]),_:1}),h(W,{label:`模型名称`,span:2},{default:d(()=>[h(G,{value:F(`llm.model`),onChange:r[3]||=e=>I(`llm.model`,e.target.value),placeholder:`gpt-4o-mini`},null,8,[`value`])]),_:1}),h(W,{label:`最大输出 Token`,span:1},{default:d(()=>[h(K,{value:F(`llm.max_tokens`),onChange:r[4]||=e=>I(`llm.max_tokens`,e),style:{width:`100%`},min:1},null,8,[`value`])]),_:1}),h(W,{label:`温度`,span:1},{default:d(()=>[h(K,{value:F(`llm.temperature`),onChange:r[5]||=e=>I(`llm.temperature`,e),style:{width:`100%`},min:0,max:2,step:.1},null,8,[`value`])]),_:1})]),_:1})]),_:1}),h(J,{title:`限额配置`,size:`small`,style:{"margin-bottom":`14px`}},{extra:d(()=>[h(p,{size:`small`,type:`primary`,onClick:r[6]||=e=>R(O)},{default:d(()=>[...r[16]||=[m(`保存`,-1)]]),_:1})]),default:d(()=>[h(q,{column:2,size:`small`,bordered:``},{default:d(()=>[(t(),s(f,null,n(O,e=>h(W,{key:e,label:P[e]?.label,span:1},{default:d(()=>[h(K,{value:F(e),onChange:t=>I(e,t),style:{width:`100%`},min:0},null,8,[`value`,`onChange`])]),_:2},1032,[`label`])),64))]),_:1})]),_:1}),h(J,{title:`功能开关`,size:`small`,style:{"margin-bottom":`14px`}},{extra:d(()=>[h(p,{size:`small`,type:`primary`,onClick:r[7]||=e=>R(k)},{default:d(()=>[...r[17]||=[m(`保存`,-1)]]),_:1})]),default:d(()=>[h(q,{column:2,size:`small`,bordered:``},{default:d(()=>[(t(),s(f,null,n(k,e=>h(W,{key:e,label:P[e]?.label,span:1},{default:d(()=>[h(Y,{checked:F(e),onChange:t=>I(e,t)},null,8,[`checked`,`onChange`])]),_:2},1032,[`label`])),64))]),_:1})]),_:1}),h(J,{title:`注册默认权限`,size:`small`,style:{"margin-bottom":`14px`}},{extra:d(()=>[h(p,{size:`small`,type:`primary`,onClick:r[8]||=e=>R(A)},{default:d(()=>[...r[18]||=[m(`保存`,-1)]]),_:1})]),default:d(()=>[h(q,{column:1,size:`small`,bordered:``},{default:d(()=>[(t(),s(f,null,n(A,e=>h(W,{key:e,label:P[e]?.label},{default:d(()=>[h(Y,{checked:F(e),onChange:t=>I(e,t)},null,8,[`checked`,`onChange`]),u(`span`,x,o(P[e]?.desc),1)]),_:2},1032,[`label`])),64))]),_:1})]),_:1}),h(J,{title:`新用户 AI 对话额度`,size:`small`,style:{"margin-bottom":`14px`}},{extra:d(()=>[h(p,{size:`small`,type:`primary`,onClick:r[9]||=e=>R(j)},{default:d(()=>[...r[19]||=[m(`保存`,-1)]]),_:1})]),default:d(()=>[h(q,{column:2,size:`small`,bordered:``},{default:d(()=>[h(W,{label:`默认次数`},{default:d(()=>[h(K,{value:F(`quota.default_ai_chat_limit`),onChange:r[10]||=e=>I(`quota.default_ai_chat_limit`,e),style:{width:`100%`},min:0,max:1e6},null,8,[`value`]),r[20]||=u(`div`,{style:{color:`#999`,"font-size":`11px`,"margin-top":`3px`}},`0 表示不限次数`,-1)]),_:1}),h(W,{label:`重置周期`},{default:d(()=>[h(Z,{value:F(`quota.default_ai_chat_period`)||`day`,onChange:r[11]||=e=>I(`quota.default_ai_chat_period`,e),style:{width:`100%`}},{default:d(()=>[h(X,{value:`day`},{default:d(()=>[...r[21]||=[m(`每天`,-1)]]),_:1}),h(X,{value:`week`},{default:d(()=>[...r[22]||=[m(`每周(周一开始)`,-1)]]),_:1}),h(X,{value:`month`},{default:d(()=>[...r[23]||=[m(`每月`,-1)]]),_:1})]),_:1},8,[`value`])]),_:1})]),_:1})]),_:1}),h(J,{title:`系统 & 品牌`,size:`small`,style:{"margin-bottom":`14px`}},{extra:d(()=>[h(p,{size:`small`,type:`primary`,onClick:r[12]||=e=>R(M)},{default:d(()=>[...r[24]||=[m(`保存`,-1)]]),_:1})]),default:d(()=>[h(q,{column:2,size:`small`,bordered:``},{default:d(()=>[(t(),s(f,null,n(M,e=>h(W,{key:e,label:P[e]?.label,span:e===`brand.slogan`||e===`brand.logo_url`?2:1},{default:d(()=>[e===`system.max_ledgers_per_user`?(t(),l(K,{key:0,value:F(e),onChange:t=>I(e,t),style:{width:`100%`},min:1,max:50},null,8,[`value`,`onChange`])):(t(),l(G,{key:1,value:F(e),onChange:t=>I(e,t.target.value)},null,8,[`value`,`onChange`]))]),_:2},1032,[`label`,`span`])),64))]),_:1})]),_:1})],64))}}});export{S as default};