koishi-plugin-media-luna 0.0.30 → 0.0.32

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 (50) hide show
  1. package/client/components/ConfigRenderer.vue +119 -1
  2. package/dist/index.js +2 -2
  3. package/dist/style.css +1 -1
  4. package/lib/core/api/setup-api.d.ts.map +1 -1
  5. package/lib/core/api/setup-api.js +22 -0
  6. package/lib/core/api/setup-api.js.map +1 -1
  7. package/lib/core/medialuna.service.d.ts +20 -0
  8. package/lib/core/medialuna.service.d.ts.map +1 -1
  9. package/lib/core/medialuna.service.js +58 -8
  10. package/lib/core/medialuna.service.js.map +1 -1
  11. package/lib/core/plugin-loader.d.ts +5 -1
  12. package/lib/core/plugin-loader.d.ts.map +1 -1
  13. package/lib/core/plugin-loader.js +49 -2
  14. package/lib/core/plugin-loader.js.map +1 -1
  15. package/lib/core/types.d.ts +2 -0
  16. package/lib/core/types.d.ts.map +1 -1
  17. package/lib/core/types.js.map +1 -1
  18. package/lib/index.d.ts.map +1 -1
  19. package/lib/index.js +17 -5
  20. package/lib/index.js.map +1 -1
  21. package/lib/plugins/connector-chatluna/api.d.ts +6 -0
  22. package/lib/plugins/connector-chatluna/api.d.ts.map +1 -0
  23. package/lib/plugins/connector-chatluna/api.js +161 -0
  24. package/lib/plugins/connector-chatluna/api.js.map +1 -0
  25. package/lib/plugins/connector-chatluna/config.d.ts +41 -0
  26. package/lib/plugins/connector-chatluna/config.d.ts.map +1 -0
  27. package/lib/plugins/connector-chatluna/config.js +142 -0
  28. package/lib/plugins/connector-chatluna/config.js.map +1 -0
  29. package/lib/plugins/connector-chatluna/connector.d.ts +4 -0
  30. package/lib/plugins/connector-chatluna/connector.d.ts.map +1 -0
  31. package/lib/plugins/connector-chatluna/connector.js +114 -0
  32. package/lib/plugins/connector-chatluna/connector.js.map +1 -0
  33. package/lib/plugins/connector-chatluna/index.d.ts +5 -0
  34. package/lib/plugins/connector-chatluna/index.d.ts.map +1 -0
  35. package/lib/plugins/connector-chatluna/index.js +53 -0
  36. package/lib/plugins/connector-chatluna/index.js.map +1 -0
  37. package/lib/plugins/connector-chatluna/tools.d.ts +11 -0
  38. package/lib/plugins/connector-chatluna/tools.d.ts.map +1 -0
  39. package/lib/plugins/connector-chatluna/tools.js +353 -0
  40. package/lib/plugins/connector-chatluna/tools.js.map +1 -0
  41. package/lib/plugins/index.d.ts +3 -1
  42. package/lib/plugins/index.d.ts.map +1 -1
  43. package/lib/plugins/index.js +5 -2
  44. package/lib/plugins/index.js.map +1 -1
  45. package/lib/plugins/koishi-commands/index.d.ts.map +1 -1
  46. package/lib/plugins/koishi-commands/index.js +202 -234
  47. package/lib/plugins/koishi-commands/index.js.map +1 -1
  48. package/lib/types/index.d.ts +2 -0
  49. package/lib/types/index.d.ts.map +1 -1
  50. package/package.json +1 -1
@@ -32,6 +32,26 @@
32
32
  </el-select>
33
33
  </template>
34
34
 
35
+ <!-- Select Remote 类型(远程获取选项) -->
36
+ <template v-else-if="field.type === 'select-remote'">
37
+ <el-select
38
+ :model-value="getFieldValue(field.key)"
39
+ @update:model-value="setFieldValue(field.key, $event)"
40
+ :placeholder="field.placeholder || '请选择'"
41
+ :clearable="clearable"
42
+ :loading="isRemoteLoading(field)"
43
+ filterable
44
+ style="width: 100%"
45
+ >
46
+ <el-option
47
+ v-for="opt in getRemoteOptions(field)"
48
+ :key="String(opt.value)"
49
+ :label="opt.label"
50
+ :value="opt.value"
51
+ />
52
+ </el-select>
53
+ </template>
54
+
35
55
  <!-- Number 类型 -->
36
56
  <template v-else-if="field.type === 'number'">
37
57
  <el-input-number
@@ -94,9 +114,10 @@
94
114
  </template>
95
115
 
96
116
  <script setup lang="ts">
97
- import { computed, inject } from 'vue'
117
+ import { computed, inject, ref, watch, onMounted } from 'vue'
98
118
  import type { ConfigField, TableColumnDefinition } from '../types'
