feat: 添加 queryConfig 字段及相关配置功能
- 在 CreateModelParams 接口中新增 queryConfig 字段,支持更灵活的查询配置。 - 更新 ModelSelector 组件,优化模型选择界面,增强用户体验。 - 在 editModule.vue 中添加响应类型选择及主动拉取配置功能,提升配置灵活性与可用性。
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user