zen-gitsync 2.9.8 → 2.9.10
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.
- package/README.md +100 -148
- package/package.json +1 -1
- package/src/ui/public/assets/{index-C-ZzwQYX.css → index-CzUoE1WP.css} +1 -1
- package/src/ui/public/assets/index-GE6lIBHK.js +79 -0
- package/src/ui/public/index.html +2 -2
- package/src/ui/server/index.js +143 -5311
- package/src/ui/server/index_pro.js +5483 -0
- package/src/ui/server/middleware/requestLogger.js +37 -0
- package/src/ui/server/routes/branchStatus.js +168 -0
- package/src/ui/server/routes/config.js +586 -0
- package/src/ui/server/routes/exec.js +247 -0
- package/src/ui/server/routes/fileOpen.js +173 -0
- package/src/ui/server/routes/fs.js +443 -0
- package/src/ui/server/routes/git/diff.js +206 -0
- package/src/ui/server/routes/git/diffUtils.js +114 -0
- package/src/ui/server/routes/git/stash.js +481 -0
- package/src/ui/server/routes/git/tags.js +158 -0
- package/src/ui/server/routes/git.js +176 -0
- package/src/ui/server/routes/gitOps.js +974 -0
- package/src/ui/server/routes/npm.js +981 -0
- package/src/ui/server/routes/process.js +68 -0
- package/src/ui/server/routes/status.js +24 -0
- package/src/ui/server/routes/terminal.js +244 -0
- package/src/ui/server/socket/registerUiSocketHandlers.js +212 -0
- package/src/ui/server/utils/createSavePortToFile.js +32 -0
- package/src/ui/server/utils/startServerOnAvailablePort.js +87 -0
- package/src/ui/public/assets/index-DXmNo3gw.js +0 -79
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import fs from 'fs/promises';
|
|
5
|
+
import open from 'open';
|
|
6
|
+
|
|
7
|
+
export function registerConfigRoutes({
|
|
8
|
+
app,
|
|
9
|
+
configManager
|
|
10
|
+
}) {
|
|
11
|
+
// 保存最近访问的目录
|
|
12
|
+
app.post('/api/save_recent_directory', async (req, res) => {
|
|
13
|
+
try {
|
|
14
|
+
const { path } = req.body;
|
|
15
|
+
|
|
16
|
+
if (!path) {
|
|
17
|
+
return res.status(400).json({
|
|
18
|
+
success: false,
|
|
19
|
+
error: '目录路径不能为空'
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 保存到配置
|
|
24
|
+
await configManager.saveRecentDirectory(path);
|
|
25
|
+
|
|
26
|
+
res.json({
|
|
27
|
+
success: true
|
|
28
|
+
});
|
|
29
|
+
} catch (error) {
|
|
30
|
+
res.status(500).json({
|
|
31
|
+
success: false,
|
|
32
|
+
error: error.message
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// 获取配置
|
|
38
|
+
app.get('/api/config/getConfig', async (req, res) => {
|
|
39
|
+
try {
|
|
40
|
+
// console.log('获取配置中。。。')
|
|
41
|
+
const config = await configManager.loadConfig()
|
|
42
|
+
|
|
43
|
+
// 兼容旧数据:补齐自定义命令 id,避免前端编辑/删除/编排引用异常
|
|
44
|
+
if (Array.isArray(config.customCommands)) {
|
|
45
|
+
let changed = false
|
|
46
|
+
config.customCommands = config.customCommands.map((cmd) => {
|
|
47
|
+
if (cmd && typeof cmd === 'object' && !cmd.id) {
|
|
48
|
+
changed = true
|
|
49
|
+
return {
|
|
50
|
+
...cmd,
|
|
51
|
+
id: `cmd_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return cmd
|
|
55
|
+
})
|
|
56
|
+
if (changed) {
|
|
57
|
+
await configManager.saveConfig(config)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// console.log('获取配置成功')
|
|
62
|
+
res.json(config)
|
|
63
|
+
} catch (error) {
|
|
64
|
+
// console.log('获取配置失败')
|
|
65
|
+
res.status(500).json({ error: error.message })
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
// 保存默认提交信息
|
|
70
|
+
app.post('/api/config/saveDefaultMessage', express.json(), async (req, res) => {
|
|
71
|
+
try {
|
|
72
|
+
const { defaultCommitMessage } = req.body
|
|
73
|
+
|
|
74
|
+
if (!defaultCommitMessage) {
|
|
75
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const config = await configManager.loadConfig()
|
|
79
|
+
|
|
80
|
+
// 更新默认提交信息
|
|
81
|
+
config.defaultCommitMessage = defaultCommitMessage
|
|
82
|
+
await configManager.saveConfig(config)
|
|
83
|
+
|
|
84
|
+
res.json({ success: true })
|
|
85
|
+
} catch (error) {
|
|
86
|
+
res.status(500).json({ success: false, error: error.message })
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
// 保存所有配置
|
|
91
|
+
app.post('/api/config/saveAll', express.json(), async (req, res) => {
|
|
92
|
+
try {
|
|
93
|
+
const { config } = req.body
|
|
94
|
+
|
|
95
|
+
if (!config) {
|
|
96
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
await configManager.saveConfig(config)
|
|
100
|
+
|
|
101
|
+
res.json({ success: true })
|
|
102
|
+
} catch (error) {
|
|
103
|
+
res.status(500).json({ success: false, error: error.message })
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// 检查系统配置文件格式
|
|
108
|
+
app.get('/api/config/check-file-format', async (req, res) => {
|
|
109
|
+
try {
|
|
110
|
+
const configPath = path.join(os.homedir(), '.git-commit-tool.json');
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const data = await fs.readFile(configPath, 'utf-8');
|
|
114
|
+
try {
|
|
115
|
+
JSON.parse(data);
|
|
116
|
+
res.json({ success: true, isValidJson: true, exists: true });
|
|
117
|
+
} catch (parseError) {
|
|
118
|
+
res.json({
|
|
119
|
+
success: true,
|
|
120
|
+
isValidJson: false,
|
|
121
|
+
exists: true,
|
|
122
|
+
error: `JSON解析失败: ${parseError.message}`
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
} catch (fileError) {
|
|
126
|
+
if (fileError.code === 'ENOENT') {
|
|
127
|
+
res.json({ success: true, isValidJson: true, exists: false });
|
|
128
|
+
} else {
|
|
129
|
+
res.json({
|
|
130
|
+
success: true,
|
|
131
|
+
isValidJson: false,
|
|
132
|
+
exists: true,
|
|
133
|
+
error: `文件读取失败: ${fileError.message}`
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
res.status(500).json({ success: false, error: error.message });
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
// 使用系统默认程序打开配置文件 ~/.git-commit-tool.json
|
|
143
|
+
app.post('/api/config/open-file', async (req, res) => {
|
|
144
|
+
try {
|
|
145
|
+
const filePath = path.join(os.homedir(), '.git-commit-tool.json');
|
|
146
|
+
try {
|
|
147
|
+
// 检查文件是否存在,不存在也尝试让系统创建(可能会打开空文件)
|
|
148
|
+
await fs.access(filePath);
|
|
149
|
+
} catch (_) {
|
|
150
|
+
// 如果文件不存在,先创建一个最小结构,避免某些系统无法打开不存在的路径
|
|
151
|
+
try {
|
|
152
|
+
await fs.writeFile(filePath, '{}', 'utf-8');
|
|
153
|
+
} catch (e) {
|
|
154
|
+
// 创建失败不阻断打开尝试
|
|
155
|
+
console.warn('创建配置文件失败(可忽略):', e?.message || e);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
await open(filePath, { wait: false });
|
|
160
|
+
res.json({ success: true })
|
|
161
|
+
} catch (error) {
|
|
162
|
+
res.status(400).json({ success: false, error: `无法打开配置文件: ${error.message}` })
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
// 保存模板
|
|
167
|
+
app.post('/api/config/save-template', express.json(), async (req, res) => {
|
|
168
|
+
try {
|
|
169
|
+
const { template, type } = req.body
|
|
170
|
+
|
|
171
|
+
if (!template || !type) {
|
|
172
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const config = await configManager.loadConfig()
|
|
176
|
+
|
|
177
|
+
if (type === 'description') {
|
|
178
|
+
// 确保描述模板数组存在
|
|
179
|
+
if (!config.descriptionTemplates) {
|
|
180
|
+
config.descriptionTemplates = []
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// 检查是否已存在相同模板
|
|
184
|
+
if (!config.descriptionTemplates.includes(template)) {
|
|
185
|
+
config.descriptionTemplates.push(template)
|
|
186
|
+
await configManager.saveConfig(config)
|
|
187
|
+
}
|
|
188
|
+
} else if (type === 'scope') {
|
|
189
|
+
// 确保作用域模板数组存在
|
|
190
|
+
if (!config.scopeTemplates) {
|
|
191
|
+
config.scopeTemplates = []
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// 检查是否已存在相同模板
|
|
195
|
+
if (!config.scopeTemplates.includes(template)) {
|
|
196
|
+
config.scopeTemplates.push(template)
|
|
197
|
+
await configManager.saveConfig(config)
|
|
198
|
+
}
|
|
199
|
+
} else if (type === 'message') {
|
|
200
|
+
// 确保提交信息模板数组存在
|
|
201
|
+
if (!config.messageTemplates) {
|
|
202
|
+
config.messageTemplates = []
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// 检查是否已存在相同模板
|
|
206
|
+
if (!config.messageTemplates.includes(template)) {
|
|
207
|
+
config.messageTemplates.push(template)
|
|
208
|
+
await configManager.saveConfig(config)
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
return res.status(400).json({ success: false, error: '不支持的模板类型' })
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
res.json({ success: true })
|
|
215
|
+
} catch (error) {
|
|
216
|
+
res.status(500).json({ success: false, error: error.message })
|
|
217
|
+
}
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
// 删除模板
|
|
221
|
+
app.post('/api/config/delete-template', express.json(), async (req, res) => {
|
|
222
|
+
try {
|
|
223
|
+
const { template, type } = req.body
|
|
224
|
+
|
|
225
|
+
if (!template || !type) {
|
|
226
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const config = await configManager.loadConfig()
|
|
230
|
+
|
|
231
|
+
if (type === 'description') {
|
|
232
|
+
// 确保描述模板数组存在
|
|
233
|
+
if (config.descriptionTemplates) {
|
|
234
|
+
const index = config.descriptionTemplates.indexOf(template)
|
|
235
|
+
if (index !== -1) {
|
|
236
|
+
config.descriptionTemplates.splice(index, 1)
|
|
237
|
+
await configManager.saveConfig(config)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
} else if (type === 'scope') {
|
|
241
|
+
// 确保作用域模板数组存在
|
|
242
|
+
if (config.scopeTemplates) {
|
|
243
|
+
const index = config.scopeTemplates.indexOf(template)
|
|
244
|
+
if (index !== -1) {
|
|
245
|
+
config.scopeTemplates.splice(index, 1)
|
|
246
|
+
await configManager.saveConfig(config)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
} else if (type === 'message') {
|
|
250
|
+
// 确保提交信息模板数组存在
|
|
251
|
+
if (config.messageTemplates) {
|
|
252
|
+
const index = config.messageTemplates.indexOf(template)
|
|
253
|
+
if (index !== -1) {
|
|
254
|
+
config.messageTemplates.splice(index, 1)
|
|
255
|
+
await configManager.saveConfig(config)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
} else {
|
|
259
|
+
return res.status(400).json({ success: false, error: '不支持的模板类型' })
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
res.json({ success: true })
|
|
263
|
+
} catch (error) {
|
|
264
|
+
res.status(500).json({ success: false, error: error.message })
|
|
265
|
+
}
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
// 更新模板
|
|
269
|
+
app.post('/api/config/update-template', express.json(), async (req, res) => {
|
|
270
|
+
try {
|
|
271
|
+
const { oldTemplate, newTemplate, type } = req.body
|
|
272
|
+
|
|
273
|
+
if (!oldTemplate || !newTemplate || !type) {
|
|
274
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const config = await configManager.loadConfig()
|
|
278
|
+
|
|
279
|
+
if (type === 'description') {
|
|
280
|
+
// 确保描述模板数组存在
|
|
281
|
+
if (config.descriptionTemplates) {
|
|
282
|
+
const index = config.descriptionTemplates.indexOf(oldTemplate)
|
|
283
|
+
if (index !== -1) {
|
|
284
|
+
config.descriptionTemplates[index] = newTemplate
|
|
285
|
+
await configManager.saveConfig(config)
|
|
286
|
+
} else {
|
|
287
|
+
return res.status(404).json({ success: false, error: '未找到原模板' })
|
|
288
|
+
}
|
|
289
|
+
} else {
|
|
290
|
+
return res.status(404).json({ success: false, error: '模板列表不存在' })
|
|
291
|
+
}
|
|
292
|
+
} else if (type === 'scope') {
|
|
293
|
+
// 确保作用域模板数组存在
|
|
294
|
+
if (config.scopeTemplates) {
|
|
295
|
+
const index = config.scopeTemplates.indexOf(oldTemplate)
|
|
296
|
+
if (index !== -1) {
|
|
297
|
+
config.scopeTemplates[index] = newTemplate
|
|
298
|
+
await configManager.saveConfig(config)
|
|
299
|
+
} else {
|
|
300
|
+
return res.status(404).json({ success: false, error: '未找到原模板' })
|
|
301
|
+
}
|
|
302
|
+
} else {
|
|
303
|
+
return res.status(404).json({ success: false, error: '模板列表不存在' })
|
|
304
|
+
}
|
|
305
|
+
} else if (type === 'message') {
|
|
306
|
+
// 确保提交信息模板数组存在
|
|
307
|
+
if (config.messageTemplates) {
|
|
308
|
+
const index = config.messageTemplates.indexOf(oldTemplate)
|
|
309
|
+
if (index !== -1) {
|
|
310
|
+
config.messageTemplates[index] = newTemplate
|
|
311
|
+
await configManager.saveConfig(config)
|
|
312
|
+
} else {
|
|
313
|
+
return res.status(404).json({ success: false, error: '未找到原模板' })
|
|
314
|
+
}
|
|
315
|
+
} else {
|
|
316
|
+
return res.status(404).json({ success: false, error: '模板列表不存在' })
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
return res.status(400).json({ success: false, error: '不支持的模板类型' })
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
res.json({ success: true })
|
|
323
|
+
} catch (error) {
|
|
324
|
+
res.status(500).json({ success: false, error: error.message })
|
|
325
|
+
}
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
// 置顶模板
|
|
329
|
+
app.post('/api/config/pin-template', express.json(), async (req, res) => {
|
|
330
|
+
try {
|
|
331
|
+
const { template, type } = req.body
|
|
332
|
+
|
|
333
|
+
if (!template || !type) {
|
|
334
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const config = await configManager.loadConfig()
|
|
338
|
+
|
|
339
|
+
if (type === 'description') {
|
|
340
|
+
if (config.descriptionTemplates) {
|
|
341
|
+
// 删除原位置的模板
|
|
342
|
+
config.descriptionTemplates = config.descriptionTemplates.filter(t => t !== template)
|
|
343
|
+
// 添加到第一位
|
|
344
|
+
config.descriptionTemplates.unshift(template)
|
|
345
|
+
await configManager.saveConfig(config)
|
|
346
|
+
} else {
|
|
347
|
+
return res.status(404).json({ success: false, error: '模板列表不存在' })
|
|
348
|
+
}
|
|
349
|
+
} else if (type === 'scope') {
|
|
350
|
+
if (config.scopeTemplates) {
|
|
351
|
+
config.scopeTemplates = config.scopeTemplates.filter(t => t !== template)
|
|
352
|
+
config.scopeTemplates.unshift(template)
|
|
353
|
+
await configManager.saveConfig(config)
|
|
354
|
+
} else {
|
|
355
|
+
return res.status(404).json({ success: false, error: '模板列表不存在' })
|
|
356
|
+
}
|
|
357
|
+
} else if (type === 'message') {
|
|
358
|
+
if (config.messageTemplates) {
|
|
359
|
+
config.messageTemplates = config.messageTemplates.filter(t => t !== template)
|
|
360
|
+
config.messageTemplates.unshift(template)
|
|
361
|
+
await configManager.saveConfig(config)
|
|
362
|
+
} else {
|
|
363
|
+
return res.status(404).json({ success: false, error: '模板列表不存在' })
|
|
364
|
+
}
|
|
365
|
+
} else {
|
|
366
|
+
return res.status(400).json({ success: false, error: '不支持的模板类型' })
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
res.json({ success: true })
|
|
370
|
+
} catch (error) {
|
|
371
|
+
res.status(500).json({ success: false, error: error.message })
|
|
372
|
+
}
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
// 保存自定义命令
|
|
376
|
+
app.post('/api/config/save-custom-command', express.json(), async (req, res) => {
|
|
377
|
+
try {
|
|
378
|
+
const { command } = req.body
|
|
379
|
+
|
|
380
|
+
if (!command || !command.name || !command.command) {
|
|
381
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const config = await configManager.loadConfig()
|
|
385
|
+
|
|
386
|
+
// 确保自定义命令数组存在
|
|
387
|
+
if (!Array.isArray(config.customCommands)) {
|
|
388
|
+
config.customCommands = []
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// 生成唯一ID
|
|
392
|
+
const id = `cmd_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
|
|
393
|
+
const newCommand = {
|
|
394
|
+
id,
|
|
395
|
+
name: command.name,
|
|
396
|
+
description: command.description || '',
|
|
397
|
+
directory: command.directory || '',
|
|
398
|
+
command: command.command
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
config.customCommands.push(newCommand)
|
|
402
|
+
await configManager.saveConfig(config)
|
|
403
|
+
|
|
404
|
+
res.json({ success: true, command: newCommand })
|
|
405
|
+
} catch (error) {
|
|
406
|
+
res.status(500).json({ success: false, error: error.message })
|
|
407
|
+
}
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
// 删除自定义命令
|
|
411
|
+
app.post('/api/config/delete-custom-command', express.json(), async (req, res) => {
|
|
412
|
+
try {
|
|
413
|
+
const { id } = req.body
|
|
414
|
+
|
|
415
|
+
if (!id) {
|
|
416
|
+
return res.status(400).json({ success: false, error: '缺少命令ID参数' })
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const config = await configManager.loadConfig()
|
|
420
|
+
|
|
421
|
+
if (Array.isArray(config.customCommands)) {
|
|
422
|
+
const index = config.customCommands.findIndex(cmd => cmd.id === id)
|
|
423
|
+
if (index !== -1) {
|
|
424
|
+
config.customCommands.splice(index, 1)
|
|
425
|
+
await configManager.saveConfig(config)
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
res.json({ success: true })
|
|
430
|
+
} catch (error) {
|
|
431
|
+
res.status(500).json({ success: false, error: error.message })
|
|
432
|
+
}
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
// 更新自定义命令
|
|
436
|
+
app.post('/api/config/update-custom-command', express.json(), async (req, res) => {
|
|
437
|
+
try {
|
|
438
|
+
const { id, command } = req.body
|
|
439
|
+
|
|
440
|
+
if (!id || !command || !command.name || !command.command) {
|
|
441
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const config = await configManager.loadConfig()
|
|
445
|
+
|
|
446
|
+
if (Array.isArray(config.customCommands)) {
|
|
447
|
+
const index = config.customCommands.findIndex(cmd => cmd.id === id)
|
|
448
|
+
if (index !== -1) {
|
|
449
|
+
config.customCommands[index] = {
|
|
450
|
+
id,
|
|
451
|
+
name: command.name,
|
|
452
|
+
description: command.description || '',
|
|
453
|
+
directory: command.directory || '',
|
|
454
|
+
command: command.command
|
|
455
|
+
}
|
|
456
|
+
await configManager.saveConfig(config)
|
|
457
|
+
} else {
|
|
458
|
+
return res.status(404).json({ success: false, error: '未找到指定命令' })
|
|
459
|
+
}
|
|
460
|
+
} else {
|
|
461
|
+
return res.status(404).json({ success: false, error: '命令列表不存在' })
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
res.json({ success: true })
|
|
465
|
+
} catch (error) {
|
|
466
|
+
res.status(500).json({ success: false, error: error.message })
|
|
467
|
+
}
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
// 保存指令编排
|
|
471
|
+
app.post('/api/config/save-orchestration', express.json(), async (req, res) => {
|
|
472
|
+
try {
|
|
473
|
+
const { orchestration } = req.body
|
|
474
|
+
|
|
475
|
+
if (!orchestration || !orchestration.name || !Array.isArray(orchestration.steps)) {
|
|
476
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const config = await configManager.loadConfig()
|
|
480
|
+
|
|
481
|
+
// 确保编排数组存在
|
|
482
|
+
if (!Array.isArray(config.orchestrations)) {
|
|
483
|
+
config.orchestrations = []
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// 生成唯一ID
|
|
487
|
+
const id = `orch_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
|
|
488
|
+
const newOrchestration = {
|
|
489
|
+
id,
|
|
490
|
+
name: orchestration.name,
|
|
491
|
+
description: orchestration.description || '',
|
|
492
|
+
steps: orchestration.steps,
|
|
493
|
+
flowData: orchestration.flowData || null
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
config.orchestrations.push(newOrchestration)
|
|
497
|
+
await configManager.saveConfig(config)
|
|
498
|
+
|
|
499
|
+
res.json({ success: true, orchestration: newOrchestration })
|
|
500
|
+
} catch (error) {
|
|
501
|
+
res.status(500).json({ success: false, error: error.message })
|
|
502
|
+
}
|
|
503
|
+
})
|
|
504
|
+
|
|
505
|
+
// 删除指令编排
|
|
506
|
+
app.post('/api/config/delete-orchestration', express.json(), async (req, res) => {
|
|
507
|
+
try {
|
|
508
|
+
const { id } = req.body
|
|
509
|
+
|
|
510
|
+
if (!id) {
|
|
511
|
+
return res.status(400).json({ success: false, error: '缺少编排ID参数' })
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
const config = await configManager.loadConfig()
|
|
515
|
+
|
|
516
|
+
if (Array.isArray(config.orchestrations)) {
|
|
517
|
+
const index = config.orchestrations.findIndex(orch => orch.id === id)
|
|
518
|
+
if (index !== -1) {
|
|
519
|
+
config.orchestrations.splice(index, 1)
|
|
520
|
+
await configManager.saveConfig(config)
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
res.json({ success: true })
|
|
525
|
+
} catch (error) {
|
|
526
|
+
res.status(500).json({ success: false, error: error.message })
|
|
527
|
+
}
|
|
528
|
+
})
|
|
529
|
+
|
|
530
|
+
// 更新指令编排
|
|
531
|
+
app.post('/api/config/update-orchestration', express.json(), async (req, res) => {
|
|
532
|
+
try {
|
|
533
|
+
const { id, orchestration } = req.body
|
|
534
|
+
|
|
535
|
+
if (!id || !orchestration || !orchestration.name || !Array.isArray(orchestration.steps)) {
|
|
536
|
+
return res.status(400).json({ success: false, error: '缺少必要参数' })
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const config = await configManager.loadConfig()
|
|
540
|
+
|
|
541
|
+
if (Array.isArray(config.orchestrations)) {
|
|
542
|
+
const index = config.orchestrations.findIndex(orch => orch.id === id)
|
|
543
|
+
if (index !== -1) {
|
|
544
|
+
config.orchestrations[index] = {
|
|
545
|
+
id,
|
|
546
|
+
name: orchestration.name,
|
|
547
|
+
description: orchestration.description || '',
|
|
548
|
+
steps: orchestration.steps,
|
|
549
|
+
flowData: orchestration.flowData || null
|
|
550
|
+
}
|
|
551
|
+
await configManager.saveConfig(config)
|
|
552
|
+
} else {
|
|
553
|
+
return res.status(404).json({ success: false, error: '未找到指定编排' })
|
|
554
|
+
}
|
|
555
|
+
} else {
|
|
556
|
+
return res.status(404).json({ success: false, error: '编排列表不存在' })
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
res.json({ success: true })
|
|
560
|
+
} catch (error) {
|
|
561
|
+
res.status(500).json({ success: false, error: error.message })
|
|
562
|
+
}
|
|
563
|
+
})
|
|
564
|
+
|
|
565
|
+
// 保存项目启动项
|
|
566
|
+
app.post('/api/config/save-startup-items', express.json(), async (req, res) => {
|
|
567
|
+
try {
|
|
568
|
+
const { startupItems, startupAutoRun } = req.body
|
|
569
|
+
|
|
570
|
+
if (!Array.isArray(startupItems)) {
|
|
571
|
+
return res.status(400).json({ success: false, error: '启动项必须是数组' })
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const config = await configManager.loadConfig()
|
|
575
|
+
config.startupItems = startupItems
|
|
576
|
+
if (typeof startupAutoRun === 'boolean') {
|
|
577
|
+
config.startupAutoRun = startupAutoRun
|
|
578
|
+
}
|
|
579
|
+
await configManager.saveConfig(config)
|
|
580
|
+
|
|
581
|
+
res.json({ success: true })
|
|
582
|
+
} catch (error) {
|
|
583
|
+
res.status(500).json({ success: false, error: error.message })
|
|
584
|
+
}
|
|
585
|
+
})
|
|
586
|
+
}
|