99
119
  import TableFieldEditor from './TableFieldEditor.vue'
120
+ import { send } from '@koishijs/client'
100
121
 
101
122
  interface Props {
102
123
  /** 配置字段定义 */
@@ -118,6 +139,103 @@ const emit = defineEmits<{
118
139
  'update:modelValue': [value: Record<string, any>]
119
140
  }>()
120
141
 
142
+ // ============ 远程选项缓存 ============
143
+ const remoteOptionsCache = ref<Record<string, { label: string; value: any }[]>>({})
144
+ const remoteOptionsLoading = ref<Record<string, boolean>>({})
145
+
146
+ // 构建带参数的缓存 key
147
+ const buildCacheKey = (source: string, params?: Record<string, any>) => {
148
+ if (!params || Object.keys(params).length === 0) {
149
+ return source
150
+ }
151
+ const sortedParams = Object.keys(params).sort().map(k => `${k}=${params[k]}`).join('&')
152
+ return `${source}?${sortedParams}`
153
+ }
154
+
155
+ // 获取远程选项(支持带参数)
156
+ const fetchRemoteOptions = async (source: string, params?: Record<string, any>) => {
157
+ const cacheKey = buildCacheKey(source, params)
158
+
159
+ if (remoteOptionsCache.value[cacheKey] || remoteOptionsLoading.value[cacheKey]) {
160
+ return
161
+ }
162
+
163
+ remoteOptionsLoading.value[cacheKey] = true
164
+ try {
165
+ const result = await send(source, params)
166
+ if (result?.success && Array.isArray(result.data)) {
167
+ remoteOptionsCache.value[cacheKey] = result.data
168
+ } else {
169
+ remoteOptionsCache.value[cacheKey] = []
170
+ }
171
+ } catch (e) {
172
+ console.error(`Failed to fetch options from ${source}:`, e)
173
+ remoteOptionsCache.value[cacheKey] = []
174
+ } finally {
175
+ remoteOptionsLoading.value[cacheKey] = false
176
+ }
177
+ }
178
+
179
+ // 获取字段的参数(基于 dependsOn)
180
+ const getFieldParams = (field: ConfigField): Record<string, any> | undefined => {
181
+ if (!field.dependsOn) return undefined
182
+ const dependValue = props.modelValue[field.dependsOn]
183
+ if (dependValue === undefined || dependValue === null || dependValue === '') {
184
+ return undefined
185
+ }
186
+ return { [field.dependsOn]: dependValue }
187
+ }
188
+
189
+ // 获取字段的缓存 key
190
+ const getFieldCacheKey = (field: ConfigField): string => {
191
+ if (!field.optionsSource) return ''
192
+ const params = getFieldParams(field)
193
+ return buildCacheKey(field.optionsSource, params)
194
+ }
195
+
196
+ // 获取远程选项(同步访问缓存)
197
+ const getRemoteOptions = (field: ConfigField) => {
198
+ const cacheKey = getFieldCacheKey(field)
199
+ if (!cacheKey) return []
200
+ return remoteOptionsCache.value[cacheKey] || []
201
+ }
202
+
203
+ // 检查是否正在加载
204
+ const isRemoteLoading = (field: ConfigField) => {
205
+ const cacheKey = getFieldCacheKey(field)
206
+ if (!cacheKey) return false
207
+ return remoteOptionsLoading.value[cacheKey] || false
208
+ }
209
+
210
+ // 加载字段的远程选项
211
+ const loadFieldOptions = (field: ConfigField) => {
212
+ if (field.type !== 'select-remote' || !field.optionsSource) return
213
+ const params = getFieldParams(field)
214
+ fetchRemoteOptions(field.optionsSource, params)
215
+ }
216
+
217
+ // 在组件挂载时预加载所有远程选项
218
+ onMounted(() => {
219
+ for (const field of props.fields) {
220
+ loadFieldOptions(field)
221
+ }
222
+ })
223
+
224
+ // 监听依赖字段变化,重新加载选项
225
+ watch(() => props.modelValue, (newVal, oldVal) => {
226
+ for (const field of props.fields) {
227
+ if (field.type === 'select-remote' && field.dependsOn && field.optionsSource) {
228
+ const newDependValue = newVal[field.dependsOn]
229
+ const oldDependValue = oldVal?.[field.dependsOn]
230
+
231
+ if (newDependValue !== oldDependValue) {
232
+ // 依赖字段变化,重新加载选项
233
+ loadFieldOptions(field)
234
+ }
235
+ }
236
+ }
237
+ }, { deep: true })
238
+
121
239
  // 获取字段值
122
240
  const getFieldValue = (key: string) => {
123
241
  return props.modelValue[key]