koishi-plugin-media-luna 0.0.1

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 (437) hide show
  1. package/client/README.md +558 -0
  2. package/client/api.ts +256 -0
  3. package/client/components/ChannelConfigDialog.vue +1113 -0
  4. package/client/components/ChannelsView.vue +698 -0
  5. package/client/components/ConfigRenderer.vue +164 -0
  6. package/client/components/EmptyState.vue +87 -0
  7. package/client/components/GenerateView.vue +778 -0
  8. package/client/components/HistoryGallery.vue +590 -0
  9. package/client/components/ImageLightbox.vue +510 -0
  10. package/client/components/ImageUpload.vue +298 -0
  11. package/client/components/JsonEditor.vue +68 -0
  12. package/client/components/LoadingState.vue +73 -0
  13. package/client/components/PresetsView.vue +800 -0
  14. package/client/components/ScrollContainer.vue +45 -0
  15. package/client/components/SettingsView.vue +231 -0
  16. package/client/components/StatusBadge.vue +55 -0
  17. package/client/components/TagFilter.vue +139 -0
  18. package/client/components/TagInput.vue +63 -0
  19. package/client/components/TasksView.vue +1074 -0
  20. package/client/components/ViewModeSwitch.vue +78 -0
  21. package/client/components/settings/CachePanel.vue +142 -0
  22. package/client/components/settings/MiddlewaresPanel.vue +480 -0
  23. package/client/components/settings/PluginsPanel.vue +493 -0
  24. package/client/index.ts +13 -0
  25. package/client/pages/index.vue +177 -0
  26. package/client/styles/shared.css +258 -0
  27. package/client/types.ts +158 -0
  28. package/client/utils/format.ts +72 -0
  29. package/dist/index.js +1 -0
  30. package/dist/style.css +1 -0
  31. package/lib/api/README.md +643 -0
  32. package/lib/api/cache-api.d.ts +6 -0
  33. package/lib/api/cache-api.d.ts.map +1 -0
  34. package/lib/api/cache-api.js +147 -0
  35. package/lib/api/cache-api.js.map +1 -0
  36. package/lib/api/channel-api.d.ts +6 -0
  37. package/lib/api/channel-api.d.ts.map +1 -0
  38. package/lib/api/channel-api.js +148 -0
  39. package/lib/api/channel-api.js.map +1 -0
  40. package/lib/api/connector-api.d.ts +6 -0
  41. package/lib/api/connector-api.d.ts.map +1 -0
  42. package/lib/api/connector-api.js +63 -0
  43. package/lib/api/connector-api.js.map +1 -0
  44. package/lib/api/generate-api.d.ts +6 -0
  45. package/lib/api/generate-api.d.ts.map +1 -0
  46. package/lib/api/generate-api.js +123 -0
  47. package/lib/api/generate-api.js.map +1 -0
  48. package/lib/api/index.d.ts +15 -0
  49. package/lib/api/index.d.ts.map +1 -0
  50. package/lib/api/index.js +34 -0
  51. package/lib/api/index.js.map +1 -0
  52. package/lib/api/middleware-api.d.ts +6 -0
  53. package/lib/api/middleware-api.d.ts.map +1 -0
  54. package/lib/api/middleware-api.js +212 -0
  55. package/lib/api/middleware-api.js.map +1 -0
  56. package/lib/api/plugin-api.d.ts +6 -0
  57. package/lib/api/plugin-api.d.ts.map +1 -0
  58. package/lib/api/plugin-api.js +78 -0
  59. package/lib/api/plugin-api.js.map +1 -0
  60. package/lib/api/preset-api.d.ts +6 -0
  61. package/lib/api/preset-api.d.ts.map +1 -0
  62. package/lib/api/preset-api.js +256 -0
  63. package/lib/api/preset-api.js.map +1 -0
  64. package/lib/api/settings-api.d.ts +6 -0
  65. package/lib/api/settings-api.d.ts.map +1 -0
  66. package/lib/api/settings-api.js +118 -0
  67. package/lib/api/settings-api.js.map +1 -0
  68. package/lib/api/task-api.d.ts +6 -0
  69. package/lib/api/task-api.d.ts.map +1 -0
  70. package/lib/api/task-api.js +148 -0
  71. package/lib/api/task-api.js.map +1 -0
  72. package/lib/config.d.ts +6 -0
  73. package/lib/config.d.ts.map +1 -0
  74. package/lib/config.js +8 -0
  75. package/lib/config.js.map +1 -0
  76. package/lib/connectors/builtin/chat-api.d.ts +9 -0
  77. package/lib/connectors/builtin/chat-api.d.ts.map +1 -0
  78. package/lib/connectors/builtin/chat-api.js +351 -0
  79. package/lib/connectors/builtin/chat-api.js.map +1 -0
  80. package/lib/connectors/builtin/dalle.d.ts +6 -0
  81. package/lib/connectors/builtin/dalle.d.ts.map +1 -0
  82. package/lib/connectors/builtin/dalle.js +109 -0
  83. package/lib/connectors/builtin/dalle.js.map +1 -0
  84. package/lib/connectors/builtin/flux.d.ts +7 -0
  85. package/lib/connectors/builtin/flux.d.ts.map +1 -0
  86. package/lib/connectors/builtin/flux.js +199 -0
  87. package/lib/connectors/builtin/flux.js.map +1 -0
  88. package/lib/connectors/builtin/index.d.ts +5 -0
  89. package/lib/connectors/builtin/index.d.ts.map +1 -0
  90. package/lib/connectors/builtin/index.js +6 -0
  91. package/lib/connectors/builtin/index.js.map +1 -0
  92. package/lib/connectors/builtin/sd-webui.d.ts +7 -0
  93. package/lib/connectors/builtin/sd-webui.d.ts.map +1 -0
  94. package/lib/connectors/builtin/sd-webui.js +157 -0
  95. package/lib/connectors/builtin/sd-webui.js.map +1 -0
  96. package/lib/connectors/connector-registry.d.ts +36 -0
  97. package/lib/connectors/connector-registry.d.ts.map +1 -0
  98. package/lib/connectors/connector-registry.js +66 -0
  99. package/lib/connectors/connector-registry.js.map +1 -0
  100. package/lib/connectors/index.d.ts +3 -0
  101. package/lib/connectors/index.d.ts.map +1 -0
  102. package/lib/connectors/index.js +4 -0
  103. package/lib/connectors/index.js.map +1 -0
  104. package/lib/core/api/api-utils.d.ts +46 -0
  105. package/lib/core/api/api-utils.d.ts.map +1 -0
  106. package/lib/core/api/api-utils.js +78 -0
  107. package/lib/core/api/api-utils.js.map +1 -0
  108. package/lib/core/api/cache-api.d.ts +6 -0
  109. package/lib/core/api/cache-api.d.ts.map +1 -0
  110. package/lib/core/api/cache-api.js +147 -0
  111. package/lib/core/api/cache-api.js.map +1 -0
  112. package/lib/core/api/channel-api.d.ts +6 -0
  113. package/lib/core/api/channel-api.d.ts.map +1 -0
  114. package/lib/core/api/channel-api.js +146 -0
  115. package/lib/core/api/channel-api.js.map +1 -0
  116. package/lib/core/api/connector-api.d.ts +6 -0
  117. package/lib/core/api/connector-api.d.ts.map +1 -0
  118. package/lib/core/api/connector-api.js +63 -0
  119. package/lib/core/api/connector-api.js.map +1 -0
  120. package/lib/core/api/generate-api.d.ts +6 -0
  121. package/lib/core/api/generate-api.d.ts.map +1 -0
  122. package/lib/core/api/generate-api.js +124 -0
  123. package/lib/core/api/generate-api.js.map +1 -0
  124. package/lib/core/api/index.d.ts +16 -0
  125. package/lib/core/api/index.d.ts.map +1 -0
  126. package/lib/core/api/index.js +38 -0
  127. package/lib/core/api/index.js.map +1 -0
  128. package/lib/core/api/middleware-api.d.ts +6 -0
  129. package/lib/core/api/middleware-api.d.ts.map +1 -0
  130. package/lib/core/api/middleware-api.js +196 -0
  131. package/lib/core/api/middleware-api.js.map +1 -0
  132. package/lib/core/api/plugin-api.d.ts +6 -0
  133. package/lib/core/api/plugin-api.d.ts.map +1 -0
  134. package/lib/core/api/plugin-api.js +78 -0
  135. package/lib/core/api/plugin-api.js.map +1 -0
  136. package/lib/core/api/preset-api.d.ts +6 -0
  137. package/lib/core/api/preset-api.d.ts.map +1 -0
  138. package/lib/core/api/preset-api.js +272 -0
  139. package/lib/core/api/preset-api.js.map +1 -0
  140. package/lib/core/api/settings-api.d.ts +6 -0
  141. package/lib/core/api/settings-api.d.ts.map +1 -0
  142. package/lib/core/api/settings-api.js +118 -0
  143. package/lib/core/api/settings-api.js.map +1 -0
  144. package/lib/core/api/task-api.d.ts +6 -0
  145. package/lib/core/api/task-api.d.ts.map +1 -0
  146. package/lib/core/api/task-api.js +281 -0
  147. package/lib/core/api/task-api.js.map +1 -0
  148. package/lib/core/channel.service.d.ts +44 -0
  149. package/lib/core/channel.service.d.ts.map +1 -0
  150. package/lib/core/channel.service.js +146 -0
  151. package/lib/core/channel.service.js.map +1 -0
  152. package/lib/core/config/config.service.d.ts +89 -0
  153. package/lib/core/config/config.service.d.ts.map +1 -0
  154. package/lib/core/config/config.service.js +216 -0
  155. package/lib/core/config/config.service.js.map +1 -0
  156. package/lib/core/config/index.d.ts +3 -0
  157. package/lib/core/config/index.d.ts.map +1 -0
  158. package/lib/core/config/index.js +3 -0
  159. package/lib/core/config/index.js.map +1 -0
  160. package/lib/core/error.d.ts +73 -0
  161. package/lib/core/error.d.ts.map +1 -0
  162. package/lib/core/error.js +137 -0
  163. package/lib/core/error.js.map +1 -0
  164. package/lib/core/index.d.ts +12 -0
  165. package/lib/core/index.d.ts.map +1 -0
  166. package/lib/core/index.js +23 -0
  167. package/lib/core/index.js.map +1 -0
  168. package/lib/core/logger.d.ts +18 -0
  169. package/lib/core/logger.d.ts.map +1 -0
  170. package/lib/core/logger.js +39 -0
  171. package/lib/core/logger.js.map +1 -0
  172. package/lib/core/medialuna.service.d.ts +168 -0
  173. package/lib/core/medialuna.service.d.ts.map +1 -0
  174. package/lib/core/medialuna.service.js +423 -0
  175. package/lib/core/medialuna.service.js.map +1 -0
  176. package/lib/core/pipeline/dependency-graph.d.ts +43 -0
  177. package/lib/core/pipeline/dependency-graph.d.ts.map +1 -0
  178. package/lib/core/pipeline/dependency-graph.js +223 -0
  179. package/lib/core/pipeline/dependency-graph.js.map +1 -0
  180. package/lib/core/pipeline/generation-pipeline.d.ts +40 -0
  181. package/lib/core/pipeline/generation-pipeline.d.ts.map +1 -0
  182. package/lib/core/pipeline/generation-pipeline.js +216 -0
  183. package/lib/core/pipeline/generation-pipeline.js.map +1 -0
  184. package/lib/core/pipeline/index.d.ts +4 -0
  185. package/lib/core/pipeline/index.d.ts.map +1 -0
  186. package/lib/core/pipeline/index.js +5 -0
  187. package/lib/core/pipeline/index.js.map +1 -0
  188. package/lib/core/pipeline/middleware-registry.d.ts +33 -0
  189. package/lib/core/pipeline/middleware-registry.d.ts.map +1 -0
  190. package/lib/core/pipeline/middleware-registry.js +78 -0
  191. package/lib/core/pipeline/middleware-registry.js.map +1 -0
  192. package/lib/core/plugin-loader.d.ts +77 -0
  193. package/lib/core/plugin-loader.d.ts.map +1 -0
  194. package/lib/core/plugin-loader.js +300 -0
  195. package/lib/core/plugin-loader.js.map +1 -0
  196. package/lib/core/registry/connector.registry.d.ts +36 -0
  197. package/lib/core/registry/connector.registry.d.ts.map +1 -0
  198. package/lib/core/registry/connector.registry.js +65 -0
  199. package/lib/core/registry/connector.registry.js.map +1 -0
  200. package/lib/core/registry/index.d.ts +3 -0
  201. package/lib/core/registry/index.d.ts.map +1 -0
  202. package/lib/core/registry/index.js +4 -0
  203. package/lib/core/registry/index.js.map +1 -0
  204. package/lib/core/registry/service.registry.d.ts +27 -0
  205. package/lib/core/registry/service.registry.d.ts.map +1 -0
  206. package/lib/core/registry/service.registry.js +54 -0
  207. package/lib/core/registry/service.registry.js.map +1 -0
  208. package/lib/core/request.service.d.ts +83 -0
  209. package/lib/core/request.service.d.ts.map +1 -0
  210. package/lib/core/request.service.js +237 -0
  211. package/lib/core/request.service.js.map +1 -0
  212. package/lib/core/types.d.ts +270 -0
  213. package/lib/core/types.d.ts.map +1 -0
  214. package/lib/core/types.js +17 -0
  215. package/lib/core/types.js.map +1 -0
  216. package/lib/database.d.ts +6 -0
  217. package/lib/database.d.ts.map +1 -0
  218. package/lib/database.js +89 -0
  219. package/lib/database.js.map +1 -0
  220. package/lib/index.d.ts +13 -0
  221. package/lib/index.d.ts.map +1 -0
  222. package/lib/index.js +54 -0
  223. package/lib/index.js.map +1 -0
  224. package/lib/middlewares/builtin/billing.d.ts +45 -0
  225. package/lib/middlewares/builtin/billing.d.ts.map +1 -0
  226. package/lib/middlewares/builtin/billing.js +362 -0
  227. package/lib/middlewares/builtin/billing.js.map +1 -0
  228. package/lib/middlewares/builtin/index.d.ts +6 -0
  229. package/lib/middlewares/builtin/index.d.ts.map +1 -0
  230. package/lib/middlewares/builtin/index.js +7 -0
  231. package/lib/middlewares/builtin/index.js.map +1 -0
  232. package/lib/middlewares/builtin/preset.d.ts +14 -0
  233. package/lib/middlewares/builtin/preset.d.ts.map +1 -0
  234. package/lib/middlewares/builtin/preset.js +156 -0
  235. package/lib/middlewares/builtin/preset.js.map +1 -0
  236. package/lib/middlewares/builtin/remote-preset-sync.d.ts +8 -0
  237. package/lib/middlewares/builtin/remote-preset-sync.d.ts.map +1 -0
  238. package/lib/middlewares/builtin/remote-preset-sync.js +32 -0
  239. package/lib/middlewares/builtin/remote-preset-sync.js.map +1 -0
  240. package/lib/middlewares/builtin/request.d.ts +10 -0
  241. package/lib/middlewares/builtin/request.d.ts.map +1 -0
  242. package/lib/middlewares/builtin/request.js +50 -0
  243. package/lib/middlewares/builtin/request.js.map +1 -0
  244. package/lib/middlewares/builtin/storage.d.ts +64 -0
  245. package/lib/middlewares/builtin/storage.d.ts.map +1 -0
  246. package/lib/middlewares/builtin/storage.js +715 -0
  247. package/lib/middlewares/builtin/storage.js.map +1 -0
  248. package/lib/middlewares/builtin/task-recorder.d.ts +20 -0
  249. package/lib/middlewares/builtin/task-recorder.d.ts.map +1 -0
  250. package/lib/middlewares/builtin/task-recorder.js +138 -0
  251. package/lib/middlewares/builtin/task-recorder.js.map +1 -0
  252. package/lib/middlewares/index.d.ts +2 -0
  253. package/lib/middlewares/index.d.ts.map +1 -0
  254. package/lib/middlewares/index.js +3 -0
  255. package/lib/middlewares/index.js.map +1 -0
  256. package/lib/pipeline/dependency-graph.d.ts +43 -0
  257. package/lib/pipeline/dependency-graph.d.ts.map +1 -0
  258. package/lib/pipeline/dependency-graph.js +240 -0
  259. package/lib/pipeline/dependency-graph.js.map +1 -0
  260. package/lib/pipeline/generation-pipeline.d.ts +38 -0
  261. package/lib/pipeline/generation-pipeline.d.ts.map +1 -0
  262. package/lib/pipeline/generation-pipeline.js +211 -0
  263. package/lib/pipeline/generation-pipeline.js.map +1 -0
  264. package/lib/pipeline/index.d.ts +4 -0
  265. package/lib/pipeline/index.d.ts.map +1 -0
  266. package/lib/pipeline/index.js +5 -0
  267. package/lib/pipeline/index.js.map +1 -0
  268. package/lib/pipeline/middleware-registry.d.ts +36 -0
  269. package/lib/pipeline/middleware-registry.d.ts.map +1 -0
  270. package/lib/pipeline/middleware-registry.js +83 -0
  271. package/lib/pipeline/middleware-registry.js.map +1 -0
  272. package/lib/plugins/billing/config.d.ts +19 -0
  273. package/lib/plugins/billing/config.d.ts.map +1 -0
  274. package/lib/plugins/billing/config.js +98 -0
  275. package/lib/plugins/billing/config.js.map +1 -0
  276. package/lib/plugins/billing/index.d.ts +4 -0
  277. package/lib/plugins/billing/index.d.ts.map +1 -0
  278. package/lib/plugins/billing/index.js +20 -0
  279. package/lib/plugins/billing/index.js.map +1 -0
  280. package/lib/plugins/billing/middleware.d.ts +12 -0
  281. package/lib/plugins/billing/middleware.d.ts.map +1 -0
  282. package/lib/plugins/billing/middleware.js +233 -0
  283. package/lib/plugins/billing/middleware.js.map +1 -0
  284. package/lib/plugins/cache/config.d.ts +44 -0
  285. package/lib/plugins/cache/config.d.ts.map +1 -0
  286. package/lib/plugins/cache/config.js +187 -0
  287. package/lib/plugins/cache/config.js.map +1 -0
  288. package/lib/plugins/cache/index.d.ts +6 -0
  289. package/lib/plugins/cache/index.d.ts.map +1 -0
  290. package/lib/plugins/cache/index.js +87 -0
  291. package/lib/plugins/cache/index.js.map +1 -0
  292. package/lib/plugins/cache/middleware.d.ts +12 -0
  293. package/lib/plugins/cache/middleware.d.ts.map +1 -0
  294. package/lib/plugins/cache/middleware.js +194 -0
  295. package/lib/plugins/cache/middleware.js.map +1 -0
  296. package/lib/plugins/cache/service.d.ts +106 -0
  297. package/lib/plugins/cache/service.d.ts.map +1 -0
  298. package/lib/plugins/cache/service.js +467 -0
  299. package/lib/plugins/cache/service.js.map +1 -0
  300. package/lib/plugins/cache/utils/index.d.ts +4 -0
  301. package/lib/plugins/cache/utils/index.d.ts.map +1 -0
  302. package/lib/plugins/cache/utils/index.js +5 -0
  303. package/lib/plugins/cache/utils/index.js.map +1 -0
  304. package/lib/plugins/cache/utils/mime.d.ts +9 -0
  305. package/lib/plugins/cache/utils/mime.d.ts.map +1 -0
  306. package/lib/plugins/cache/utils/mime.js +65 -0
  307. package/lib/plugins/cache/utils/mime.js.map +1 -0
  308. package/lib/plugins/cache/utils/s3.d.ts +19 -0
  309. package/lib/plugins/cache/utils/s3.d.ts.map +1 -0
  310. package/lib/plugins/cache/utils/s3.js +147 -0
  311. package/lib/plugins/cache/utils/s3.js.map +1 -0
  312. package/lib/plugins/cache/utils/webdav.d.ts +16 -0
  313. package/lib/plugins/cache/utils/webdav.d.ts.map +1 -0
  314. package/lib/plugins/cache/utils/webdav.js +69 -0
  315. package/lib/plugins/cache/utils/webdav.js.map +1 -0
  316. package/lib/plugins/connector-chat-api/index.d.ts +7 -0
  317. package/lib/plugins/connector-chat-api/index.d.ts.map +1 -0
  318. package/lib/plugins/connector-chat-api/index.js +400 -0
  319. package/lib/plugins/connector-chat-api/index.js.map +1 -0
  320. package/lib/plugins/connector-dalle/index.d.ts +7 -0
  321. package/lib/plugins/connector-dalle/index.d.ts.map +1 -0
  322. package/lib/plugins/connector-dalle/index.js +140 -0
  323. package/lib/plugins/connector-dalle/index.js.map +1 -0
  324. package/lib/plugins/connector-flux/index.d.ts +7 -0
  325. package/lib/plugins/connector-flux/index.d.ts.map +1 -0
  326. package/lib/plugins/connector-flux/index.js +232 -0
  327. package/lib/plugins/connector-flux/index.js.map +1 -0
  328. package/lib/plugins/connector-sd-webui/index.d.ts +7 -0
  329. package/lib/plugins/connector-sd-webui/index.d.ts.map +1 -0
  330. package/lib/plugins/connector-sd-webui/index.js +171 -0
  331. package/lib/plugins/connector-sd-webui/index.js.map +1 -0
  332. package/lib/plugins/index.d.ts +22 -0
  333. package/lib/plugins/index.d.ts.map +1 -0
  334. package/lib/plugins/index.js +21 -0
  335. package/lib/plugins/index.js.map +1 -0
  336. package/lib/plugins/preset/config.d.ts +37 -0
  337. package/lib/plugins/preset/config.d.ts.map +1 -0
  338. package/lib/plugins/preset/config.js +74 -0
  339. package/lib/plugins/preset/config.js.map +1 -0
  340. package/lib/plugins/preset/index.d.ts +6 -0
  341. package/lib/plugins/preset/index.d.ts.map +1 -0
  342. package/lib/plugins/preset/index.js +58 -0
  343. package/lib/plugins/preset/index.js.map +1 -0
  344. package/lib/plugins/preset/middleware.d.ts +6 -0
  345. package/lib/plugins/preset/middleware.d.ts.map +1 -0
  346. package/lib/plugins/preset/middleware.js +126 -0
  347. package/lib/plugins/preset/middleware.js.map +1 -0
  348. package/lib/plugins/preset/remote-sync.service.d.ts +84 -0
  349. package/lib/plugins/preset/remote-sync.service.d.ts.map +1 -0
  350. package/lib/plugins/preset/remote-sync.service.js +342 -0
  351. package/lib/plugins/preset/remote-sync.service.js.map +1 -0
  352. package/lib/plugins/preset/service.d.ts +64 -0
  353. package/lib/plugins/preset/service.d.ts.map +1 -0
  354. package/lib/plugins/preset/service.js +196 -0
  355. package/lib/plugins/preset/service.js.map +1 -0
  356. package/lib/plugins/prompt-encoding/config.d.ts +25 -0
  357. package/lib/plugins/prompt-encoding/config.d.ts.map +1 -0
  358. package/lib/plugins/prompt-encoding/config.js +62 -0
  359. package/lib/plugins/prompt-encoding/config.js.map +1 -0
  360. package/lib/plugins/prompt-encoding/index.d.ts +5 -0
  361. package/lib/plugins/prompt-encoding/index.d.ts.map +1 -0
  362. package/lib/plugins/prompt-encoding/index.js +21 -0
  363. package/lib/plugins/prompt-encoding/index.js.map +1 -0
  364. package/lib/plugins/prompt-encoding/middleware.d.ts +6 -0
  365. package/lib/plugins/prompt-encoding/middleware.d.ts.map +1 -0
  366. package/lib/plugins/prompt-encoding/middleware.js +151 -0
  367. package/lib/plugins/prompt-encoding/middleware.js.map +1 -0
  368. package/lib/plugins/task/config.d.ts +15 -0
  369. package/lib/plugins/task/config.d.ts.map +1 -0
  370. package/lib/plugins/task/config.js +33 -0
  371. package/lib/plugins/task/config.js.map +1 -0
  372. package/lib/plugins/task/index.d.ts +5 -0
  373. package/lib/plugins/task/index.d.ts.map +1 -0
  374. package/lib/plugins/task/index.js +58 -0
  375. package/lib/plugins/task/index.js.map +1 -0
  376. package/lib/plugins/task/middleware.d.ts +14 -0
  377. package/lib/plugins/task/middleware.d.ts.map +1 -0
  378. package/lib/plugins/task/middleware.js +123 -0
  379. package/lib/plugins/task/middleware.js.map +1 -0
  380. package/lib/plugins/task/service.d.ts +94 -0
  381. package/lib/plugins/task/service.d.ts.map +1 -0
  382. package/lib/plugins/task/service.js +226 -0
  383. package/lib/plugins/task/service.js.map +1 -0
  384. package/lib/plugins/webui-auth/config.d.ts +12 -0
  385. package/lib/plugins/webui-auth/config.d.ts.map +1 -0
  386. package/lib/plugins/webui-auth/config.js +30 -0
  387. package/lib/plugins/webui-auth/config.js.map +1 -0
  388. package/lib/plugins/webui-auth/index.d.ts +5 -0
  389. package/lib/plugins/webui-auth/index.d.ts.map +1 -0
  390. package/lib/plugins/webui-auth/index.js +99 -0
  391. package/lib/plugins/webui-auth/index.js.map +1 -0
  392. package/lib/plugins/webui-auth/service.d.ts +42 -0
  393. package/lib/plugins/webui-auth/service.d.ts.map +1 -0
  394. package/lib/plugins/webui-auth/service.js +106 -0
  395. package/lib/plugins/webui-auth/service.js.map +1 -0
  396. package/lib/services/asset-cache.service.d.ts +133 -0
  397. package/lib/services/asset-cache.service.d.ts.map +1 -0
  398. package/lib/services/asset-cache.service.js +882 -0
  399. package/lib/services/asset-cache.service.js.map +1 -0
  400. package/lib/services/cache.service.d.ts +110 -0
  401. package/lib/services/cache.service.d.ts.map +1 -0
  402. package/lib/services/cache.service.js +333 -0
  403. package/lib/services/cache.service.js.map +1 -0
  404. package/lib/services/channel.service.d.ts +44 -0
  405. package/lib/services/channel.service.d.ts.map +1 -0
  406. package/lib/services/channel.service.js +154 -0
  407. package/lib/services/channel.service.js.map +1 -0
  408. package/lib/services/config.service.d.ts +73 -0
  409. package/lib/services/config.service.d.ts.map +1 -0
  410. package/lib/services/config.service.js +171 -0
  411. package/lib/services/config.service.js.map +1 -0
  412. package/lib/services/index.d.ts +8 -0
  413. package/lib/services/index.d.ts.map +1 -0
  414. package/lib/services/index.js +9 -0
  415. package/lib/services/index.js.map +1 -0
  416. package/lib/services/medialuna.service.d.ts +173 -0
  417. package/lib/services/medialuna.service.d.ts.map +1 -0
  418. package/lib/services/medialuna.service.js +455 -0
  419. package/lib/services/medialuna.service.js.map +1 -0
  420. package/lib/services/preset.service.d.ts +69 -0
  421. package/lib/services/preset.service.d.ts.map +1 -0
  422. package/lib/services/preset.service.js +202 -0
  423. package/lib/services/preset.service.js.map +1 -0
  424. package/lib/services/remote-preset.service.d.ts +97 -0
  425. package/lib/services/remote-preset.service.d.ts.map +1 -0
  426. package/lib/services/remote-preset.service.js +212 -0
  427. package/lib/services/remote-preset.service.js.map +1 -0
  428. package/lib/services/task.service.d.ts +57 -0
  429. package/lib/services/task.service.d.ts.map +1 -0
  430. package/lib/services/task.service.js +138 -0
  431. package/lib/services/task.service.js.map +1 -0
  432. package/lib/types/index.d.ts +357 -0
  433. package/lib/types/index.d.ts.map +1 -0
  434. package/lib/types/index.js +21 -0
  435. package/lib/types/index.js.map +1 -0
  436. package/package.json +66 -0
  437. package/readme.md +326 -0
