koishi-plugin-media-luna 0.0.35 → 0.0.36
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/client/components/ChannelConfigDialog.vue +122 -2
- package/client/components/ConfigRenderer.vue +5 -1
- package/dist/index.js +2 -2
- package/dist/style.css +1 -1
- package/lib/core/pipeline/generation-pipeline.d.ts +3 -1
- package/lib/core/pipeline/generation-pipeline.d.ts.map +1 -1
- package/lib/core/pipeline/generation-pipeline.js +11 -4
- package/lib/core/pipeline/generation-pipeline.js.map +1 -1
- package/lib/plugins/connector-chatluna/middleware.d.ts.map +1 -1
- package/lib/plugins/connector-chatluna/middleware.js +11 -2
- package/lib/plugins/connector-chatluna/middleware.js.map +1 -1
- package/package.json +1 -1
|
@@ -248,6 +248,25 @@
|
|
|
248
248
|
</el-select>
|
|
249
249
|
</template>
|
|
250
250
|
|
|
251
|
+
<!-- Select Remote 类型 -->
|
|
252
|
+
<template v-else-if="field.type === 'select-remote'">
|
|
253
|
+
<el-select
|
|
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
|
+
:loading="isRemoteLoading(field)"
|
|
258
|
+
clearable
|
|
259
|
+
filterable
|
|
260
|
+
>
|
|
261
|
+
<el-option
|
|
262
|
+
v-for="opt in getRemoteOptions(field, plugin)"
|
|
263
|
+
:key="String(opt.value)"
|
|
264
|
+
:label="opt.label"
|
|
265
|
+
:value="opt.value"
|
|
266
|
+
/>
|
|
267
|
+
</el-select>
|
|
268
|
+
</template>
|
|
269
|
+
|
|
251
270
|
<!-- Number 类型 -->
|
|
252
271
|
<template v-else-if="field.type === 'number'">
|
|
253
272
|
<el-input-number
|
|
@@ -257,6 +276,17 @@
|
|
|
257
276
|
/>
|
|
258
277
|
</template>
|
|
259
278
|
|
|
279
|
+
<!-- Textarea 类型 -->
|
|
280
|
+
<template v-else-if="field.type === 'textarea'">
|
|
281
|
+
<el-input
|
|
282
|
+
:model-value="getOverrideValue(plugin.id, field.key)"
|
|
283
|
+
@update:model-value="setOverrideValue(plugin.id, field.key, $event)"
|
|
284
|
+
type="textarea"
|
|
285
|
+
:rows="3"
|
|
286
|
+
:placeholder="`全局: ${plugin.config[field.key] ?? '未设置'}`"
|
|
287
|
+
/>
|
|
288
|
+
</template>
|
|
289
|
+
|
|
260
290
|
<!-- Text/String 类型 (默认) -->
|
|
261
291
|
<template v-else>
|
|
262
292
|
<el-input
|
|
@@ -294,8 +324,8 @@
|
|
|
294
324
|
</template>
|
|
295
325
|
|
|
296
326
|
<script setup lang="ts">
|
|
297
|
-
import { ref, computed, watch } from 'vue'
|
|
298
|
-
import { message } from '@koishijs/client'
|
|
327
|
+
import { ref, computed, watch, onMounted } from 'vue'
|
|
328
|
+
import { message, send } from '@koishijs/client'
|
|
299
329
|
import { ChannelConfig, ConfigField, ConnectorDefinition, MiddlewareInfo, FieldDefinition } from '../types'
|
|
300
330
|
import { channelApi, connectorApi, middlewareApi, pluginApi, PluginInfo } from '../api'
|
|
301
331
|
import TagInput from './TagInput.vue'
|
|
@@ -332,6 +362,10 @@ const connectorFields = ref<Record<string, ConfigField[]>>({})
|
|
|
332
362
|
const allMiddlewares = ref<MiddlewareInfo[]>([])
|
|
333
363
|
const allPlugins = ref<PluginInfo[]>([])
|
|
334
364
|
|
|
365
|
+
// 远程选项缓存(用于 select-remote 类型字段)
|
|
366
|
+
const remoteOptionsCache = ref<Record<string, { label: string; value: any }[]>>({})
|
|
367
|
+
const remoteOptionsLoading = ref<Record<string, boolean>>({})
|
|
368
|
+
|
|
335
369
|
// 表单
|
|
336
370
|
const form = ref<Partial<ChannelConfig>>({
|
|
337
371
|
name: '',
|
|
@@ -397,6 +431,92 @@ const pluginsWithConfig = computed(() => {
|
|
|
397
431
|
return allPlugins.value.filter(p => p.configFields && p.configFields.length > 0)
|
|
398
432
|
})
|
|
399
433
|
|
|
434
|
+
// ============ 远程选项相关方法 ============
|
|
435
|
+
|
|
436
|
+
// 构建带参数的缓存 key
|
|
437
|
+
const buildCacheKey = (source: string, params?: Record<string, any>) => {
|
|
438
|
+
if (!params || Object.keys(params).length === 0) {
|
|
439
|
+
return source
|
|
440
|
+
}
|
|
441
|
+
const sortedParams = Object.keys(params).sort().map(k => `${k}=${params[k]}`).join('&')
|
|
442
|
+
return `${source}?${sortedParams}`
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// 获取远程选项(异步)
|
|
446
|
+
const fetchRemoteOptions = async (source: string, params?: Record<string, any>) => {
|
|
447
|
+
const cacheKey = buildCacheKey(source, params)
|
|
448
|
+
|
|
449
|
+
if (remoteOptionsCache.value[cacheKey] || remoteOptionsLoading.value[cacheKey]) {
|
|
450
|
+
return
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
remoteOptionsLoading.value[cacheKey] = true
|
|
454
|
+
try {
|
|
455
|
+
const result = await send(source, params)
|
|
456
|
+
if (result?.success && Array.isArray(result.data)) {
|
|
457
|
+
remoteOptionsCache.value[cacheKey] = result.data
|
|
458
|
+
} else {
|
|
459
|
+
remoteOptionsCache.value[cacheKey] = []
|
|
460
|
+
}
|
|
461
|
+
} catch (e) {
|
|
462
|
+
console.error(`Failed to fetch options from ${source}:`, e)
|
|
463
|
+
remoteOptionsCache.value[cacheKey] = []
|
|
464
|
+
} finally {
|
|
465
|
+
remoteOptionsLoading.value[cacheKey] = false
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// 获取字段参数(基于 dependsOn 和插件配置)
|
|
470
|
+
const getFieldParams = (field: FieldDefinition, plugin: PluginInfo): Record<string, any> | undefined => {
|
|
471
|
+
if (!field.dependsOn) return undefined
|
|
472
|
+
// 优先使用覆盖值,其次使用全局配置
|
|
473
|
+
const overrideValue = form.value.pluginOverrides?.[plugin.id]?.[field.dependsOn]
|
|
474
|
+
const globalValue = plugin.config[field.dependsOn]
|
|
475
|
+
const dependValue = overrideValue !== undefined ? overrideValue : globalValue
|
|
476
|
+
|
|
477
|
+
if (dependValue === undefined || dependValue === null || dependValue === '') {
|
|
478
|
+
return undefined
|
|
479
|
+
}
|
|
480
|
+
// 提取 dependsOn 的最后一段作为参数名
|
|
481
|
+
const paramName = field.dependsOn.includes('.')
|
|
482
|
+
? field.dependsOn.split('.').pop()!
|
|
483
|
+
: field.dependsOn
|
|
484
|
+
return { [paramName]: dependValue }
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// 获取字段的缓存 key
|
|
488
|
+
const getFieldCacheKey = (field: FieldDefinition, plugin: PluginInfo): string => {
|
|
489
|
+
if (!field.optionsSource) return ''
|
|
490
|
+
const params = getFieldParams(field, plugin)
|
|
491
|
+
return buildCacheKey(field.optionsSource, params)
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// 获取远程选项(同步访问缓存)
|
|
495
|
+
const getRemoteOptions = (field: FieldDefinition, plugin: PluginInfo) => {
|
|
496
|
+
const cacheKey = getFieldCacheKey(field, plugin)
|
|
497
|
+
if (!cacheKey) return []
|
|
498
|
+
|
|
499
|
+
// 如果还没加载,触发加载
|
|
500
|
+
if (!remoteOptionsCache.value[cacheKey] && !remoteOptionsLoading.value[cacheKey]) {
|
|
501
|
+
const params = getFieldParams(field, plugin)
|
|
502
|
+
fetchRemoteOptions(field.optionsSource!, params)
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
return remoteOptionsCache.value[cacheKey] || []
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// 检查是否正在加载
|
|
509
|
+
const isRemoteLoading = (field: FieldDefinition) => {
|
|
510
|
+
if (!field.optionsSource) return false
|
|
511
|
+
// 简单检查,不考虑参数
|
|
512
|
+
for (const key of Object.keys(remoteOptionsLoading.value)) {
|
|
513
|
+
if (key.startsWith(field.optionsSource) && remoteOptionsLoading.value[key]) {
|
|
514
|
+
return true
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return false
|
|
518
|
+
}
|
|
519
|
+
|
|
400
520
|
// 方法
|
|
401
521
|
const getPhaseMiddlewares = (phaseId: string) => {
|
|
402
522
|
return allMiddlewares.value.filter(mw => mw.phase === phaseId)
|
|
@@ -183,7 +183,11 @@ const getFieldParams = (field: ConfigField): Record<string, any> | undefined =>
|
|
|
183
183
|
if (dependValue === undefined || dependValue === null || dependValue === '') {
|
|
184
184
|
return undefined
|
|
185
185
|
}
|
|
186
|
-
|
|
186
|
+
// 提取 dependsOn 的最后一段作为参数名(例如 'promptEnhance.platform' -> 'platform')
|
|
187
|
+
const paramName = field.dependsOn.includes('.')
|
|
188
|
+
? field.dependsOn.split('.').pop()!
|
|
189
|
+
: field.dependsOn
|
|
190
|
+
return { [paramName]: dependValue }
|
|
187
191
|
}
|
|
188
192
|
|
|
189
193
|
// 获取字段的缓存 key
|