@ytchuan/flowlink 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +176 -0
  2. package/app-ui/dist/assets/BaseCard-BquKu8iW.js +1 -0
  3. package/app-ui/dist/assets/BaseCard-vDGVmnfA.css +1 -0
  4. package/app-ui/dist/assets/ConsumptionView-Bv1BmzJZ.css +1 -0
  5. package/app-ui/dist/assets/ConsumptionView-CKpT-R7X.js +1 -0
  6. package/app-ui/dist/assets/HomeView-BXZYBUAv.js +1 -0
  7. package/app-ui/dist/assets/HomeView-C0c8S1Ss.css +1 -0
  8. package/app-ui/dist/assets/MetricCard-CIRjcKHO.css +1 -0
  9. package/app-ui/dist/assets/MetricCard-irffmzJu.js +1 -0
  10. package/app-ui/dist/assets/PackageView-C0KTgqoW.css +1 -0
  11. package/app-ui/dist/assets/PackageView-DzGcYqiI.js +1 -0
  12. package/app-ui/dist/assets/SettingsView-CKxlifru.js +2 -0
  13. package/app-ui/dist/assets/SettingsView-Co_5arPi.css +1 -0
  14. package/app-ui/dist/assets/StatusBadge-BeZad7-E.js +1 -0
  15. package/app-ui/dist/assets/StatusBadge-jZK8Ckfn.css +1 -0
  16. package/app-ui/dist/assets/index-C2wBeAgU.js +2269 -0
  17. package/app-ui/dist/assets/index-EXys6EPN.css +1 -0
  18. package/app-ui/dist/index.html +13 -0
  19. package/assets/icon.icns +0 -0
  20. package/assets/icon.ico +0 -0
  21. package/assets/logo256.png +0 -0
  22. package/assets/logo512.png +0 -0
  23. package/bin/flowlink.js +24 -0
  24. package/main.js +315 -0
  25. package/package.json +88 -0
  26. package/preload.js +103 -0
  27. package/resources/tray-icon.png +0 -0
  28. package/services/config-writer.js +415 -0
  29. package/services/device.js +104 -0
  30. package/services/scanner.js +254 -0
  31. package/services/scheduler.js +197 -0
  32. package/services/selfcheck.js +154 -0
  33. package/services/settings.js +58 -0
  34. package/services/tray.js +110 -0
  35. package/services/updater.js +26 -0
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # FlowLink Electron 客户端
2
+
3
+ FlowLink 桌面客户端主进程,基于 Electron + Node.js,负责本地调度服务、客户端配置写入、设备管理、环境自检等功能。
4
+
5
+ ## 目录结构
6
+
7
+ ```
8
+ app/
9
+ ├── main.js # 主进程入口,注册 IPC、窗口生命周期
10
+ ├── preload.js # 渲染进程预加载脚本,暴露 electronAPI
11
+ ├── services/ # 主进程服务模块
12
+ │ ├── scheduler.js # 本地 HTTP 调度代理服务
13
+ │ ├── config-writer.js # 客户端配置写入/备份/还原
14
+ │ ├── device.js # 设备标识管理
15
+ │ ├── scanner.js # 已安装客户端扫描
16
+ │ ├── selfcheck.js # 环境自检
17
+ │ ├── settings.js # 本地配置持久化
18
+ │ ├── tray.js # 系统托盘
19
+ │ └── updater.js # 更新检查
20
+ ├── scripts/ # 发布辅助脚本
21
+ │ ├── copy-ui.js # 发布前复制渲染层产物到包内
22
+ │ └── manifest-electron.js # 发布时切换 electron 依赖位置
23
+ ├── docs/ # 设计文档与 Agent 说明
24
+ └── package.json # 依赖与 electron-builder 打包配置
25
+ ```
26
+
27
+ ## 环境要求
28
+
29
+ - Node.js 22.x(推荐与 `.node-version` 保持一致)
30
+ - npm 或 pnpm
31
+ - macOS / Windows(当前主要支持平台)
32
+
33
+ ## 本地开发
34
+
35
+ ### 1. 安装依赖
36
+
37
+ ```bash
38
+ cd soft-ats-clients/app
39
+ npm install
40
+ ```
41
+
42
+ ### 2. 同时启动渲染层与 Electron
43
+
44
+ ```bash
45
+ npm run dev
46
+ ```
47
+
48
+ 该命令会:
49
+ - 在 `../app-ui` 启动 Vite 开发服务器(默认端口 5173)
50
+ - 等待 5173 端口就绪后启动 Electron
51
+
52
+ ### 3. 单独启动 Electron(需先启动 app-ui 开发服务器)
53
+
54
+ ```bash
55
+ npm start
56
+ ```
57
+
58
+ ## 构建与打包
59
+
60
+ ### 前置步骤:构建渲染层
61
+
62
+ 所有打包命令都会先执行 `npm run build:ui`,将 `../app-ui/dist` 产物复制到应用包中。
63
+
64
+ ```bash
65
+ npm run build:ui
66
+ ```
67
+
68
+ ### 默认打包(当前平台,同时输出安装包 + 便携版)
69
+
70
+ ```bash
71
+ npm run build
72
+ ```
73
+
74
+ ### 分平台打包
75
+
76
+ | 命令 | 说明 | 输出产物 |
77
+ |---|---|---|
78
+ | `npm run build:mac` | macOS 完整构建 | `.dmg` 安装包 + `.zip` 便携版 |
79
+ | `npm run build:mac:zip` | macOS 仅便携版 | `.zip`(解压后双击 `.app` 运行) |
80
+ | `npm run build:win` | Windows 完整构建 | `.exe` 安装包 + `portable` 文件夹 |
81
+ | `npm run build:win:portable` | Windows 仅便携版 | 单个可执行文件夹,无需安装 |
82
+
83
+ ## npm 发布
84
+
85
+ ### 前置条件
86
+
87
+ 1. 已在 [npmjs.com](https://www.npmjs.com/) 注册账号
88
+ 2. 已在本地登录 npm:
89
+
90
+ ```bash
91
+ npm login
92
+ ```
93
+
94
+ 3. 包名为 `@ytchuan/flowlink`(scoped 包),如需更换组织名,在 `package.json` 中修改 `name` 即可(`publishConfig.access` 已设为 `public`)
95
+
96
+ ### 发布流程
97
+
98
+ ```bash
99
+ cd soft-ats-clients/app
100
+ npm publish
101
+ ```
102
+
103
+ `npm publish` 会依次执行:
104
+ 1. `prepack`:`npm run build:ui && node scripts/copy-ui.js && node scripts/manifest-electron.js rewrite`,构建渲染层并将 `../app-ui/dist` 产物复制到包内 `app-ui/dist`,再将发布清单中的 `electron` 从 `devDependencies` 移入 `dependencies`(electron-builder 要求本地必须在 `devDependencies`,而用户全局安装只会安装 `dependencies`,两者通过此脚本兼得);
105
+ 2. `postpack`:自动将本地 `package.json` 中的 `electron` 恢复回 `devDependencies`。
106
+
107
+ > 所有发布准备工作统一挂在 `prepack` 上,因此 `npm pack` 打出的本地 tarball 与正式发布的包内容完全一致,可直接用于发布前验证。
108
+
109
+ ### 发布后用户安装与运行
110
+
111
+ ```bash
112
+ npm install -g @ytchuan/flowlink
113
+ flowlink
114
+ ```
115
+
116
+ ### 本地测试(不发布到 npm)
117
+
118
+ ```bash
119
+ cd soft-ats-clients/app
120
+ npm link # 本地全局链接
121
+ flowlink # 测试启动
122
+ ```
123
+
124
+ ### 注意事项
125
+
126
+ - 首次 `npm install -g @ytchuan/flowlink` 会下载 Electron(~150MB),需要耐心等待。
127
+ - 国内网络若下载 Electron 超时,可先设置镜像:
128
+ ```bash
129
+ export ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
130
+ npm install -g @ytchuan/flowlink
131
+ ```
132
+ - 发布前请确认 `package.json` 中的 `version` 已更新,npm 不允许重复发布同一版本。
133
+ - 如需发布 beta 版本:`npm publish --tag beta`
134
+
135
+ ## 输出目录
136
+
137
+ 打包产物统一输出到:
138
+
139
+ ```
140
+ app/dist-electron/
141
+ ```
142
+
143
+ 按平台与子目录组织,例如:
144
+
145
+ ```
146
+ dist-electron/
147
+ ├── mac/
148
+ │ ├── FlowLink-1.5.2.dmg
149
+ │ └── FlowLink-1.5.2-mac.zip
150
+ └── win-unpacked/
151
+ ├── FlowLink.exe # 便携版可直接运行
152
+ └── ...
153
+ ```
154
+
155
+ ## 便携版说明
156
+
157
+ - **macOS**:`FlowLink-x.x.x-mac.zip` 解压后得到 `FlowLink.app`,双击即可运行,无需安装到 Applications。
158
+ - **Windows**:`win-unpacked/FlowLink.exe` 为绿色便携版,复制整个 `win-unpacked` 文件夹到任意位置即可运行。
159
+
160
+ ## 常用配置
161
+
162
+ 打包相关配置位于 `package.json` 的 `build` 字段:
163
+
164
+ - `appId`:应用标识
165
+ - `productName`:应用名称
166
+ - `directories.output`:输出目录
167
+ - `files`:需要打入应用包的文件
168
+ - `extraResources`:额外复制的静态资源(如 `../app-ui/dist`)
169
+ - `mac.target` / `win.target`:打包目标格式
170
+
171
+ ## 注意事项
172
+
173
+ 1. 打包前请确保 `../app-ui` 已能成功构建:`cd ../app-ui && npm run build`。
174
+ 2. macOS 打包可能需要在「系统设置 > 隐私与安全性」中允许相关权限。
175
+ 3. 若签名/公证失败,可临时在 `build` 配置中关闭 `asar` 或调整 `mac.identity` 排查。
176
+ 4. 本地调度服务端口默认为 `51173`,占用时自动回退到 `51172`、`51171`。
@@ -0,0 +1 @@
1
+ import{d as i,r,o as s,b as t,E as d,e as n,p as _,j as o,t as c,G as u,_ as b}from"./index-C2wBeAgU.js";const m={class:"base-card"},h={key:0,class:"base-card__header"},v={class:"base-card__title-group"},y={key:0,class:"base-card__title"},k={key:1,class:"base-card__subtitle"},B={key:0,class:"base-card__extra"},f=i({__name:"BaseCard",props:{title:{},subtitle:{},icon:{},noPadding:{type:Boolean,default:!1}},setup(e){return(a,C)=>{const l=r("t-icon");return s(),t("div",m,[e.title||a.$slots.header?(s(),t("div",h,[d(a.$slots,"header",{},()=>[n("div",v,[e.icon?(s(),_(l,{key:0,name:e.icon,class:"base-card__icon"},null,8,["name"])):o("",!0),n("div",null,[e.title?(s(),t("h3",y,c(e.title),1)):o("",!0),e.subtitle?(s(),t("p",k,c(e.subtitle),1)):o("",!0)])])]),a.$slots.extra?(s(),t("div",B,[d(a.$slots,"extra",{},void 0)])):o("",!0)])):o("",!0),n("div",{class:u(["base-card__body",{"base-card__body--no-padding":e.noPadding}])},[d(a.$slots,"default",{},void 0)],2)])}}}),$=b(f,[["__scopeId","data-v-5d989854"]]);export{$ as B};
@@ -0,0 +1 @@
1
+ .base-card[data-v-5d989854]{background:var(--td-bg-color-container);border-radius:var(--radius-md);box-shadow:var(--shadow-card)}.base-card__header[data-v-5d989854]{display:flex;align-items:center;justify-content:space-between;padding:20px 20px 0}.base-card__title-group[data-v-5d989854]{display:flex;align-items:flex-start;gap:var(--space-sm)}.base-card__icon[data-v-5d989854]{font-size:18px;color:var(--td-text-color-secondary);margin-top:2px}.base-card__title[data-v-5d989854]{font-size:var(--font-title);font-weight:600;color:var(--td-text-color-primary);line-height:1.4}.base-card__subtitle[data-v-5d989854]{font-size:var(--font-caption);color:var(--td-text-color-secondary);margin-top:2px}.base-card__extra[data-v-5d989854]{flex-shrink:0}.base-card__body[data-v-5d989854]{padding:20px}.base-card__body--no-padding[data-v-5d989854]{padding:0}
@@ -0,0 +1 @@
1
+ .consumption-overview[data-v-c5c1a04b]{display:flex;gap:var(--space-xl)}.consumption-table__pagination[data-v-77506e99]{display:flex;justify-content:center;margin-top:var(--space-lg)}.consumption-view[data-v-cdac19a5]{display:flex;flex-direction:column;gap:var(--space-lg)}
@@ -0,0 +1 @@
1
+ import{d as m,A as _,s as y,o as C,p as b,w as s,e as p,f as i,g as a,_ as g,r as w,n as F,t as l,i as d,b as M}from"./index-C2wBeAgU.js";import{B as S}from"./BaseCard-BquKu8iW.js";import{M as T}from"./MetricCard-irffmzJu.js";const D={class:"consumption-overview"},I=m({__name:"ConsumptionOverview",setup(f){const r=_(),{overview:c}=y(r);return(v,h)=>(C(),b(S,{title:"消耗概览",subtitle:"查看每次调用的模型、Token 消耗与结果",icon:"chart-bar"},{default:s(()=>[p("div",D,[i(T,{label:"累计消耗(积分)",value:a(c).totalConsumption.toFixed(2),valueColor:"default"},null,8,["value"]),i(T,{label:"今日消耗(积分)",value:a(c).todayConsumption.toFixed(2),valueColor:"primary"},null,8,["value"])])]),_:1}))}}),N=g(I,[["__scopeId","data-v-c5c1a04b"]]),G={class:"consumption-table__pagination"},O=m({__name:"ConsumptionTable",setup(f){const r=_(),{records:c,total:v,currentPage:h,pageSize:x,loading:k}=y(r),$=[{colKey:"createTime",title:"时间",width:160},{colKey:"model",title:"模型",width:150},{colKey:"inputTokens",title:"请求Token",width:100},{colKey:"outputTokens",title:"响应Token",width:100},{colKey:"consumedPoints",title:"消耗积分",width:100},{colKey:"statusCode",title:"状态",width:80}];function B(t){const e=new Date(t),n=u=>String(u).padStart(2,"0");return`${e.getFullYear()}-${n(e.getMonth()+1)}-${n(e.getDate())} ${n(e.getHours())}:${n(e.getMinutes())}:${n(e.getSeconds())}`}function P(t){return(t==null?void 0:t.toFixed(2))??"0.00"}function K(t){return{CG:"成功",SB:"失败",CS:"超时"}[t]||t}function z(t){return{CG:"var(--td-success-color)",SB:"var(--td-error-color)",CS:"var(--td-warning-color)"}[t]||"var(--td-text-color-primary)"}function V(t){r.changePage(t)}return(t,e)=>{const n=w("t-table"),u=w("t-pagination");return C(),b(S,{title:"消耗明细",subtitle:"每次调用的模型、Token 消耗与结果",icon:"list"},{default:s(()=>[i(n,{data:a(c),columns:$,loading:a(k),"row-key":"id",stripe:"",hover:"",bordered:"",empty:"暂无记录"},{createTime:s(({row:o})=>[d(l(B(o.createTime)),1)]),model:s(({row:o})=>[d(l(o.model),1)]),consumedPoints:s(({row:o})=>[d(l(P(o.consumedPoints)),1)]),statusCode:s(({row:o})=>[p("span",{style:F({color:z(o.statusCode),fontWeight:500})},l(K(o.statusCode)),5)]),_:1},8,["data","loading"]),p("div",G,[i(u,{current:a(h),"page-size":a(x),total:a(v),"show-jumper":!1,size:"small",onChange:V},null,8,["current","page-size","total"])])]),_:1})}}}),j=g(O,[["__scopeId","data-v-77506e99"]]),A={class:"consumption-view"},E=m({__name:"ConsumptionView",setup(f){return _(),(r,c)=>(C(),M("div",A,[i(N),i(j)]))}}),Y=g(E,[["__scopeId","data-v-cdac19a5"]]);export{Y as default};
@@ -0,0 +1 @@
1
+ import{u as T,s as h,c as _,d as b,a as x,o as v,b as g,e,f as o,g as n,n as B,t as m,_ as S,h as D,r as y,w as p,i as $,j as I,k as z,l as M,m as N,p as P,M as E}from"./index-C2wBeAgU.js";import{S as w}from"./StatusBadge-BeZad7-E.js";import{B as F}from"./BaseCard-BquKu8iW.js";function H(){const f=T(),{alertSettings:t}=h(f),s=_(()=>t.value.yellowThreshold),c=_(()=>t.value.redThreshold),i=_(()=>t.value.popupEnabled);return{yellowThreshold:s,redThreshold:c,popupEnabled:i,alertSettings:t}}const R={class:"balance-card"},j={class:"balance-card__header"},Q={class:"balance-card__body"},W={class:"balance-card__package-count"},q={class:"balance-card__progress"},G={class:"balance-card__progress-bar"},J={class:"balance-card__progress-info"},K=b({__name:"BalanceCard",setup(f){const t=x(),{balance:s,packageCount:c,isActivated:i,totalQuota:r,consumed:d}=h(t),{yellowThreshold:a,redThreshold:l}=H(),u=_(()=>Math.max(r.value-s.value,0)),C=_(()=>r.value?Math.min(u.value/r.value*100,100):0),V=_(()=>!i.value||s.value<=0?"var(--td-text-color-primary)":s.value<=l.value?"var(--td-error-color)":s.value<=a.value?"var(--td-warning-color)":"var(--td-text-color-primary)"),A=_(()=>s.value.toFixed(2));return(me,k)=>(v(),g("div",R,[e("div",j,[k[0]||(k[0]=e("div",{class:"balance-card__title-area"},[e("div",null,[e("div",{class:"balance-card__title"},"积分包余额")])],-1)),o(w,{type:n(i)?"active":"inactive"},null,8,["type"])]),e("div",Q,[e("div",{class:"balance-card__amount",style:B({color:V.value})},m(A.value),5),e("div",W,"("+m(n(c))+" 个积分包)",1),e("div",q,[e("div",G,[e("div",{class:"balance-card__progress-fill",style:B({width:C.value+"%"})},null,4)]),e("div",J,[e("span",null,"已消耗 "+m(u.value.toFixed(2)),1),e("span",null,"总额度 "+m(n(r).toFixed(2)),1)])])])]))}}),L=S(K,[["__scopeId","data-v-ad6381d6"]]),O={class:"service-card"},U={class:"service-card__header"},X={class:"service-card__title-area"},Y={key:0,class:"service-card__tip"},Z={key:1,class:"service-card__tip",style:{color:"#555555"}},ee=b({__name:"ServiceCard",setup(f){const t=D(),s=x(),{running:c,starting:i}=h(t),{isActivated:r}=h(s);async function d(){c.value?await t.stop():await t.start()}return(a,l)=>{const u=y("t-icon"),C=y("t-button");return v(),g("div",O,[e("div",U,[e("div",X,[o(u,{name:"info-circle",size:"16px",style:{color:"var(--td-text-color-secondary)"}}),l[0]||(l[0]=e("span",{class:"service-card__title"},"调度服务",-1))]),o(w,{type:n(c)?"running":"stopped"},null,8,["type"])]),l[1]||(l[1]=e("p",{class:"service-card__desc"},"为客户提供稳定的 AI 服务",-1)),o(C,{theme:"primary",disabled:!n(r)||n(i),loading:n(i),onClick:d},{icon:p(()=>[o(u,{name:n(c)?"stop-circle":"play-circle"},null,8,["name"])]),default:p(()=>[$(" "+m(n(c)?"停止服务":"启动服务"),1)]),_:1},8,["disabled","loading"]),n(r)?I("",!0):(v(),g("p",Y,"请先激活积分包")),n(r)?(v(),g("p",Z,"点击启动服务激活本地API端点")):I("",!0)])}}}),te=S(ee,[["__scopeId","data-v-74a89612"]]),se={class:"client-config-card"},oe={class:"client-config-card__header"},ae={class:"client-config-card__title-area"},ce=b({__name:"ClientConfigCard",setup(f){const t=z(),s=T(),{clientTargets:c}=h(s),i=_(()=>c.value.some(d=>d.installed));function r(){t.push("/settings")}return(d,a)=>{const l=y("t-icon"),u=y("t-button");return v(),g("div",se,[e("div",oe,[e("div",ae,[o(l,{name:"info-circle",size:"16px",style:{color:"var(--td-text-color-secondary)"}}),a[0]||(a[0]=e("span",{class:"client-config-card__title"},"配置客户端",-1))]),o(w,{type:i.value?"active":"unconfigured"},null,8,["type"])]),a[2]||(a[2]=e("p",{class:"client-config-card__desc"},"一键配置 WorkBuddy / CodeBuddy 客户端",-1)),o(u,{theme:"primary",onClick:r},{icon:p(()=>[o(l,{name:"setting"})]),default:p(()=>[a[1]||(a[1]=$(" 一键配置 ",-1))]),_:1}),a[3]||(a[3]=e("p",{class:"client-config-card__tip"},"前往设置页完成客户端接入配置",-1))])}}}),ne=S(ce,[["__scopeId","data-v-2f01f11b"]]),ie={class:"device-info"},re={class:"device-info__row"},le={class:"device-info__value-row"},de={class:"device-info__value mono-font"},_e=b({__name:"DeviceInfoSection",setup(f){const t=M(),{deviceId:s}=h(t),{clipboard:c}=N();async function i(){await c.write(s.value),E.success("已复制")}return(r,d)=>{const a=y("t-icon"),l=y("t-button");return v(),P(F,{title:"设备信息",subtitle:"当前设备的唯一标识",icon:"info-circle"},{default:p(()=>[e("div",ie,[e("div",re,[d[1]||(d[1]=e("span",{class:"device-info__label"},"设备标识",-1)),e("div",le,[e("code",de,m(n(s)||"加载中..."),1),o(l,{variant:"text",size:"small",onClick:i},{icon:p(()=>[o(a,{name:"file-copy"})]),default:p(()=>[d[0]||(d[0]=$(" 复制 ",-1))]),_:1})])])])]),_:1})}}}),ue=S(_e,[["__scopeId","data-v-fc4e4aec"]]),ve={class:"home-view"},pe={class:"home-view__dual-cards"},fe=b({__name:"HomeView",setup(f){return x(),(t,s)=>(v(),g("div",ve,[o(L),e("div",pe,[o(te),o(ne)]),o(ue)]))}}),be=S(fe,[["__scopeId","data-v-c95f28fa"]]);export{be as default};
@@ -0,0 +1 @@
1
+ .balance-card[data-v-ad6381d6]{background:var(--td-bg-color-container);border-radius:var(--radius-md);box-shadow:var(--shadow-card);padding:20px}.balance-card__header[data-v-ad6381d6]{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-md)}.balance-card__title-area[data-v-ad6381d6]{display:flex;align-items:center;gap:var(--space-sm)}.balance-card__title[data-v-ad6381d6]{font-size:var(--font-title);font-weight:600;color:var(--td-text-color-primary)}.balance-card__amount[data-v-ad6381d6]{font-size:var(--font-hero);font-weight:700;line-height:1.2}.balance-card__package-count[data-v-ad6381d6]{font-size:var(--font-caption);color:var(--td-text-color-secondary);margin-top:var(--space-xs)}.balance-card__progress[data-v-ad6381d6]{margin-top:var(--space-lg)}.balance-card__progress-bar[data-v-ad6381d6]{height:6px;background:var(--td-gray-color-3);border-radius:3px;overflow:hidden}.balance-card__progress-fill[data-v-ad6381d6]{height:100%;background:var(--td-brand-color);border-radius:3px;transition:width .3s ease}.balance-card__progress-info[data-v-ad6381d6]{display:flex;justify-content:space-between;margin-top:var(--space-xs);font-size:var(--font-caption);color:var(--td-text-color-secondary)}.service-card[data-v-74a89612]{flex:1;background:var(--td-bg-color-container);border-radius:var(--radius-md);box-shadow:var(--shadow-card);padding:20px;display:flex;flex-direction:column}.service-card__header[data-v-74a89612]{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-sm)}.service-card__title-area[data-v-74a89612]{display:flex;align-items:center;gap:var(--space-sm)}.service-card__title[data-v-74a89612]{font-size:var(--font-title);font-weight:600;color:var(--td-text-color-primary)}.service-card__desc[data-v-74a89612]{font-size:var(--font-body);color:var(--td-text-color-secondary);margin-bottom:var(--space-lg);flex:1}.service-card__tip[data-v-74a89612]{font-size:var(--font-caption);color:var(--td-warning-color);margin-top:var(--space-sm)}.client-config-card[data-v-2f01f11b]{flex:1;background:var(--td-bg-color-container);border-radius:var(--radius-md);box-shadow:var(--shadow-card);padding:20px;display:flex;flex-direction:column}.client-config-card__header[data-v-2f01f11b]{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-sm)}.client-config-card__title-area[data-v-2f01f11b]{display:flex;align-items:center;gap:var(--space-sm)}.client-config-card__title[data-v-2f01f11b]{font-size:var(--font-title);font-weight:600;color:var(--td-text-color-primary)}.client-config-card__desc[data-v-2f01f11b]{font-size:var(--font-body);color:var(--td-text-color-secondary);margin-bottom:var(--space-lg);flex:1}.client-config-card__tip[data-v-2f01f11b]{font-size:var(--font-caption);color:var(--td-text-color-secondary);margin-top:var(--space-sm)}.device-info__row[data-v-fc4e4aec]{display:flex;align-items:center;justify-content:space-between}.device-info__label[data-v-fc4e4aec]{font-size:var(--font-label);font-weight:500;color:var(--td-text-color-primary);flex-shrink:0}.device-info__value-row[data-v-fc4e4aec]{display:flex;align-items:center;gap:var(--space-sm);min-width:0}.device-info__value[data-v-fc4e4aec]{font-size:var(--font-body);color:var(--td-text-color-secondary);background:var(--td-bg-color-page);padding:6px 12px;border-radius:var(--radius-sm);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.home-view[data-v-c95f28fa]{display:flex;flex-direction:column;gap:var(--space-lg)}.home-view__dual-cards[data-v-c95f28fa]{display:flex;gap:var(--space-lg)}
@@ -0,0 +1 @@
1
+ .metric-card[data-v-ce08033b]{display:flex;flex-direction:column;gap:var(--space-xs);min-width:0}.metric-card__value[data-v-ce08033b]{font-size:24px;font-weight:700;line-height:1.2}.metric-card__label[data-v-ce08033b]{font-size:var(--font-caption);color:var(--td-text-color-secondary)}
@@ -0,0 +1 @@
1
+ import{d as s,o as l,b as d,e as a,t as r,n,c as i,_ as u}from"./index-C2wBeAgU.js";const v={class:"metric-card"},_={class:"metric-card__label"},m=s({__name:"MetricCard",props:{label:{},value:{},valueColor:{default:"default"}},setup(e){const o=e,c={primary:"var(--td-brand-color)",success:"var(--td-success-color)",default:"var(--td-text-color-primary)",warning:"var(--td-warning-color)",error:"var(--td-error-color)"},t=i(()=>c[o.valueColor]);return(p,f)=>(l(),d("div",v,[a("div",{class:"metric-card__value",style:n({color:t.value})},r(e.value),5),a("div",_,r(e.label),1)]))}}),y=u(m,[["__scopeId","data-v-ce08033b"]]);export{y as M};
@@ -0,0 +1 @@
1
+ .package-overview__metrics[data-v-abaf465d]{display:flex;gap:var(--space-xl);margin-bottom:var(--space-lg)}.package-overview__progress-bar[data-v-abaf465d]{height:6px;background:var(--td-gray-color-3);border-radius:3px;overflow:hidden}.package-overview__progress-fill[data-v-abaf465d]{height:100%;background:var(--td-brand-color);border-radius:3px;transition:width .3s ease}.package-overview__progress-info[data-v-abaf465d]{display:flex;justify-content:space-between;margin-top:var(--space-xs);font-size:var(--font-caption);color:var(--td-text-color-secondary)}.activate-modal__desc[data-v-3e973f82]{font-size:var(--font-body);color:var(--td-text-color-secondary);margin-bottom:var(--space-lg)}.package-view[data-v-4ceb9f48]{display:flex;flex-direction:column;gap:var(--space-lg)}
@@ -0,0 +1 @@
1
+ import{d as w,a as C,s as V,o as x,p as S,w as a,e as l,f as s,g as p,n as z,t as _,c as T,_ as M,r as k,i as m,D as Y,M as h,q as A,v as P,x as Q,y as D,b as F,z as q}from"./index-C2wBeAgU.js";import{S as U}from"./StatusBadge-BeZad7-E.js";import{M as B}from"./MetricCard-irffmzJu.js";import{B as K}from"./BaseCard-BquKu8iW.js";const I={class:"package-overview"},N={class:"package-overview__metrics"},E={class:"package-overview__progress"},G={class:"package-overview__progress-bar"},O={class:"package-overview__progress-info"},R=w({__name:"PackageOverview",setup(b){const c=C(),{overview:r,isActivated:g,totalQuota:n,consumed:i}=V(c),u=T(()=>Math.max(n.value-r.value.totalBalance,0)),v=T(()=>n.value?Math.min(u.value/n.value*100,100):0);return(y,t)=>(x(),S(K,{title:"兑换码总览",subtitle:"当前用户已兑换的兑换码汇总"},{extra:a(()=>[s(U,{type:p(g)?"active":"inactive"},null,8,["type"])]),default:a(()=>[l("div",I,[l("div",N,[s(B,{label:"可用积分余额",value:p(r).totalBalance.toFixed(2),valueColor:"primary"},null,8,["value"]),s(B,{label:"积分包数量",value:p(r).packageCount,valueColor:"default"},null,8,["value"]),s(B,{label:"已失效积分",value:p(i).toFixed(2),valueColor:"default"},null,8,["value"])]),l("div",E,[l("div",G,[l("div",{class:"package-overview__progress-fill",style:z({width:v.value+"%"})},null,4)]),l("div",O,[l("span",null,"已消耗 "+_(u.value.toFixed(2)),1),l("span",null,"总额度 "+_(p(n).toFixed(2)),1)])])])]),_:1}))}}),W=M(R,[["__scopeId","data-v-abaf465d"]]),j={class:"mono-font"},H=w({__name:"PackageTable",setup(b){const c=C(),{cdkRecords:r,loading:g}=V(c),n=[{colKey:"cdkCode",title:"兑换码",minWidth:200,ellipsis:!0},{colKey:"quantity",title:"积分数量",width:120},{colKey:"useQuantity",title:"已使用",width:100},{colKey:"expireTime",title:"到期时间",width:160},{colKey:"statusCode",title:"状态",width:100},{colKey:"op",title:"操作",width:120,fixed:"right"}];function i(t){if(!t)return"-";const e=new Date(t),d=f=>String(f).padStart(2,"0");return`${e.getFullYear()}-${d(e.getMonth()+1)}-${d(e.getDate())} ${d(e.getHours())}:${d(e.getMinutes())}`}function u(t){return{KY:"可用",YWY:"已用完",YGQ:"已过期"}[t]||t}function v(t){return t==="KY"?"success":t==="YGQ"?"warning":"default"}function y(t){const e=Y.confirm({header:"解绑兑换码",body:`确定要解绑兑换码「${t.cdk.cdk}」吗?解绑后剩余积分将被回收。`,confirmBtn:{content:"确定解绑",theme:"danger"},cancelBtn:"取消",onConfirm:async()=>{try{await c.unbind(t.id),h.success("解绑成功"),e.destroy()}catch{h.error("解绑失败"),e.destroy()}}})}return(t,e)=>{const d=k("t-tag"),f=k("t-button"),$=k("t-table");return x(),S(K,{title:"兑换码列表",subtitle:"当前用户已兑换的兑换码记录"},{default:a(()=>[s($,{data:p(r),columns:n,loading:p(g),"row-key":"id",stripe:"",hover:"",bordered:"",empty:"暂无兑换码,请点击右上角兑换"},{cdkCode:a(({row:o})=>[l("code",j,_(o.cdk.cdk),1)]),quantity:a(({row:o})=>[m(_(o.cdk.quantity),1)]),useQuantity:a(({row:o})=>[m(_(o.cdk.useQuantity),1)]),expireTime:a(({row:o})=>[m(_(i(o.cdk.expireTime)),1)]),statusCode:a(({row:o})=>[s(d,{theme:v(o.cdk.statusCode),variant:"light",size:"small"},{default:a(()=>[m(_(u(o.cdk.statusCode)),1)]),_:2},1032,["theme"])]),op:a(({row:o})=>[s(f,{variant:"text",theme:"primary",size:"small",onClick:te=>y(o)},{default:a(()=>[...e[0]||(e[0]=[m(" 解绑 ",-1)])]),_:1},8,["onClick"])]),_:1},8,["data","loading"])]),_:1})}}}),J={class:"activate-modal"},L=w({__name:"ActivatePackageModal",props:{visible:{type:Boolean}},emits:["update:visible"],setup(b,{emit:c}){const r=b,g=c,n=C(),i=P(""),u=P(!1);A(()=>r.visible,t=>{t&&(i.value="")});function v(){g("update:visible",!1)}async function y(){if(!i.value.trim()){h.warning("请输入兑换码");return}u.value=!0;try{await n.activate(i.value.trim()),h.success("兑换成功"),v()}catch(t){const e=t&&typeof t=="object"&&"desc"in t?t.desc:"兑换失败";h.error(e)}finally{u.value=!1}}return(t,e)=>{const d=k("t-input"),f=k("t-button"),$=k("t-dialog");return x(),S($,{visible:b.visible,header:"兑换码兑换",width:480,placement:"center",onClose:v},{footer:a(()=>[s(f,{variant:"outline",size:"large",onClick:v},{default:a(()=>[...e[2]||(e[2]=[m("取消",-1)])]),_:1}),s(f,{theme:"primary",size:"large",loading:u.value,onClick:y},{default:a(()=>[...e[3]||(e[3]=[m(" 立即兑换 ",-1)])]),_:1},8,["loading"])]),default:a(()=>[l("div",J,[e[1]||(e[1]=l("p",{class:"activate-modal__desc"},"输入兑换码兑换积分",-1)),s(d,{modelValue:i.value,"onUpdate:modelValue":e[0]||(e[0]=o=>i.value=o),placeholder:"请输入兑换码",clearable:"",size:"large",onEnter:y},null,8,["modelValue"])])]),_:1},8,["visible"])}}}),X=M(L,[["__scopeId","data-v-3e973f82"]]),Z={class:"package-view"},ee=w({__name:"PackageView",setup(b){C();const c=P(!1),{setAction:r}=q();return Q(()=>{r({label:"兑换码兑换",theme:"primary",icon:"add",handler:()=>{c.value=!0}})}),D(()=>{r(null)}),(g,n)=>(x(),F("div",Z,[s(W),s(H),s(X,{visible:c.value,"onUpdate:visible":n[0]||(n[0]=i=>c.value=i)},null,8,["visible"])]))}}),ie=M(ee,[["__scopeId","data-v-4ceb9f48"]]);export{ie as default};
@@ -0,0 +1,2 @@
1
+ import{d as N,u as K,s as F,r as $,o as y,p as T,w as i,e,f as a,g as x,_ as O,m as z,x as ae,b as U,F as j,B as G,t as A,i as k,v as b,C as q,c as oe,M as m,D as le,j as M,l as ie,a as ce,n as re}from"./index-C2wBeAgU.js";import{B as P}from"./BaseCard-BquKu8iW.js";import{S as ue}from"./StatusBadge-BeZad7-E.js";const de={class:"appearance-section"},pe={class:"appearance-section__row"},_e={class:"appearance-section__row"},fe={class:"appearance-section__row"},ge={class:"appearance-section__row"},ve=N({__name:"AppearanceSection",setup(E){const f=K(),{appSettings:g}=F(f),l=[{label:"浅色",value:"light"},{label:"深色",value:"dark"},{label:"跟随系统",value:"system"}],c=[{label:"最小化到托盘",value:"minimize"},{label:"退出应用",value:"exit"}];async function v(s){await f.saveAppSettings({theme:s})}async function w(s){await f.saveAppSettings({closeBehavior:s})}async function r(s){await f.saveAppSettings({autoStart:s})}async function p(s){await f.saveAppSettings({autoSchedule:s})}return(s,o)=>{const _=$("t-select"),C=$("t-switch");return y(),T(P,{title:"外观与行为",subtitle:"主题、启动与关闭",icon:"palette"},{default:i(()=>[e("div",de,[e("div",pe,[o[0]||(o[0]=e("span",{class:"appearance-section__label"},"主题",-1)),a(_,{value:x(g).theme,options:l,size:"medium",style:{width:"200px"},onChange:v},null,8,["value"])]),e("div",_e,[o[1]||(o[1]=e("span",{class:"appearance-section__label"},"关闭窗口",-1)),a(_,{value:x(g).closeBehavior,options:c,size:"medium",style:{width:"200px"},onChange:w},null,8,["value"])]),e("div",fe,[o[2]||(o[2]=e("span",{class:"appearance-section__label"},"开机自启",-1)),a(C,{value:x(g).autoStart,onChange:r},null,8,["value"])]),e("div",ge,[o[3]||(o[3]=e("div",{class:"appearance-section__label-group"},[e("span",{class:"appearance-section__label"},"自动调度"),e("span",{class:"appearance-section__desc"},"启动时自动启动调度服务")],-1)),a(C,{value:x(g).autoSchedule,onChange:p},null,8,["value"])])])]),_:1})}}}),me=O(ve,[["__scopeId","data-v-9675e52d"]]),he={class:"client-config-section"},ye={class:"client-config-section__sub"},we={class:"client-config-section__targets"},Se={class:"client-config-section__target-info"},be={class:"client-config-section__target-name"},Ce={class:"client-config-section__target-desc"},ke={class:"client-config-section__sub"},$e={class:"client-config-section__config-row"},xe={class:"client-config-section__config-value mono-font"},Ae={class:"client-config-section__config-row"},Ee={class:"client-config-section__config-value mono-font"},Ve={class:"client-config-section__backup-row"},Be={class:"client-config-section__actions"},L="configured_clients",Y="managed_models",Ie=N({__name:"ClientConfigSection",setup(E){const f=K(),{clientTargets:g,clientConfig:l,appSettings:c}=F(f),{config:v,clipboard:w}=z(),r=b([]),p=b(!1),s=b([]),o=b(!1);function _(){const n=localStorage.getItem(L);if(!n)return[];try{return JSON.parse(n)}catch{return[]}}function C(n){localStorage.setItem(L,JSON.stringify(n))}function V(n){const t=new Set(_());t.add(n),C([...t])}function I(n){const t=_().filter(S=>S!==n);C(t)}function D(){const n=localStorage.getItem(Y);if(!n)return[];try{const t=JSON.parse(n);return Array.isArray(t)?t:[]}catch{return[]}}function Q(n){localStorage.setItem(Y,JSON.stringify(n))}async function W(){if(!o.value){o.value=!0;try{const t=(await q.modelPage({},1,100)).records||[];s.value=t,Q(t)}catch(n){console.error("获取模型列表失败:",n),s.value=D()}finally{o.value=!1}}}function R(){return JSON.parse(JSON.stringify(s.value))}ae(()=>{r.value=_(),s.value=D(),W()});const X=oe(()=>g.value.map(n=>({label:n.name,value:n.key,description:n.description,installed:n.installed})));function Z(n,t){t?r.value.includes(n)||r.value.push(n):r.value=r.value.filter(S=>S!==n)}async function J(n){await w.write(n),m.success("已复制")}async function ee(){const n=`API 端点: ${l.value.apiEndpoint}
2
+ API Key: ${l.value.apiKey}`;await w.write(n),m.success("配置已复制")}async function te(){const n=_(),t=[...r.value],S=n.filter(u=>!r.value.includes(u));if(t.length===0&&S.length===0){m.info("没有需要变更的客户端");return}p.value=!0;try{const u=[];if(t.length>0){const d=await v.apply(t,c.value.backupBeforeConfig,{apiEndpoint:l.value.apiEndpoint,apiKey:l.value.apiKey},R());u.push(...d),d.filter(h=>h.success).forEach(h=>V(h.target))}if(S.length>0){const d=await v.restore(S);u.push(...d),d.filter(h=>h.success).forEach(h=>I(h.target))}const B=u.filter(d=>d.success).length;if(B===u.length)m.success(`操作成功(${B} 个客户端)`);else{const d=u.filter(h=>!h.success);m.warning(`部分失败:${d.map(h=>h.message).join(";")}`)}}finally{p.value=!1}}async function se(){if(r.value.length===0){m.warning("请至少选择一个客户端");return}const n=le.confirm({header:"删除配置",body:"将移除已写入选中客户端的配置,恢复原始状态。确定继续吗?",confirmBtn:{content:"确定删除",theme:"danger"},cancelBtn:"取消",onConfirm:async()=>{const t=await v.delete([...r.value],R()),S=t.filter(u=>u.success).length;t.filter(u=>u.success).forEach(u=>I(u.target)),m.success(`已删除 ${S} 个客户端配置`),n.destroy()}})}async function ne(){await v.openBackupDir(),m.success("已打开备份目录")}return(n,t)=>{const S=$("t-checkbox"),u=$("t-icon"),B=$("t-button");return y(),T(P,{title:"客户端配置",subtitle:"一键配置客户端接入本地调度服务",icon:"setting-1"},{default:i(()=>[e("div",he,[e("div",ye,[t[3]||(t[3]=e("div",{class:"client-config-section__sub-title"},"选择目标客户端(可多选)",-1)),e("div",we,[(y(!0),U(j,null,G(X.value,d=>(y(),U("div",{key:d.value,class:"client-config-section__target"},[a(S,{checked:r.value.includes(d.value),onChange:h=>Z(d.value,h)},null,8,["checked","onChange"]),e("div",Se,[e("span",be,A(d.label),1),e("span",Ce,A(d.description),1)]),a(ue,{type:d.installed?"detected":"not-detected"},null,8,["type"])]))),128))])]),e("div",ke,[t[10]||(t[10]=e("div",{class:"client-config-section__sub-title"},"配置信息(用于手动接入其他工具)",-1)),e("div",$e,[t[5]||(t[5]=e("span",{class:"client-config-section__config-label"},"API 端点",-1)),e("code",xe,A(x(l).apiEndpoint),1),a(B,{variant:"text",size:"small",onClick:t[0]||(t[0]=d=>J(x(l).apiEndpoint))},{icon:i(()=>[a(u,{name:"file-copy"})]),default:i(()=>[t[4]||(t[4]=k(" 复制 ",-1))]),_:1})]),e("div",Ae,[t[7]||(t[7]=e("span",{class:"client-config-section__config-label"},"API Key",-1)),e("code",Ee,A(x(l).apiKey),1),a(B,{variant:"text",size:"small",onClick:t[1]||(t[1]=d=>J(x(l).apiKey))},{icon:i(()=>[a(u,{name:"file-copy"})]),default:i(()=>[t[6]||(t[6]=k(" 复制 ",-1))]),_:1})]),e("div",Ve,[a(S,{checked:x(c).backupBeforeConfig,onChange:t[2]||(t[2]=d=>x(f).saveAppSettings({backupBeforeConfig:d}))},{default:i(()=>[...t[8]||(t[8]=[k(" 配置前自动备份原文件(推荐) ",-1)])]),_:1},8,["checked"]),a(B,{variant:"text",size:"small",onClick:ne},{icon:i(()=>[a(u,{name:"folder-open"})]),default:i(()=>[t[9]||(t[9]=k(" 打开备份目录 ",-1))]),_:1})])]),e("div",Be,[a(B,{variant:"outline",onClick:ee},{icon:i(()=>[a(u,{name:"file-copy"})]),default:i(()=>[t[11]||(t[11]=k(" 复制配置 ",-1))]),_:1}),a(B,{variant:"outline",theme:"danger",onClick:se},{icon:i(()=>[a(u,{name:"delete"})]),default:i(()=>[t[12]||(t[12]=k(" 删除配置 ",-1))]),_:1}),a(B,{theme:"primary",loading:p.value,onClick:te},{icon:i(()=>[a(u,{name:"setting"})]),default:i(()=>[t[13]||(t[13]=k(" 立即配置 ",-1))]),_:1},8,["loading"])])])]),_:1})}}}),Ue=O(Ie,[["__scopeId","data-v-6f6fd984"]]),Te={class:"points-alert"},Ne={class:"points-alert__row"},Oe={class:"points-alert__row"},Pe={class:"points-alert__row"},De={class:"points-alert__actions"},Ke=N({__name:"PointsAlertSection",setup(E){const f=K(),{alertSettings:g}=F(f),l=b(g.value.yellowThreshold),c=b(g.value.redThreshold),v=b(g.value.popupEnabled),w=b(!1);async function r(){if(l.value<=c.value){m.warning("黄线阈值应大于红线阈值");return}w.value=!0;try{await f.saveAlertSettings({yellowThreshold:l.value,redThreshold:c.value,popupEnabled:v.value}),m.success("保存成功")}finally{w.value=!1}}return(p,s)=>{const o=$("t-input-number"),_=$("t-switch"),C=$("t-button");return y(),T(P,{title:"积分预警",subtitle:"余额低于阈值时主动提醒,避免任务因积分不足中断",icon:"error-triangle"},{default:i(()=>[e("div",Te,[e("div",Ne,[s[3]||(s[3]=e("div",{class:"points-alert__label-group"},[e("span",{class:"points-alert__label"},"黄线阈值"),e("span",{class:"points-alert__desc"},"积分低于此值 → 托盘气泡通知 + 余额数字变橙色")],-1)),a(o,{modelValue:l.value,"onUpdate:modelValue":s[0]||(s[0]=V=>l.value=V),min:0,theme:"normal",style:{width:"120px"}},null,8,["modelValue"])]),e("div",Oe,[s[4]||(s[4]=e("div",{class:"points-alert__label-group"},[e("span",{class:"points-alert__label"},"红线阈值"),e("span",{class:"points-alert__desc"},"积分低于此值 → 强提醒弹窗 + 余额数字变红色")],-1)),a(o,{modelValue:c.value,"onUpdate:modelValue":s[1]||(s[1]=V=>c.value=V),min:0,theme:"normal",style:{width:"120px"}},null,8,["modelValue"])]),e("div",Pe,[s[5]||(s[5]=e("div",{class:"points-alert__label-group"},[e("span",{class:"points-alert__label"},"启用弹窗/通知提醒"),e("span",{class:"points-alert__desc"},"默认关闭,仅余额变色")],-1)),a(_,{modelValue:v.value,"onUpdate:modelValue":s[2]||(s[2]=V=>v.value=V)},null,8,["modelValue"])]),e("div",De,[a(C,{theme:"primary",loading:w.value,onClick:r},{default:i(()=>[...s[6]||(s[6]=[k("保存",-1)])]),_:1},8,["loading"])])])]),_:1})}}}),Me=O(Ke,[["__scopeId","data-v-86a67357"]]),H="1.0.0",Fe={async check(){const E=await q.config();return{hasUpdate:E.latestVersion!==H,latestVersion:E.latestVersion,downloadUrl:E.downloadUrl}}},ze={class:"update-section"},Re={key:0,class:"update-section__info"},Je={class:"update-section__actions"},Le=N({__name:"UpdateSection",setup(E){const{shell:f}=z(),g=`v${H}`,l=b(!1),c=b(null);async function v(){l.value=!0;try{c.value=await Fe.check(),c.value.hasUpdate?m.success(`发现新版本 ${c.value.latestVersion}`):m.success("当前已是最新版本")}finally{l.value=!1}}async function w(){var p;const r=(p=c.value)==null?void 0:p.downloadUrl;if(r)try{await f.openExternal(r)}catch(s){m.error(`打开下载链接失败:${s instanceof Error?s.message:String(s)}`)}}return(r,p)=>{const s=$("t-button");return y(),T(P,{title:"更新管理",subtitle:"版本检查与手动更新",icon:"upload"},{default:i(()=>{var o;return[e("div",ze,[e("div",{class:"update-section__row"},[p[0]||(p[0]=e("span",{class:"update-section__label"},"当前版本",-1)),e("span",{class:"update-section__version"},A(g))]),p[2]||(p[2]=e("p",{class:"update-section__desc"}," 应用启动时会自动检查新版本,如有更新请手动下载替换。 ",-1)),(o=c.value)!=null&&o.hasUpdate?(y(),U("div",Re,[e("span",null,"发现新版本:"+A(c.value.latestVersion),1),c.value.downloadUrl?(y(),T(s,{key:0,theme:"primary",variant:"text",size:"small",onClick:w},{default:i(()=>[...p[1]||(p[1]=[k(" 前往下载 ",-1)])]),_:1})):M("",!0)])):M("",!0),e("div",Je,[a(s,{theme:"primary",loading:l.value,onClick:v},{default:i(()=>[k(A(l.value?"检查中...":c.value?"待查更新":"检查更新"),1)]),_:1},8,["loading"])])])]}),_:1})}}}),Ye=O(Le,[["__scopeId","data-v-0313748f"]]),je={class:"self-check"},Ge={class:"self-check__actions"},qe={key:0,class:"self-check__results"},He={class:"self-check__item-header"},Qe={class:"self-check__item-name"},We={class:"self-check__item-message"},Xe=N({__name:"SelfCheckSection",setup(E){const{selfcheck:f}=z(),g=ie(),l=ce(),c=b(!1),v=b([]);async function w(){c.value=!0;try{await g.init(),await l.init().catch(()=>{});const o={activated:g.isActivated,packageCount:l.packageCount,balance:l.balance,apiKey:g.apiKey};v.value=await f.run(o);const _=v.value.filter(C=>C.status==="fail");_.length===0?m.success("自检完成,所有检查项通过"):m.warning(`自检完成,${_.length} 项检查未通过`)}finally{c.value=!1}}function r(o){return{pass:"通过",fail:"失败",warning:"警告"}[o]}function p(o){return{pass:"var(--td-success-color)",fail:"var(--td-error-color)",warning:"var(--td-warning-color)"}[o]}function s(o){return{pass:"#E8F8F0",fail:"#FDECEE",warning:"#FFF3E0"}[o]}return(o,_)=>{const C=$("t-icon"),V=$("t-button");return y(),T(P,{title:"环境自检",subtitle:"诊断服务连通性问题,自动修复常见配置错误",icon:"check-circle"},{default:i(()=>[e("div",je,[e("div",Ge,[a(V,{theme:"primary",loading:c.value,onClick:w},{icon:i(()=>[a(C,{name:"play-circle"})]),default:i(()=>[_[0]||(_[0]=k(" 一键自检 ",-1))]),_:1},8,["loading"])]),v.value.length>0?(y(),U("div",qe,[(y(!0),U(j,null,G(v.value,(I,D)=>(y(),U("div",{key:D,class:"self-check__item"},[e("div",He,[e("span",Qe,A(I.item),1),e("span",{class:"self-check__item-status",style:re({color:p(I.status),backgroundColor:s(I.status)})},A(r(I.status)),5)]),e("p",We,A(I.message),1)]))),128))])):M("",!0)])]),_:1})}}}),Ze=O(Xe,[["__scopeId","data-v-96452ede"]]),et={class:"settings-view"},tt=N({__name:"SettingsView",setup(E){return K(),(f,g)=>(y(),U("div",et,[a(me),a(Ue),a(Me),a(Ye),a(Ze)]))}}),ot=O(tt,[["__scopeId","data-v-6f0b652b"]]);export{ot as default};
@@ -0,0 +1 @@
1
+ .appearance-section[data-v-9675e52d]{display:flex;flex-direction:column;gap:var(--space-lg)}.appearance-section__row[data-v-9675e52d]{display:flex;align-items:center;justify-content:space-between}.appearance-section__label-group[data-v-9675e52d]{display:flex;flex-direction:column}.appearance-section__label[data-v-9675e52d]{font-size:var(--font-label);font-weight:500;color:var(--td-text-color-primary)}.appearance-section__desc[data-v-9675e52d]{font-size:var(--font-caption);color:var(--td-text-color-secondary);margin-top:2px}.client-config-section[data-v-6f6fd984]{display:flex;flex-direction:column;gap:var(--space-xl)}.client-config-section__sub-title[data-v-6f6fd984]{font-size:var(--font-label);font-weight:500;color:var(--td-text-color-primary);margin-bottom:var(--space-md)}.client-config-section__targets[data-v-6f6fd984]{display:flex;flex-direction:column;gap:var(--space-md)}.client-config-section__target[data-v-6f6fd984]{display:flex;align-items:center;gap:var(--space-md);padding:var(--space-sm) 0}.client-config-section__target-info[data-v-6f6fd984]{display:flex;flex-direction:column;flex:1}.client-config-section__target-name[data-v-6f6fd984]{font-size:var(--font-body);color:var(--td-text-color-primary)}.client-config-section__target-desc[data-v-6f6fd984]{font-size:var(--font-caption);color:var(--td-text-color-secondary);margin-top:2px}.client-config-section__config-row[data-v-6f6fd984]{display:flex;align-items:center;gap:var(--space-sm);margin-bottom:var(--space-md)}.client-config-section__config-label[data-v-6f6fd984]{font-size:var(--font-label);font-weight:500;color:var(--td-text-color-primary);width:70px;flex-shrink:0}.client-config-section__config-value[data-v-6f6fd984]{flex:1;font-size:var(--font-caption);color:var(--td-text-color-secondary);background:var(--td-bg-color-page);padding:6px 10px;border-radius:var(--radius-sm);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.client-config-section__backup-row[data-v-6f6fd984]{display:flex;align-items:center;justify-content:space-between;margin-top:var(--space-md)}.client-config-section__actions[data-v-6f6fd984]{display:flex;justify-content:flex-end;gap:var(--space-sm);padding-top:var(--space-md);border-top:1px solid var(--td-border-level-2-color)}.points-alert[data-v-86a67357]{display:flex;flex-direction:column;gap:var(--space-lg)}.points-alert__row[data-v-86a67357]{display:flex;align-items:center;justify-content:space-between}.points-alert__label-group[data-v-86a67357]{display:flex;flex-direction:column}.points-alert__label[data-v-86a67357]{font-size:var(--font-label);font-weight:500;color:var(--td-text-color-primary)}.points-alert__desc[data-v-86a67357]{font-size:var(--font-caption);color:var(--td-text-color-secondary);margin-top:2px}.points-alert__actions[data-v-86a67357]{display:flex;justify-content:flex-end}.update-section[data-v-0313748f]{display:flex;flex-direction:column;gap:var(--space-md)}.update-section__row[data-v-0313748f]{display:flex;align-items:center;gap:var(--space-md)}.update-section__label[data-v-0313748f]{font-size:var(--font-label);font-weight:500;color:var(--td-text-color-primary)}.update-section__version[data-v-0313748f]{font-size:var(--font-body);color:var(--td-brand-color);font-weight:600}.update-section__desc[data-v-0313748f]{font-size:var(--font-caption);color:var(--td-text-color-secondary);line-height:1.6}.update-section__info[data-v-0313748f]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-md);padding:var(--space-sm) var(--space-md);background:var(--td-brand-color-light);border-radius:var(--radius-sm);font-size:var(--font-caption);color:var(--td-brand-color)}.update-section__actions[data-v-0313748f]{display:flex;justify-content:flex-end}.self-check[data-v-96452ede]{display:flex;flex-direction:column;gap:var(--space-lg)}.self-check__actions[data-v-96452ede]{display:flex;justify-content:flex-end}.self-check__results[data-v-96452ede]{display:flex;flex-direction:column;gap:var(--space-sm)}.self-check__item[data-v-96452ede]{padding:var(--space-md);background:var(--td-bg-color-page);border-radius:var(--radius-sm)}.self-check__item-header[data-v-96452ede]{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-xs)}.self-check__item-name[data-v-96452ede]{font-size:var(--font-body);font-weight:500;color:var(--td-text-color-primary)}.self-check__item-status[data-v-96452ede]{font-size:var(--font-caption);font-weight:500;padding:2px 10px;border-radius:var(--radius-sm)}.self-check__item-message[data-v-96452ede]{font-size:var(--font-caption);color:var(--td-text-color-secondary)}.settings-view[data-v-6f0b652b]{display:flex;flex-direction:column;gap:var(--space-xl)}
@@ -0,0 +1 @@
1
+ import{d as s,o as n,b as r,n as d,t as u,c as o,_ as p}from"./index-C2wBeAgU.js";const g=s({__name:"StatusBadge",props:{type:{},text:{}},setup(a){const e=a,c={inactive:{bg:"#FDECEE",color:"#E34D59",defaultText:"未激活"},active:{bg:"#E8F8F0",color:"#00A870",defaultText:"已激活"},running:{bg:"#E8F8F0",color:"#00A870",defaultText:"运行中"},stopped:{bg:"#F3F3F3",color:"#666666",defaultText:"已停止"},unconfigured:{bg:"#F3F3F3",color:"#666666",defaultText:"未配置"},"not-detected":{bg:"#F3F3F3",color:"#999999",defaultText:"未检测到安装"},detected:{bg:"#E8F8F0",color:"#00A870",defaultText:"已检测到安装"}},t=o(()=>c[e.type]),l=o(()=>e.text||t.value.defaultText);return(F,f)=>(n(),r("span",{class:"status-badge",style:d({backgroundColor:t.value.bg,color:t.value.color})},u(l.value),5))}}),x=p(g,[["__scopeId","data-v-70176240"]]);export{x as S};
@@ -0,0 +1 @@
1
+ .status-badge[data-v-70176240]{display:inline-flex;align-items:center;padding:2px 10px;border-radius:var(--radius-sm);font-size:var(--font-caption);font-weight:500;white-space:nowrap;line-height:20px}