@@ -0,0 +1,1113 @@
1
+ <template>
2
+ <el-dialog
3
+ v-model="visible"
4
+ :title="isEdit ? '编辑渠道' : '创建渠道'"
5
+ width="800px"
6
+ :close-on-click-modal="false"
7
+ class="channel-config-dialog"
8
+ @closed="handleClosed"
9
+ >
10
+ <div class="dialog-layout">
11
+ <!-- 左侧 Tab 导航 -->
12
+ <div class="tab-nav">
13
+ <div
14
+ v-for="tab in availableTabs"
15
+ :key="tab.id"
16
+ class="tab-item"
17
+ :class="{ active: activeTab === tab.id }"
18
+ @click="activeTab = tab.id"
19
+ >
20
+ <k-icon :name="tab.icon" />
21
+ <span>{{ tab.label }}</span>
22
+ <span v-if="tab.badge" class="tab-badge">{{ tab.badge }}</span>
23
+ </div>
24
+ </div>
25
+
26
+ <!-- 右侧内容区 -->
27
+ <div class="tab-content">
28
+ <!-- 基本信息 -->
29
+ <div v-show="activeTab === 'basic'" class="content-section">
30
+ <div class="section-header">
31
+ <h4>基本信息</h4>
32
+ <p>设置渠道的名称、连接器和标签</p>
33
+ </div>
34
+
35
+ <div class="form-group">
36
+ <label class="form-label required">渠道名称</label>
37
+ <el-input
38
+ v-model="form.name"
39
+ placeholder="如 OpenAI DALL-E"
40
+ />
41
+ <div class="form-hint">用户可见的渠道名称,冲突时会自动添加后缀</div>
42
+ </div>
43
+
44
+ <div class="form-row">
45
+ <div class="form-group flex-1">
46
+ <label class="form-label required">连接器</label>
47
+ <el-select
48
+ v-model="form.connectorId"
49
+ placeholder="选择连接器"
50
+ @change="handleConnectorChange"
51
+ style="width: 100%"
52
+ >
53
+ <el-option
54
+ v-for="connector in connectors"
55
+ :key="connector.id"
56
+ :label="connector.name"
57
+ :value="connector.id"
58
+ />
59
+ </el-select>
60
+ </div>
61
+ <div class="form-group">
62
+ <label class="form-label">启用状态</label>
63
+ <div class="switch-wrapper">
64
+ <el-switch v-model="form.enabled" />
65
+ <span class="switch-label">{{ form.enabled ? '启用' : '禁用' }}</span>
66
+ </div>
67
+ </div>
68
+ </div>
69
+
70
+ <div class="form-group">
71
+ <label class="form-label">标签</label>
72
+ <TagInput v-model="form.tags!" placeholder="输入标签后按回车..." />
73
+ <div class="form-hint">用于分类和筛选渠道</div>
74
+ </div>
75
+
76
+ <!-- 连接器配置(内嵌) -->
77
+ <template v-if="currentConnectorFields.length > 0">
78
+ <div class="section-divider">
79
+ <span>{{ currentConnectorName }} 配置</span>
80
+ </div>
81
+ <ConfigRenderer
82
+ :fields="currentConnectorFields"
83
+ v-model="form.connectorConfig!"
84
+ />
85
+ </template>
86
+ </div>
87
+
88
+ <!-- 中间件流程 -->
89
+ <div v-show="activeTab === 'middlewares'" class="content-section">
90
+ <div class="section-header">
91
+ <h4>中间件流程</h4>
92
+ <p>控制此渠道的中间件启用状态</p>
93
+ </div>
94
+
95
+ <div class="override-hint-bar">
96
+ <k-icon name="info-circle" />
97
+ <span>留空表示跟随全局配置</span>
98
+ </div>
99
+
100
+ <div class="pipeline-flow">
101
+ <div
102
+ v-for="(phase, phaseIndex) in phases"
103
+ :key="phase.id"
104
+ class="phase-section"
105
+ >
106
+ <!-- 阶段标题 -->
107
+ <div class="phase-header" :class="phase.colorClass">
108
+ <div class="phase-icon">
109
+ <k-icon :name="phase.icon" />
110
+ </div>
111
+ <div class="phase-info">
112
+ <span class="phase-name">{{ phase.label }}</span>
113
+ <span class="phase-desc">{{ phase.description }}</span>
114
+ </div>
115
+ <span class="phase-badge">{{ getPhaseMiddlewares(phase.id).length }}</span>
116
+ </div>
117
+
118
+ <!-- 中间件列表 -->
119
+ <div class="phase-middlewares" v-if="getPhaseMiddlewares(phase.id).length > 0">
120
+ <div
121
+ v-for="mw in getPhaseMiddlewares(phase.id)"
122
+ :key="mw.name"
123
+ class="mw-item"
124
+ :class="{ 'has-override': getMiddlewareEnabled(mw.configGroup || mw.name, mw.name) !== undefined }"
125
+ >
126
+ <div class="mw-card">
127
+ <div class="mw-status" :class="getMiddlewareStatusClass(mw)"></div>
128
+ <div class="mw-content">
129
+ <span class="mw-name">{{ mw.displayName }}</span>
130
+ <span class="mw-desc">{{ mw.description || categoryLabels[mw.category] || mw.category }}</span>
131
+ </div>
132
+ <el-select
133
+ :model-value="getMiddlewareEnabled(mw.configGroup || mw.name, mw.name)"
134
+ @update:model-value="setMiddlewareEnabled(mw.configGroup || mw.name, mw.name, $event)"
135
+ :placeholder="mw.enabled ? '全局: 启用' : '全局: 禁用'"
136
+ clearable
137
+ size="small"
138
+ class="mw-switch"
139
+ >
140
+ <el-option label="启用" :value="true" />
141
+ <el-option label="禁用" :value="false" />
142
+ </el-select>
143
+ </div>
144
+ </div>
145
+ </div>
146
+
147
+ <!-- 空状态 -->
148
+ <div v-else class="empty-phase">
149
+ <span>无中间件</span>
150
+ </div>
151
+
152
+ <!-- 阶段间连接箭头 -->
153
+ <div v-if="phaseIndex < phases.length - 1" class="phase-connector">
154
+ <div class="connector-line"></div>
155
+ <div class="connector-arrow">
156
+ <k-icon name="chevron-down" />
157
+ </div>
158
+ <div class="connector-line"></div>
159
+ </div>
160
+ </div>
161
+ </div>
162
+
163
+ <!-- 底部说明 -->
164
+ <div class="pipeline-footer">
165
+ <div class="footer-item">
166
+ <span class="dot active"></span>
167
+ <span>启用 - 中间件将在请求中执行</span>
168
+ </div>
169
+ <div class="footer-item">
170
+ <span class="dot"></span>
171
+ <span>禁用 - 中间件将被跳过</span>
172
+ </div>
173
+ <div class="footer-item">
174
+ <span class="dot override"></span>
175
+ <span>已覆盖 - 与全局配置不同</span>
176
+ </div>
177
+ </div>
178
+ </div>
179
+
180
+ <!-- 插件配置 -->
181
+ <div v-show="activeTab === 'plugins'" class="content-section">
182
+ <div class="section-header">
183
+ <h4>插件配置覆盖</h4>
184
+ <p>为此渠道单独配置插件参数</p>
185
+ </div>
186
+
187
+ <div class="override-hint-bar">
188
+ <k-icon name="info-circle" />
189
+ <span>留空使用全局配置,填写后将覆盖全局设置</span>
190
+ </div>
191
+
192
+ <div v-if="pluginsWithConfig.length > 0" class="plugins-override-list">
193
+ <div
194
+ v-for="plugin in pluginsWithConfig"
195
+ :key="plugin.id"
196
+ class="plugin-override-card"
197
+ :class="{ expanded: expandedPlugins.has(plugin.id) }"
198
+ >
199
+ <div class="plugin-header" @click="togglePluginExpand(plugin.id)">
200
+ <div class="plugin-info">
201
+ <span class="plugin-name">{{ plugin.name }}</span>
202
+ <span v-if="hasPluginOverride(plugin.id)" class="override-badge">已覆盖</span>
203
+ </div>
204
+ <div class="plugin-actions">
205
+ <k-button
206
+ v-if="hasPluginOverride(plugin.id)"
207
+ size="mini"
208
+ @click.stop="clearPluginOverride(plugin.id)"
209
+ >
210
+ 清除
211
+ </k-button>
212
+ <k-icon :name="expandedPlugins.has(plugin.id) ? 'chevron-up' : 'chevron-down'" />
213
+ </div>
214
+ </div>
215
+
216
+ <div v-show="expandedPlugins.has(plugin.id)" class="plugin-config-fields">
217
+ <template v-for="field in plugin.configFields" :key="field.key">
218
+ <div v-if="shouldShowOverrideField(plugin, field)" class="override-field-row">
219
+ <label class="field-label">{{ field.label }}</label>
220
+ <div class="field-input">
221
+ <!-- Boolean 类型 -->
222
+ <template v-if="field.type === 'boolean'">
223
+ <el-select
224
+ :model-value="getOverrideValue(plugin.id, field.key)"
225
+ @update:model-value="setOverrideValue(plugin.id, field.key, $event)"
226
+ placeholder="使用全局配置"
227
+ clearable
228
+ >
229
+ <el-option label="是" :value="true" />
230
+ <el-option label="否" :value="false" />
231
+ </el-select>
232
+ </template>
233
+
234
+ <!-- Select 类型 -->
235
+ <template v-else-if="field.type === 'select'">
236
+ <el-select
237
+ :model-value="getOverrideValue(plugin.id, field.key)"
238
+ @update:model-value="setOverrideValue(plugin.id, field.key, $event)"
239
+ :placeholder="`全局: ${plugin.config[field.key] ?? '未设置'}`"
240
+ clearable
241
+ >
242
+ <el-option
243
+ v-for="opt in field.options"
244
+ :key="String(opt.value)"
245
+ :label="opt.label"
246
+ :value="opt.value"
247
+ />
248
+ </el-select>
249
+ </template>
250
+
251
+ <!-- Number 类型 -->
252
+ <template v-else-if="field.type === 'number'">
253
+ <el-input-number
254
+ :model-value="getOverrideValue(plugin.id, field.key)"
255
+ @update:model-value="setOverrideValue(plugin.id, field.key, $event)"
256
+ :placeholder="`全局: ${plugin.config[field.key] ?? ''}`"
257
+ />
258
+ </template>
259
+
260
+ <!-- Text/String 类型 (默认) -->
261
+ <template v-else>
262
+ <el-input
263
+ :model-value="getOverrideValue(plugin.id, field.key)"
264
+ @update:model-value="setOverrideValue(plugin.id, field.key, $event)"
265
+ :placeholder="`全局: ${plugin.config[field.key] ?? '未设置'}`"
266
+ clearable
267
+ />
268
+ </template>
269
+ </div>
270
+ <div v-if="field.description" class="field-hint">{{ field.description }}</div>
271
+ </div>
272
+ </template>
273
+ </div>
274
+ </div>
275
+ </div>
276
+
277
+ <div v-else class="empty-hint">
278
+ <k-icon name="apps" />
279
+ <span>暂无可配置的插件</span>
280
+ </div>
281
+ </div>
282
+ </div>
283
+ </div>
284
+
285
+ <template #footer>
286
+ <div class="dialog-footer">
287
+ <k-button @click="visible = false">取消</k-button>
288
+ <k-button type="primary" @click="handleSave" :loading="saving">
289
+ {{ isEdit ? '保存' : '创建' }}
290
+ </k-button>
291
+ </div>
292
+ </template>
293
+ </el-dialog>
294
+ </template>
295
+
296
+ <script setup lang="ts">
297
+ import { ref, computed, watch } from 'vue'
298
+ import { message } from '@koishijs/client'
299
+ import { ChannelConfig, ConfigField, ConnectorDefinition, MiddlewareInfo, FieldDefinition } from '../types'
300
+ import { channelApi, connectorApi, middlewareApi, pluginApi, PluginInfo } from '../api'
301
+ import TagInput from './TagInput.vue'
302
+ import ConfigRenderer from './ConfigRenderer.vue'
303
+
304
+ interface Props {
305
+ modelValue: boolean
306
+ channel?: ChannelConfig | null
307
+ }
308
+
309
+ const props = withDefaults(defineProps<Props>(), {
310
+ channel: null
311
+ })
312
+
313
+ const emit = defineEmits<{
314
+ 'update:modelValue': [value: boolean]
315
+ 'saved': []
316
+ }>()
317
+
318
+ // 状态
319
+ const visible = computed({
320
+ get: () => props.modelValue,
321
+ set: (v) => emit('update:modelValue', v)
322
+ })
323
+
324
+ const isEdit = computed(() => !!props.channel?.id)
325
+ const activeTab = ref('basic')
326
+ const saving = ref(false)
327
+ const expandedPlugins = ref(new Set<string>())
328
+
329
+ // 数据
330
+ const connectors = ref<ConnectorDefinition[]>([])
331
+ const connectorFields = ref<Record<string, ConfigField[]>>({})
332
+ const allMiddlewares = ref<MiddlewareInfo[]>([])
333
+ const allPlugins = ref<PluginInfo[]>([])
334
+
335
+ // 表单
336
+ const form = ref<Partial<ChannelConfig>>({
337
+ name: '',
338
+ enabled: true,
339
+ connectorId: '',
340
+ connectorConfig: {},
341
+ pluginOverrides: {},
342
+ tags: []
343
+ })
344
+
345
+ // Tab 定义
346
+ const tabs = [
347
+ { id: 'basic', label: '基本信息', icon: 'file-text' },
348
+ { id: 'middlewares', label: '中间件流程', icon: 'git-branch' },
349
+ { id: 'plugins', label: '插件配置', icon: 'puzzle' }
350
+ ]
351
+
352
+ // 阶段定义
353
+ const phases = [
354
+ { id: 'lifecycle-prepare', label: '准备', description: '验证、权限检查', icon: 'clipboard-check', colorClass: 'phase-prepare' },
355
+ { id: 'lifecycle-pre-request', label: '预处理', description: '预设应用、参数处理', icon: 'settings', colorClass: 'phase-pre' },
356
+ { id: 'lifecycle-request', label: '执行', description: '调用连接器生成', icon: 'play', colorClass: 'phase-request' },
357
+ { id: 'lifecycle-post-request', label: '后处理', description: '结果缓存、格式转换', icon: 'package', colorClass: 'phase-post' },
358
+ { id: 'lifecycle-finalize', label: '完成', description: '计费结算、记录保存', icon: 'check-circle', colorClass: 'phase-finalize' }
359
+ ]
360
+
361
+ const categoryLabels: Record<string, string> = {
362
+ billing: '计费模块',
363
+ transform: '转换处理',
364
+ validation: '验证检查',
365
+ preset: '预设系统',
366
+ cache: '缓存管理',
367
+ recording: '任务记录',
368
+ request: '请求执行',
369
+ custom: '自定义'
370
+ }
371
+
372
+ // 计算属性
373
+ const currentConnectorFields = computed(() => {
374
+ if (!form.value.connectorId) return []
375
+ return connectorFields.value[form.value.connectorId] || []
376
+ })
377
+
378
+ const currentConnectorName = computed(() => {
379
+ const connector = connectors.value.find(c => c.id === form.value.connectorId)
380
+ return connector?.name || '连接器'
381
+ })
382
+
383
+ const availableTabs = computed(() => {
384
+ return tabs.map(tab => {
385
+ let badge = ''
386
+ if (tab.id === 'middlewares') {
387
+ badge = String(allMiddlewares.value.length)
388
+ }
389
+ if (tab.id === 'plugins' && pluginsWithConfig.value.length > 0) {
390
+ badge = String(pluginsWithConfig.value.length)
391
+ }
392
+ return { ...tab, badge }
393
+ })
394
+ })
395
+
396
+ const pluginsWithConfig = computed(() => {
397
+ return allPlugins.value.filter(p => p.configFields && p.configFields.length > 0)
398
+ })
399
+
400
+ // 方法
401
+ const getPhaseMiddlewares = (phaseId: string) => {
402
+ return allMiddlewares.value.filter(mw => mw.phase === phaseId)
403
+ }
404
+
405
+ const getMiddlewareEnabled = (pluginId: string, mwName: string) => {
406
+ return form.value.pluginOverrides?.[pluginId]?.middlewares?.[mwName]
407
+ }
408
+
409
+ const setMiddlewareEnabled = (pluginId: string, mwName: string, value: boolean | undefined | null) => {
410
+ if (!form.value.pluginOverrides) {
411
+ form.value.pluginOverrides = {}
412
+ }
413
+ if (!form.value.pluginOverrides[pluginId]) {
414
+ form.value.pluginOverrides[pluginId] = {}
415
+ }
416
+ if (!form.value.pluginOverrides[pluginId].middlewares) {
417
+ form.value.pluginOverrides[pluginId].middlewares = {}
418
+ }
419
+
420
+ if (value === undefined || value === null) {
421
+ delete form.value.pluginOverrides[pluginId].middlewares[mwName]
422
+ if (Object.keys(form.value.pluginOverrides[pluginId].middlewares).length === 0) {
423
+ delete form.value.pluginOverrides[pluginId].middlewares
424
+ }
425
+ if (Object.keys(form.value.pluginOverrides[pluginId]).length === 0) {
426
+ delete form.value.pluginOverrides[pluginId]
427
+ }
428
+ } else {
429
+ form.value.pluginOverrides[pluginId].middlewares[mwName] = value
430
+ }
431
+ }
432
+
433
+ const getMiddlewareStatusClass = (mw: MiddlewareInfo) => {
434
+ const override = getMiddlewareEnabled(mw.configGroup || mw.name, mw.name)
435
+ if (override !== undefined) {
436
+ return override ? 'active override' : 'override'
437
+ }
438
+ return mw.enabled ? 'active' : ''
439
+ }
440
+
441
+ const getOverrideValue = (groupId: string, fieldKey: string) => {
442
+ return form.value.pluginOverrides?.[groupId]?.[fieldKey]
443
+ }
444
+
445
+ const setOverrideValue = (groupId: string, fieldKey: string, value: any) => {
446
+ if (!form.value.pluginOverrides) {
447
+ form.value.pluginOverrides = {}
448
+ }
449
+ if (!form.value.pluginOverrides[groupId]) {
450
+ form.value.pluginOverrides[groupId] = {}
451
+ }
452
+ if (value === undefined || value === null || value === '') {
453
+ delete form.value.pluginOverrides[groupId][fieldKey]
454
+ if (Object.keys(form.value.pluginOverrides[groupId]).length === 0) {
455
+ delete form.value.pluginOverrides[groupId]
456
+ }
457
+ } else {
458
+ form.value.pluginOverrides[groupId][fieldKey] = value
459
+ }
460
+ }
461
+
462
+ const hasPluginOverride = (pluginId: string) => {
463
+ const override = form.value.pluginOverrides?.[pluginId]
464
+ return override && Object.keys(override).length > 0
465
+ }
466
+
467
+ const clearPluginOverride = (pluginId: string) => {
468
+ if (form.value.pluginOverrides) {
469
+ delete form.value.pluginOverrides[pluginId]
470
+ }
471
+ }
472
+
473
+ const togglePluginExpand = (pluginId: string) => {
474
+ if (expandedPlugins.value.has(pluginId)) {
475
+ expandedPlugins.value.delete(pluginId)
476
+ } else {
477
+ expandedPlugins.value.add(pluginId)
478
+ }
479
+ }
480
+
481
+ const shouldShowOverrideField = (plugin: PluginInfo, field: FieldDefinition) => {
482
+ if (!field.showWhen) return true
483
+ const { field: dependField, value } = field.showWhen
484
+ const overrideValue = form.value.pluginOverrides?.[plugin.id]?.[dependField]
485
+ const globalValue = plugin.config[dependField]
486
+ const effectiveValue = overrideValue !== undefined ? overrideValue : globalValue
487
+ return effectiveValue === value
488
+ }
489
+
490
+ const handleConnectorChange = async (connectorId: string) => {
491
+ form.value.connectorConfig = {}
492
+ if (connectorId && !connectorFields.value[connectorId]) {
493
+ try {
494
+ const fields = await connectorApi.fields(connectorId)
495
+ connectorFields.value[connectorId] = fields
496
+ } catch (e) {
497
+ console.error('Failed to load connector fields:', e)
498
+ }
499
+ }
500
+ }
501
+
502
+ const handleSave = async () => {
503
+ if (!form.value.name) {
504
+ message.error('请输入渠道名称')
505
+ return
506
+ }
507
+ if (!form.value.connectorId) {
508
+ message.error('请选择连接器')
509
+ return
510
+ }
511
+
512
+ saving.value = true
513
+ try {
514
+ if (isEdit.value && props.channel?.id) {
515
+ await channelApi.update(props.channel.id, form.value)
516
+ message.success('保存成功')
517
+ } else {
518
+ await channelApi.create(form.value as Omit<ChannelConfig, 'id'>)
519
+ message.success('创建成功')
520
+ }
521
+ emit('saved')
522
+ visible.value = false
523
+ } catch (e) {
524
+ message.error(e instanceof Error ? e.message : '操作失败')
525
+ } finally {
526
+ saving.value = false
527
+ }
528
+ }
529
+
530
+ const handleClosed = () => {
531
+ activeTab.value = 'basic'
532
+ expandedPlugins.value.clear()
533
+ }
534
+
535
+ // 加载数据
536
+ const loadData = async () => {
537
+ try {
538
+ const [connectorsData, mwData, pluginsData] = await Promise.all([
539
+ connectorApi.list(),
540
+ middlewareApi.list(),
541
+ pluginApi.list()
542
+ ])
543
+ connectors.value = connectorsData
544
+ allMiddlewares.value = mwData
545
+ allPlugins.value = pluginsData.filter(p =>
546
+ (p.configFields && p.configFields.length > 0) ||
547
+ (p.middlewares && p.middlewares.length > 0)
548
+ )
549
+ } catch (e) {
550
+ console.error('Failed to load data:', e)
551
+ }
552
+ }
553
+
554
+ // 监听
555
+ watch(() => props.modelValue, async (newVal) => {
556
+ if (newVal) {
557
+ await loadData()
558
+
559
+ if (props.channel) {
560
+ form.value = JSON.parse(JSON.stringify(props.channel))
561
+ if (!form.value.pluginOverrides) {
562
+ form.value.pluginOverrides = {}
563
+ }
564
+ if (!form.value.connectorConfig) {
565
+ form.value.connectorConfig = {}
566
+ }
567
+ // 加载连接器字段(但不清空现有配置)
568
+ if (form.value.connectorId && !connectorFields.value[form.value.connectorId]) {
569
+ try {
570
+ const fields = await connectorApi.fields(form.value.connectorId)
571
+ connectorFields.value[form.value.connectorId] = fields
572
+ } catch (e) {
573
+ console.error('Failed to load connector fields:', e)
574
+ }
575
+ }
576
+ // 默认展开有覆盖的插件
577
+ for (const pluginId of Object.keys(form.value.pluginOverrides)) {
578
+ expandedPlugins.value.add(pluginId)
579
+ }
580
+ } else {
581
+ form.value = {
582
+ name: '',
583
+ enabled: true,
584
+ connectorId: '',
585
+ connectorConfig: {},
586
+ pluginOverrides: {},
587
+ tags: []
588
+ }
589
+ }
590
+ }
591
+ })
592
+ </script>
593
+
594
+ <style scoped>
595
+ .channel-config-dialog :deep(.el-dialog__body) {
596
+ padding: 0;
597
+ }
598
+
599
+ .dialog-layout {
600
+ display: flex;
601
+ height: 560px;
602
+ }
603
+
604
+ /* Tab 导航 */
605
+ .tab-nav {
606
+ width: 180px;
607
+ flex-shrink: 0;
608
+ background: var(--k-color-bg-2);
609
+ border-right: 1px solid var(--k-color-border);
610
+ padding: 1rem 0;
611
+ }
612
+
613
+ .tab-item {
614
+ display: flex;
615
+ align-items: center;
616
+ gap: 10px;
617
+ padding: 12px 20px;
618
+ cursor: pointer;
619
+ color: var(--k-color-text-description);
620
+ transition: all 0.2s;
621
+ border-left: 3px solid transparent;
622
+ }
623
+
624
+ .tab-item:hover {
625
+ background: var(--k-color-bg-1);
626
+ color: var(--k-color-text);
627
+ }
628
+
629
+ .tab-item.active {
630
+ background: var(--k-card-bg);
631
+ color: var(--k-color-active);
632
+ border-left-color: var(--k-color-active);
633
+ }
634
+
635
+ .tab-item .k-icon {
636
+ font-size: 16px;
637
+ }
638
+
639
+ .tab-badge {
640
+ margin-left: auto;
641
+ min-width: 20px;
642
+ height: 20px;
643
+ padding: 0 6px;
644
+ background: var(--k-color-bg-1);
645
+ border-radius: 10px;
646
+ font-size: 11px;
647
+ display: flex;
648
+ align-items: center;
649
+ justify-content: center;
650
+ }
651
+
652
+ .tab-item.active .tab-badge {
653
+ background: var(--k-color-active);
654
+ color: white;
655
+ }
656
+
657
+ /* 内容区 */
658
+ .tab-content {
659
+ flex: 1;
660
+ overflow-y: auto;
661
+ padding: 1.5rem;
662
+ background: var(--k-card-bg);
663
+ }
664
+
665
+ .content-section {
666
+ max-width: 560px;
667
+ }
668
+
669
+ .section-header {
670
+ margin-bottom: 1.5rem;
671
+ }
672
+
673
+ .section-header h4 {
674
+ margin: 0 0 4px 0;
675
+ font-size: 16px;
676
+ font-weight: 600;
677
+ color: var(--k-color-text);
678
+ }
679
+
680
+ .section-header p {
681
+ margin: 0;
682
+ font-size: 13px;
683
+ color: var(--k-color-text-description);
684
+ }
685
+
686
+ /* 表单 */
687
+ .form-group {
688
+ margin-bottom: 1.25rem;
689
+ }
690
+
691
+ .form-row {
692
+ display: flex;
693
+ gap: 1.5rem;
694
+ }
695
+
696
+ .flex-1 {
697
+ flex: 1;
698
+ }
699
+
700
+ .form-label {
701
+ display: block;
702
+ margin-bottom: 6px;
703
+ font-size: 13px;
704
+ color: var(--k-color-text);
705
+ font-weight: 500;
706
+ }
707
+
708
+ .form-label.required::after {
709
+ content: '*';
710
+ color: var(--k-color-error, #f56c6c);
711
+ margin-left: 4px;
712
+ }
713
+
714
+ .form-hint {
715
+ margin-top: 6px;
716
+ font-size: 12px;
717
+ color: var(--k-color-text-description);
718
+ }
719
+
720
+ .switch-wrapper {
721
+ display: flex;
722
+ align-items: center;
723
+ gap: 8px;
724
+ height: 32px;
725
+ }
726
+
727
+ .switch-label {
728
+ font-size: 13px;
729
+ color: var(--k-color-text-description);
730
+ }
731
+
732
+ /* 分隔线 */
733
+ .section-divider {
734
+ display: flex;
735
+ align-items: center;
736
+ margin: 1.5rem 0 1rem;
737
+ font-size: 13px;
738
+ font-weight: 500;
739
+ color: var(--k-color-text);
740
+ }
741
+
742
+ .section-divider::before,
743
+ .section-divider::after {
744
+ content: '';
745
+ flex: 1;
746
+ height: 1px;
747
+ background: var(--k-color-border);
748
+ }
749
+
750
+ .section-divider::before {
751
+ margin-right: 12px;
752
+ }
753
+
754
+ .section-divider::after {
755
+ margin-left: 12px;
756
+ }
757
+
758
+ .empty-hint {
759
+ display: flex;
760
+ flex-direction: column;
761
+ align-items: center;
762
+ justify-content: center;
763
+ gap: 12px;
764
+ padding: 3rem;
765
+ color: var(--k-color-text-description);
766
+ }
767
+
768
+ .empty-hint .k-icon {
769
+ font-size: 2rem;
770
+ opacity: 0.5;
771
+ }
772
+
773
+ /* 覆盖提示栏 */
774
+ .override-hint-bar {
775
+ display: flex;
776
+ align-items: center;
777
+ gap: 8px;
778
+ padding: 10px 14px;
779
+ background: var(--k-color-bg-2);
780
+ border-radius: 8px;
781
+ font-size: 13px;
782
+ color: var(--k-color-text-description);
783
+ margin-bottom: 1.5rem;
784
+ }
785
+
786
+ .override-hint-bar .k-icon {
787
+ color: var(--k-color-active);
788
+ }
789
+
790
+ /* 中间件流程 */
791
+ .pipeline-flow {
792
+ display: flex;
793
+ flex-direction: column;
794
+ }
795
+
796
+ .phase-section {
797
+ display: flex;
798
+ flex-direction: column;
799
+ }
800
+
801
+ .phase-header {
802
+ display: flex;
803
+ align-items: center;
804
+ gap: 12px;
805
+ padding: 12px 16px;
806
+ background: var(--k-card-bg);
807
+ border: 1px solid var(--k-color-border);
808
+ border-radius: 10px;
809
+ transition: all 0.2s;
810
+ }
811
+
812
+ .phase-icon {
813
+ display: flex;
814
+ align-items: center;
815
+ justify-content: center;
816
+ width: 36px;
817
+ height: 36px;
818
+ border-radius: 8px;
819
+ font-size: 16px;
820
+ }
821
+
822
+ .phase-prepare .phase-icon { background: rgba(59, 130, 246, 0.15); color: #3b82f6; }
823
+ .phase-pre .phase-icon { background: rgba(139, 92, 246, 0.15); color: #8b5cf6; }
824
+ .phase-request .phase-icon { background: rgba(34, 197, 94, 0.15); color: #22c55e; }
825
+ .phase-post .phase-icon { background: rgba(249, 115, 22, 0.15); color: #f97316; }
826
+ .phase-finalize .phase-icon { background: rgba(99, 102, 241, 0.15); color: #6366f1; }
827
+
828
+ .phase-info {
829
+ flex: 1;
830
+ display: flex;
831
+ flex-direction: column;
832
+ gap: 2px;
833
+ }
834
+
835
+ .phase-name {
836
+ font-size: 14px;
837
+ font-weight: 600;
838
+ color: var(--k-color-text);
839
+ }
840
+
841
+ .phase-desc {
842
+ font-size: 11px;
843
+ color: var(--k-color-text-description);
844
+ }
845
+
846
+ .phase-badge {
847
+ min-width: 24px;
848
+ height: 24px;
849
+ padding: 0 8px;
850
+ background: var(--k-color-bg-2);
851
+ border-radius: 12px;
852
+ font-size: 12px;
853
+ font-weight: 500;
854
+ color: var(--k-color-text-description);
855
+ display: flex;
856
+ align-items: center;
857
+ justify-content: center;
858
+ }
859
+
860
+ .phase-middlewares {
861
+ display: flex;
862
+ flex-direction: column;
863
+ margin-left: 24px;
864
+ padding-left: 24px;
865
+ border-left: 2px solid var(--k-color-border);
866
+ }
867
+
868
+ .mw-item {
869
+ position: relative;
870
+ }
871
+
872
+ .mw-item::before {
873
+ content: '';
874
+ position: absolute;
875
+ left: -25px;
876
+ top: 50%;
877
+ width: 12px;
878
+ height: 2px;
879
+ background: var(--k-color-border);
880
+ }
881
+
882
+ .mw-item.has-override::before {
883
+ background: var(--k-color-active);
884
+ }
885
+
886
+ .mw-card {
887
+ display: flex;
888
+ align-items: center;
889
+ gap: 12px;
890
+ padding: 10px 14px;
891
+ margin: 6px 0;
892
+ background: var(--k-card-bg);
893
+ border: 1px solid var(--k-color-border);
894
+ border-radius: 8px;
895
+ transition: all 0.2s;
896
+ }
897
+
898
+ .mw-item.has-override .mw-card {
899
+ border-color: var(--k-color-active);
900
+ background: var(--k-color-active-bg);
901
+ }
902
+
903
+ .mw-status {
904
+ width: 8px;
905
+ height: 8px;
906
+ border-radius: 50%;
907
+ background: var(--k-color-text-description);
908
+ flex-shrink: 0;
909
+ }
910
+
911
+ .mw-status.active {
912
+ background: #22c55e;
913
+ box-shadow: 0 0 8px rgba(34, 197, 94, 0.4);
914
+ }
915
+
916
+ .mw-status.override {
917
+ background: var(--k-color-active);
918
+ box-shadow: 0 0 8px var(--k-color-active);
919
+ }
920
+
921
+ .mw-content {
922
+ flex: 1;
923
+ display: flex;
924
+ flex-direction: column;
925
+ gap: 2px;
926
+ min-width: 0;
927
+ }
928
+
929
+ .mw-name {
930
+ font-size: 13px;
931
+ font-weight: 500;
932
+ color: var(--k-color-text);
933
+ }
934
+
935
+ .mw-desc {
936
+ font-size: 11px;
937
+ color: var(--k-color-text-description);
938
+ white-space: nowrap;
939
+ overflow: hidden;
940
+ text-overflow: ellipsis;
941
+ }
942
+
943
+ .mw-switch {
944
+ width: 120px;
945
+ flex-shrink: 0;
946
+ }
947
+
948
+ .empty-phase {
949
+ margin-left: 24px;
950
+ padding: 12px 24px;
951
+ border-left: 2px dashed var(--k-color-border);
952
+ color: var(--k-color-text-description);
953
+ font-size: 12px;
954
+ font-style: italic;
955
+ }
956
+
957
+ .phase-connector {
958
+ display: flex;
959
+ flex-direction: column;
960
+ align-items: center;
961
+ padding: 4px 0;
962
+ }
963
+
964
+ .connector-line {
965
+ width: 2px;
966
+ height: 8px;
967
+ background: var(--k-color-border);
968
+ }
969
+
970
+ .connector-arrow {
971
+ display: flex;
972
+ align-items: center;
973
+ justify-content: center;
974
+ width: 20px;
975
+ height: 20px;
976
+ color: var(--k-color-text-description);
977
+ font-size: 12px;
978
+ }
979
+
980
+ .pipeline-footer {
981
+ display: flex;
982
+ flex-wrap: wrap;
983
+ gap: 16px;
984
+ margin-top: 1.5rem;
985
+ padding: 12px 16px;
986
+ background: var(--k-color-bg-2);
987
+ border-radius: 10px;
988
+ }
989
+
990
+ .footer-item {
991
+ display: flex;
992
+ align-items: center;
993
+ gap: 8px;
994
+ font-size: 12px;
995
+ color: var(--k-color-text-description);
996
+ }
997
+
998
+ .dot {
999
+ width: 8px;
1000
+ height: 8px;
1001
+ border-radius: 50%;
1002
+ background: var(--k-color-text-description);
1003
+ }
1004
+
1005
+ .dot.active {
1006
+ background: #22c55e;
1007
+ }
1008
+
1009
+ .dot.override {
1010
+ background: var(--k-color-active);
1011
+ }
1012
+
1013
+ /* 插件配置列表 */
1014
+ .plugins-override-list {
1015
+ display: flex;
1016
+ flex-direction: column;
1017
+ gap: 12px;
1018
+ }
1019
+
1020
+ .plugin-override-card {
1021
+ border: 1px solid var(--k-color-border);
1022
+ border-radius: 10px;
1023
+ overflow: hidden;
1024
+ transition: all 0.2s;
1025
+ }
1026
+
1027
+ .plugin-override-card.expanded {
1028
+ border-color: var(--k-color-active);
1029
+ }
1030
+
1031
+ .plugin-header {
1032
+ display: flex;
1033
+ align-items: center;
1034
+ justify-content: space-between;
1035
+ padding: 12px 16px;
1036
+ background: var(--k-color-bg-2);
1037
+ cursor: pointer;
1038
+ transition: background 0.2s;
1039
+ }
1040
+
1041
+ .plugin-header:hover {
1042
+ background: var(--k-color-bg-1);
1043
+ }
1044
+
1045
+ .plugin-info {
1046
+ display: flex;
1047
+ align-items: center;
1048
+ gap: 10px;
1049
+ }
1050
+
1051
+ .plugin-name {
1052
+ font-weight: 500;
1053
+ color: var(--k-color-text);
1054
+ }
1055
+
1056
+ .override-badge {
1057
+ font-size: 11px;
1058
+ padding: 2px 8px;
1059
+ background: var(--k-color-active);
1060
+ color: white;
1061
+ border-radius: 10px;
1062
+ }
1063
+
1064
+ .plugin-actions {
1065
+ display: flex;
1066
+ align-items: center;
1067
+ gap: 8px;
1068
+ }
1069
+
1070
+ .plugin-config-fields {
1071
+ padding: 16px;
1072
+ background: var(--k-card-bg);
1073
+ border-top: 1px solid var(--k-color-border);
1074
+ }
1075
+
1076
+ .override-field-row {
1077
+ margin-bottom: 1rem;
1078
+ }
1079
+
1080
+ .override-field-row:last-child {
1081
+ margin-bottom: 0;
1082
+ }
1083
+
1084
+ .field-label {
1085
+ display: block;
1086
+ margin-bottom: 6px;
1087
+ font-size: 13px;
1088
+ color: var(--k-color-text);
1089
+ font-weight: 500;
1090
+ }
1091
+
1092
+ .field-input {
1093
+ width: 100%;
1094
+ }
1095
+
1096
+ .field-input .el-select,
1097
+ .field-input .el-input {
1098
+ width: 100%;
1099
+ }
1100
+
1101
+ .field-hint {
1102
+ margin-top: 4px;
1103
+ font-size: 12px;
1104
+ color: var(--k-color-text-description);
1105
+ }
1106
+
1107
+ /* 底部按钮 */
1108
+ .dialog-footer {
1109
+ display: flex;
1110
+ justify-content: flex-end;
1111
+ gap: 12px;
1112
+ }
1113
+ </style>