新增模型会话开关功能和Token映射字段
- 在模型模块中添加更新会话模型状态的API,支持会话模型的管理。 - 更新模型选择器,保存模型的表单数据和响应体,提升用户体验。 - 在编辑模块中新增Token映射字段,增强模型配置的灵活性。 - 优化会话模型开关的逻辑,确保状态切换后能正确更新列表数据。
This commit is contained in:
@@ -217,3 +217,14 @@ export function getModelModuleDetail(id: number | string) {
|
|||||||
// export function updateModelChatSessionSwitch(data: { id: number | string; chatSessionEnabled: 0 | 1 }) {
|
// export function updateModelChatSessionSwitch(data: { id: number | string; chatSessionEnabled: 0 | 1 }) {
|
||||||
// return request({ url: '/model-gateway/model/...', method: 'post', data });
|
// return request({ url: '/model-gateway/model/...', method: 'post', data });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新模型会话开关状态
|
||||||
|
*/
|
||||||
|
export function updateChatModel(data: { id: number | string; chatSessionEnabled: 0 | 1 }) {
|
||||||
|
return request({
|
||||||
|
url: '/model-gateway/model/updateChatModel',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -742,6 +742,7 @@ const workflowDsl = computed(() => ({
|
|||||||
inputSource: n.properties?.inputSource || null,
|
inputSource: n.properties?.inputSource || null,
|
||||||
formConfig: n.properties?.formConfig || null,
|
formConfig: n.properties?.formConfig || null,
|
||||||
modelConfig: n.properties?.modelConfig || null,
|
modelConfig: n.properties?.modelConfig || null,
|
||||||
|
modelResponse: n.properties?.modelResponse || null,
|
||||||
outputResult: null,
|
outputResult: null,
|
||||||
})),
|
})),
|
||||||
edges: flowDsl.value.edges.map((e) => ({
|
edges: flowDsl.value.edges.map((e) => ({
|
||||||
@@ -884,7 +885,12 @@ const handleRemoveSkill = () => {
|
|||||||
// 处理模型选择确认(只更新临时状态,不保存到节点)
|
// 处理模型选择确认(只更新临时状态,不保存到节点)
|
||||||
const handleModelConfirm = (model: any) => {
|
const handleModelConfirm = (model: any) => {
|
||||||
selectedModel.value = model.modelName;
|
selectedModel.value = model.modelName;
|
||||||
selectedModelData.value = model;
|
selectedModelData.value = {
|
||||||
|
...model,
|
||||||
|
// 保存模型的 form 和 responseBody,用于后续保存到节点
|
||||||
|
modelFormData: model.form || [],
|
||||||
|
responseBody: model.responseMapping || model.responseBody || {},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
// 移除已选择的模型(只更新临时状态)
|
// 移除已选择的模型(只更新临时状态)
|
||||||
const handleRemoveModel = () => {
|
const handleRemoveModel = () => {
|
||||||
@@ -1707,35 +1713,29 @@ const applySelected = () => {
|
|||||||
|
|
||||||
// 保存选中的模型和模型相关配置
|
// 保存选中的模型和模型相关配置
|
||||||
if (selectedModel.value) {
|
if (selectedModel.value) {
|
||||||
// 获取当前模型的表单字段
|
// 从 selectedModelData 中获取模型的 form 数据
|
||||||
const currentModelFields = currentModelForm.value;
|
const modelFormFromData = selectedModelData.value?.modelFormData || selectedModelData.value?.form || [];
|
||||||
const modelForm: Array<any> = [];
|
|
||||||
|
|
||||||
// 保存模型相关的字段配置和值
|
|
||||||
currentModelFields.forEach((fieldItem) => {
|
|
||||||
const value = dynamicFormValues[fieldItem.field];
|
|
||||||
modelForm.push({
|
|
||||||
type: fieldItem.type,
|
|
||||||
field: fieldItem.field,
|
|
||||||
label: fieldItem.label,
|
|
||||||
value: value !== undefined && value !== null ? value : fieldItem.default || '',
|
|
||||||
required: fieldItem.required || false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 保存到 modelConfig
|
// 保存到 modelConfig
|
||||||
p.modelConfig = {
|
p.modelConfig = {
|
||||||
modelName: selectedModel.value,
|
modelName: selectedModel.value,
|
||||||
modelApiKey: dynamicFormValues.modelApiKey || '',
|
modelApiKey: dynamicFormValues.modelApiKey || '',
|
||||||
modelForm: modelForm,
|
modelForm: modelFormFromData, // 使用模型列表数据里的 form
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 保存模型的 responseBody 到 modelResponse(与 modelConfig 平级)
|
||||||
|
const responseBody = selectedModelData.value?.responseBody || selectedModelData.value?.responseMapping || {};
|
||||||
|
if (Object.keys(responseBody).length > 0) {
|
||||||
|
p.modelResponse = responseBody;
|
||||||
|
}
|
||||||
|
|
||||||
// 保存模型选择状态
|
// 保存模型选择状态
|
||||||
p.selectedModel = selectedModel.value;
|
p.selectedModel = selectedModel.value;
|
||||||
p.modelData = selectedModelData.value;
|
p.modelData = selectedModelData.value;
|
||||||
} else {
|
} else {
|
||||||
// 如果没有选择模型,删除 modelConfig 和模型状态
|
// 如果没有选择模型,删除 modelConfig、modelResponse 和模型状态
|
||||||
delete p.modelConfig;
|
delete p.modelConfig;
|
||||||
|
delete p.modelResponse;
|
||||||
delete p.selectedModel;
|
delete p.selectedModel;
|
||||||
delete p.modelData;
|
delete p.modelData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,6 +145,11 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
|
<el-form-item label="Token映射" prop="tokenMapping">
|
||||||
|
<el-input v-model="state.ruleForm.tokenMapping" placeholder="请输入Token映射" clearable></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-collapse-transition>
|
</el-collapse-transition>
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -220,12 +225,7 @@
|
|||||||
<el-input v-model="field.key" placeholder="请输入字段名 (Key)" style="width: 30%" clearable></el-input>
|
<el-input v-model="field.key" placeholder="请输入字段名 (Key)" style="width: 30%" clearable></el-input>
|
||||||
<span class="separator">=</span>
|
<span class="separator">=</span>
|
||||||
<el-input v-model="field.value" placeholder="请输入字段值 (Value)" style="width: 30%" clearable></el-input>
|
<el-input v-model="field.value" placeholder="请输入字段值 (Value)" style="width: 30%" clearable></el-input>
|
||||||
<el-button
|
<el-button :type="field.isMainBody ? 'success' : 'primary'" :plain="!field.isMainBody" @click="setMainBody(index)" size="small">
|
||||||
:type="field.isMainBody ? 'success' : 'primary'"
|
|
||||||
:plain="!field.isMainBody"
|
|
||||||
@click="setMainBody(index)"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
{{ field.isMainBody ? '✓ 返回主体' : '设置返回主体' }}
|
{{ field.isMainBody ? '✓ 返回主体' : '设置返回主体' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="danger" link @click="removeResponseMappingField(index)">删除</el-button>
|
<el-button type="danger" link @click="removeResponseMappingField(index)">删除</el-button>
|
||||||
@@ -291,6 +291,7 @@ const state = reactive({
|
|||||||
retryQueueMaxSeconds: 60,
|
retryQueueMaxSeconds: 60,
|
||||||
autoCleanSeconds: 300,
|
autoCleanSeconds: 300,
|
||||||
remark: '',
|
remark: '',
|
||||||
|
tokenMapping: '',
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
modelName: [{ required: true, message: '请输入模型名称', trigger: 'blur' }],
|
modelName: [{ required: true, message: '请输入模型名称', trigger: 'blur' }],
|
||||||
@@ -490,7 +491,7 @@ const ensureKeyValueRows = (rows: Array<{ key: string; value: string }>) => (row
|
|||||||
|
|
||||||
const ensureResponseMappingRows = (rows: Array<{ key: string; value: string; isMainBody?: boolean }>) => {
|
const ensureResponseMappingRows = (rows: Array<{ key: string; value: string; isMainBody?: boolean }>) => {
|
||||||
if (!rows.length) return [{ key: '', value: '', isMainBody: false }];
|
if (!rows.length) return [{ key: '', value: '', isMainBody: false }];
|
||||||
return rows.map(row => ({ ...row, isMainBody: row.isMainBody || false }));
|
return rows.map((row) => ({ ...row, isMainBody: row.isMainBody || false }));
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 从 getModel 返回的 data 中取出单条模型对象 */
|
/** 从 getModel 返回的 data 中取出单条模型对象 */
|
||||||
@@ -539,6 +540,7 @@ const fillFormFromDetailRow = (row: Record<string, unknown>) => {
|
|||||||
retryQueueMaxSeconds: Number(row.retryQueueMaxSeconds ?? 60),
|
retryQueueMaxSeconds: Number(row.retryQueueMaxSeconds ?? 60),
|
||||||
autoCleanSeconds: Number(row.autoCleanSeconds ?? 300),
|
autoCleanSeconds: Number(row.autoCleanSeconds ?? 300),
|
||||||
remark: String(row.remark || ''),
|
remark: String(row.remark || ''),
|
||||||
|
tokenMapping: String(row.tokenMapping || ''),
|
||||||
};
|
};
|
||||||
state.headers = ensureKeyValueRows(parseHeaders(String(row.headMsg || '')));
|
state.headers = ensureKeyValueRows(parseHeaders(String(row.headMsg || '')));
|
||||||
state.formFields = ensureKeyValueRows(parseFormFields(row.form));
|
state.formFields = ensureKeyValueRows(parseFormFields(row.form));
|
||||||
@@ -550,7 +552,7 @@ const fillFormFromDetailRow = (row: Record<string, unknown>) => {
|
|||||||
if (row.responseBody && typeof row.responseBody === 'object') {
|
if (row.responseBody && typeof row.responseBody === 'object') {
|
||||||
const responseBodyKey = Object.keys(row.responseBody)[0];
|
const responseBodyKey = Object.keys(row.responseBody)[0];
|
||||||
if (responseBodyKey) {
|
if (responseBodyKey) {
|
||||||
const mainBodyIndex = state.responseMappingFields.findIndex(f => f.key === responseBodyKey);
|
const mainBodyIndex = state.responseMappingFields.findIndex((f) => f.key === responseBodyKey);
|
||||||
if (mainBodyIndex !== -1) {
|
if (mainBodyIndex !== -1) {
|
||||||
state.responseMappingFields[mainBodyIndex].isMainBody = true;
|
state.responseMappingFields[mainBodyIndex].isMainBody = true;
|
||||||
state.mainBodyIndex = mainBodyIndex;
|
state.mainBodyIndex = mainBodyIndex;
|
||||||
@@ -615,6 +617,7 @@ const openDialog = async (type: string, row?: Record<string, unknown>) => {
|
|||||||
retryQueueMaxSeconds: 60,
|
retryQueueMaxSeconds: 60,
|
||||||
autoCleanSeconds: 300,
|
autoCleanSeconds: 300,
|
||||||
remark: '',
|
remark: '',
|
||||||
|
tokenMapping: '',
|
||||||
};
|
};
|
||||||
state.headers = [{ key: '', value: '' }];
|
state.headers = [{ key: '', value: '' }];
|
||||||
state.formFields = [{ key: '', value: '' }];
|
state.formFields = [{ key: '', value: '' }];
|
||||||
@@ -648,7 +651,7 @@ const onSubmit = () => {
|
|||||||
const requestMapping = fieldsToObject(state.requestMappingFields);
|
const requestMapping = fieldsToObject(state.requestMappingFields);
|
||||||
const responseMapping = fieldsToObject(state.responseMappingFields);
|
const responseMapping = fieldsToObject(state.responseMappingFields);
|
||||||
// 获取被设置为返回主体的字段 {key: value}
|
// 获取被设置为返回主体的字段 {key: value}
|
||||||
const responseBodyField = state.responseMappingFields.find(f => f.isMainBody);
|
const responseBodyField = state.responseMappingFields.find((f) => f.isMainBody);
|
||||||
const responseBody = responseBodyField ? { [responseBodyField.key.trim()]: responseBodyField.value } : {};
|
const responseBody = responseBodyField ? { [responseBodyField.key.trim()]: responseBodyField.value } : {};
|
||||||
const submitData = {
|
const submitData = {
|
||||||
modelName: state.ruleForm.modelName,
|
modelName: state.ruleForm.modelName,
|
||||||
@@ -672,6 +675,7 @@ const onSubmit = () => {
|
|||||||
retryQueueMaxSeconds: state.ruleForm.retryQueueMaxSeconds,
|
retryQueueMaxSeconds: state.ruleForm.retryQueueMaxSeconds,
|
||||||
autoCleanSeconds: state.ruleForm.autoCleanSeconds,
|
autoCleanSeconds: state.ruleForm.autoCleanSeconds,
|
||||||
remark: state.ruleForm.remark || '',
|
remark: state.ruleForm.remark || '',
|
||||||
|
tokenMapping: state.ruleForm.tokenMapping || '',
|
||||||
};
|
};
|
||||||
|
|
||||||
if (state.dialog.type === 'edit') {
|
if (state.dialog.type === 'edit') {
|
||||||
@@ -743,50 +747,3 @@ defineExpose({
|
|||||||
color: #606266;
|
color: #606266;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,24 +32,14 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="httpMethod" label="请求方式" width="100"></el-table-column>
|
<el-table-column prop="httpMethod" label="请求方式" width="100"></el-table-column>
|
||||||
<el-table-column label="会话模型" width="100" align="center">
|
<el-table-column label="会话模型" width="110" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag :type="Number(row.isChatModel) === 1 ? 'success' : 'info'" size="small">
|
|
||||||
{{ Number(row.isChatModel) === 1 ? '是' : '否' }}
|
|
||||||
</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="会话开关" width="110" align="center">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<template v-if="Number(row.isChatModel) === 1">
|
|
||||||
<el-switch
|
<el-switch
|
||||||
size="small"
|
size="small"
|
||||||
:model-value="chatSessionSwitchOn(row)"
|
:model-value="Number(row.isChatModel) === 1"
|
||||||
:before-change="() => onChatSessionSwitchRequest(row)"
|
:before-change="() => onChatModelSwitchRequest(row)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<span v-else class="text-muted">—</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="enabled" label="状态" width="100">
|
<el-table-column prop="enabled" label="状态" width="100">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@@ -94,6 +84,7 @@ import {
|
|||||||
getModelTypeList,
|
getModelTypeList,
|
||||||
deleteModelModule,
|
deleteModelModule,
|
||||||
normalizeModelTypeOptions,
|
normalizeModelTypeOptions,
|
||||||
|
updateChatModel,
|
||||||
} from '/@/api/digitalHuman/modelConfig/modelModule/index';
|
} from '/@/api/digitalHuman/modelConfig/modelModule/index';
|
||||||
|
|
||||||
const EditModule = defineAsyncComponent(() => import('/@/views/digitalHuman/modelConfig/modelModule/component/editModule.vue'));
|
const EditModule = defineAsyncComponent(() => import('/@/views/digitalHuman/modelConfig/modelModule/component/editModule.vue'));
|
||||||
@@ -113,14 +104,22 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 列表行与会话开关接口约定字段 chatSessionEnabled(0/1);接口未就绪前占位 */
|
// 会话模型开关切换
|
||||||
const chatSessionSwitchOn = (row: { chatSessionEnabled?: number }) => Number(row.chatSessionEnabled) === 1;
|
const onChatModelSwitchRequest = async (row: { id?: number | string; isChatModel?: number }) => {
|
||||||
|
try {
|
||||||
const onChatSessionSwitchRequest = (_row: { id?: number | string }) => {
|
const newStatus = Number(row.isChatModel) === 1 ? 0 : 1;
|
||||||
return new Promise<boolean>((resolve) => {
|
await updateChatModel({
|
||||||
ElMessage.info('会话开关接口接入后即可生效');
|
id: row.id!,
|
||||||
resolve(false);
|
chatSessionEnabled: newStatus as 0 | 1,
|
||||||
});
|
});
|
||||||
|
ElMessage.success(newStatus === 1 ? '已设置为会话模型' : '已取消会话模型');
|
||||||
|
// 重新获取列表数据
|
||||||
|
await getTableData();
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
// 接口错误由 request 全局提示后端 message
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const resolveModelTypeLabel = (modelsType: number | string | undefined | null) => {
|
const resolveModelTypeLabel = (modelsType: number | string | undefined | null) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user