@@ -15,13 +15,74 @@ export default {
1515 startup: {
1616 loading: false ,
1717 type : () => {
18- return ( this .status . server && this . status . server . enabled ) ? ' primary' : ' default'
18+ return this .mainSwitchStatus ? ' primary' : ' default'
1919 },
20- doClick : () => {
21- if (this .status .server .enabled ) {
22- this .apiCall (this .startup , this .$api .shutdown )
23- } else {
24- this .apiCall (this .startup , this .$api .startup )
20+ doClick: async () => {
21+ const targetStatus = ! this .mainSwitchStatus
22+ this .startup .loading = true
23+ const errors = []
24+
25+ try {
26+ // 定义基础服务顺序,确保开关顺序稳定
27+ const baseServices = [' server' , ' proxy' ]
28+ // 收集所有实际可用的插件服务
29+ const pluginServices = []
30+ for (const key in this .switchBtns ) {
31+ if (key !== ' server' && key !== ' proxy' ) {
32+ pluginServices .push (key)
33+ }
34+ }
35+ // 合并服务列表:基础服务在前,插件服务在后
36+ const serviceOrder = [... baseServices, ... pluginServices]
37+
38+ if (targetStatus) {
39+ // 开启顺序:server → proxy → 可用插件
40+ for (const key of serviceOrder) {
41+ try {
42+ if (key === ' server' ) {
43+ await this .apiCall (this .server , this .$api .server .start )
44+ } else {
45+ // 只有当按钮实际存在时才调用
46+ if (this .switchBtns [key]) {
47+ await this .apiCall (this .switchBtns [key], this .switchBtns [key].apiTarget .start )
48+ }
49+ }
50+ } catch (err) {
51+ errors .push (` ${ this .switchBtns [key]? .label || key} 开启失败` )
52+ break // 开启失败,停止后续操作
53+ }
54+ }
55+ } else {
56+ // 关闭顺序:可用插件 → proxy → server(反转服务列表)
57+ const reverseOrder = [...serviceOrder].reverse()
58+ for (const key of reverseOrder) {
59+ try {
60+ if (key === 'server') {
61+ await this.apiCall(this.server, this.$api.server.close)
62+ } else {
63+ // 只有当按钮实际存在时才调用
64+ if (this.switchBtns[key]) {
65+ await this.apiCall(this.switchBtns[key], this.switchBtns[key].apiTarget.close)
66+ }
67+ }
68+ } catch (err) {
69+ errors.push(` ${this .switchBtns [key]? .label || key} 关闭失败` )
70+ // 关闭失败,继续尝试关闭后续服务
71+ }
72+ }
73+ }
74+
75+ // 显示错误提示
76+ if (errors.length > 0) {
77+ this.$message.error(` 操作失败:${errors .join (' ,' )}` )
78+ } else {
79+ this.$message.success(targetStatus ? '所有服务已开启' : '所有服务已关闭')
80+ }
81+ } catch (err) {
82+ console.error('大按钮操作失败:', err)
83+ this.$message.error(` 操作失败:${err .message || ' 未知错误' }` )
84+ } finally {
85+ this.startup.loading = false
2586 }
2687 },
2788 },
@@ -55,6 +116,24 @@ export default {
55116 const today = new Date().toISOString().split('T')[0] // YYYY-MM-DD
56117 return ` https: // img.shields.io/github/stars/docmirror/dev-sidecar?logo=github&cacheSeconds=86400&t=${today}`
57118 },
119+ mainSwitchStatus () {
120+ if (! this .switchBtns )
121+ return false
122+ // 遍历所有实际可用的子开关,只有当所有可用子开关都开启时,主开关才开启
123+ try {
124+ for (const key in this .switchBtns ) {
125+ // 跳过服务器和代理服务以外的插件按钮?不,应该考虑所有实际可用的按钮
126+ // 只检查 switchBtns 中实际存在的按钮
127+ if (! this .switchBtns [key]? .status ? .()) {
128+ return false
129+ }
130+ }
131+ return true
132+ } catch (err) {
133+ console .error (' 计算主开关状态失败:' , err)
134+ return false
135+ }
136+ },
58137 },
59138 async created () {
60139 await this .doCheckRootCa ()
@@ -191,8 +270,14 @@ export default {
191270 key,
192271 label,
193272 tip,
273+ apiTarget, // 添加 apiTarget 属性,用于大按钮操作
194274 status : () => {
195- return statusParent[key].enabled
275+ try {
276+ return statusParent[key].enabled
277+ } catch (err) {
278+ console .error (` 获取 ${ key} 状态失败:` , err)
279+ return false
280+ }
196281 },
197282 doClick : (checked ) => {
198283 this .onSwitchClick (this .switchBtns [key], apiTarget .start , apiTarget .close , checked)
@@ -320,7 +405,7 @@ export default {
320405 < img v- if = " !startup.loading && status.server.enabled" width= " 50" src= " /logo/logo-fff.svg" >
321406 < / a- button>
322407 < div class = " mt10" >
323- {{ status.server.enabled ? '已开启' : '已关闭' }}
408+ {{ mainSwitchStatus ? ' 已开启' : ' 已关闭' }}
324409 < / div>
325410 < / div>
326411 < / div>
0 commit comments