feat: 添加 queryConfig 字段及相关配置功能

- 在 CreateModelParams 接口中新增 queryConfig 字段,支持更灵活的查询配置。
- 更新 ModelSelector 组件,优化模型选择界面,增强用户体验。
- 在 editModule.vue 中添加响应类型选择及主动拉取配置功能,提升配置灵活性与可用性。
This commit is contained in:
2026-05-23 17:56:52 +08:00
parent 7c60e34de0
commit 27de8213f2
3 changed files with 470 additions and 70 deletions

View File

@@ -4,7 +4,7 @@
<div class="search-bar">
<el-input v-model="searchParams.modelName" placeholder="搜索模型名称" clearable @clear="handleSearch">
<template #prefix
><el-icon><Search /></el-icon
><el-icon> <Search /> </el-icon
></template>
</el-input>
<el-button type="primary" @click="handleSearch">搜索</el-button>
@@ -26,7 +26,9 @@
<div class="model-type">{{ getModelTypeName(model.modelType) }}</div>
<div class="model-badges">
<el-tag v-if="model.isOwner === 0" type="warning" size="small">内置模型</el-tag>
<el-icon v-if="selectedModel?.id === model.id" class="check-icon" color="#67c23a"><CircleCheck /></el-icon>
<el-icon v-if="selectedModel?.id === model.id" class="check-icon" color="#67c23a">
<CircleCheck />
</el-icon>
</div>
</div>
<div class="model-card-body">
@@ -121,6 +123,7 @@ interface ModelItem {
responseBody?: Record<string, unknown>;
tokenConfig?: Record<string, unknown> | string;
extendMapping?: Record<string, unknown> | string;
queryConfig?: Record<string, unknown>;
form?: ModelFormEntry[] | Record<string, unknown>;
requestMapping?: Record<string, unknown>;
responseMapping?: Record<string, unknown>;
@@ -239,6 +242,85 @@ const parseJsonObjectField = (raw: unknown): Record<string, unknown> => {
}
return {};
};
const fieldsToUnknownObject = (fields: Array<{ key: string; value: string }>) => {
const obj: Record<string, unknown> = {};
fields.forEach((f) => {
const k = String(f.key || '').trim();
if (!k) return;
obj[k] = String(f.value ?? '');
});
return obj;
};
const flattenNestedObject = (obj: Record<string, unknown>, prefix = ''): Array<{ key: string; value: string }> => {
const rows: Array<{ key: string; value: string }> = [];
Object.entries(obj || {}).forEach(([k, v]) => {
const fk = prefix ? `${prefix}.${k}` : k;
if (v && typeof v === 'object' && !Array.isArray(v)) {
rows.push(...flattenNestedObject(v as Record<string, unknown>, fk));
return;
}
rows.push({ key: fk, value: String(v ?? '') });
});
return rows;
};
const nestFieldsToObject = (fields: Array<{ key: string; value: string }>) => {
const root: Record<string, unknown> = {};
fields.forEach((f) => {
const path = String(f.key || '').trim();
if (!path) return;
const parts = path
.split('.')
.map((p) => p.trim())
.filter(Boolean);
if (!parts.length) return;
let cur: Record<string, unknown> = root;
parts.forEach((part, idx) => {
if (idx === parts.length - 1) {
cur[part] = String(f.value ?? '');
return;
}
if (!cur[part] || typeof cur[part] !== 'object' || Array.isArray(cur[part])) {
cur[part] = {};
}
cur = cur[part] as Record<string, unknown>;
});
});
return root;
};
const buildQueryConfigFromRaw = (rawQc: Record<string, unknown> | null): Record<string, unknown> => {
if (!rawQc) return { responseType: 'sync', callbackUrl: '' };
const rt = String(rawQc.responseType || 'sync');
if (rt === 'callback') return { responseType: 'callback', callbackUrl: String(rawQc.callbackUrl || '') };
if (rt === 'pull') {
const hFields = Object.entries((rawQc.headers as Record<string, unknown>) || {}).map(([k, v]) => ({ key: k, value: String(v ?? '') }));
const bFields = flattenNestedObject((rawQc.body as Record<string, unknown>) || {});
return {
responseType: 'pull',
callbackUrl: '',
method: String(rawQc.method || 'GET'),
url: String(rawQc.url || ''),
headers: fieldsToUnknownObject(hFields),
body: nestFieldsToObject(bFields),
response: ((rawQc.response as unknown[]) || [])
.map((item) => {
if (typeof item === 'string') {
return { value: item, isTokenField: false, isMainBody: false };
}
const row = item as Record<string, unknown>;
return {
value: String(row.value ?? ''),
isTokenField: Boolean(row.isTokenField),
isMainBody: Boolean(row.isMainBody),
};
})
.filter((row) => row.value !== ''),
};
}
return { responseType: 'sync', callbackUrl: '' };
};
const fetchModelList = async () => {
loading.value = true;
@@ -325,8 +407,17 @@ const handleCreatePrivateModel = async () => {
autoCleanSeconds: builtInModel.autoCleanSeconds || 300,
remark: builtInModel.remark || '',
extendMapping: parseJsonObjectField(builtInModel.extendMapping),
tokenConfig: parseJsonObjectField(builtInModel.tokenConfig),
extendMapping: fieldsToUnknownObject(
Object.entries(parseJsonObjectField(builtInModel.extendMapping)).map(([k, v]) => ({ key: k, value: String(v ?? '') }))
),
tokenConfig: fieldsToUnknownObject(
Object.entries(parseJsonObjectField(builtInModel.tokenConfig)).map(([k, v]) => ({ key: k, value: String(v ?? '') }))
),
queryConfig: buildQueryConfigFromRaw(
builtInModel.queryConfig && typeof builtInModel.queryConfig === 'object' && !Array.isArray(builtInModel.queryConfig)
? (builtInModel.queryConfig as Record<string, unknown>)
: null
),
};
const res: any = await addModelModule(createParams);