更新模型选择和设置功能

- 修改模型选择器,调整内置模型的标识逻辑,使用 `isOwner` 属性替代 `apiKey` 判断。
- 新增内置模型 API Key 输入弹窗,支持用户为内置模型配置 API Key 并创建模型副本。
- 更新模型配置页面,优化内置模型的 API Key 配置逻辑,确保用户体验流畅。
This commit is contained in:
2026-05-14 11:36:41 +08:00
parent 812b11bb68
commit caa5cc71c7
4 changed files with 176 additions and 63 deletions

View File

@@ -19,13 +19,13 @@
v-for="model in modelList"
:key="model.id"
class="model-card"
:class="{ selected: selectedModel?.id === model.id, 'builtin-model': !model.apiKey }"
:class="{ selected: selectedModel?.id === model.id }"
@click="handleSelectModel(model)"
>
<div class="model-card-header">
<div class="model-type">{{ getModelTypeName(model.modelType) }}</div>
<div class="model-badges">
<el-tag v-if="!model.apiKey" type="warning" size="small">内置模型</el-tag>
<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>
</div>
</div>
@@ -165,7 +165,7 @@ const apiKeyRules: FormRules = {
apiKey: [{ required: true, message: '请输入 API Key', trigger: 'blur' }],
};
const creatingModel = ref(false);
const systemModelToClone = ref<ModelItem | null>(null);
const builtInModelToClone = ref<ModelItem | null>(null);
// 检查是否为管理员
const checkAdminStatus = async () => {
@@ -240,10 +240,10 @@ const handleSelectModel = (model: ModelItem) => {
return;
}
// 非管理员:判断是否是内置模型(apiKey 为空
if (!model.apiKey) {
// 内置模型,需要用户配置 API Key
systemModelToClone.value = model;
// 非管理员:判断是否是内置模型(isOwner === 0 表示管理员创建的内置模型
if (model.isOwner === 0) {
// 内置模型,需要用户配置 API Key 创建副本
builtInModelToClone.value = model;
apiKeyForm.modelName = model.modelName;
apiKeyForm.apiKey = '';
apiKeyDialogVisible.value = true;
@@ -254,7 +254,7 @@ const handleSelectModel = (model: ModelItem) => {
};
const handleCreatePrivateModel = async () => {
if (!apiKeyFormRef.value || !systemModelToClone.value) return;
if (!apiKeyFormRef.value || !builtInModelToClone.value) return;
try {
await apiKeyFormRef.value.validate();
@@ -262,30 +262,30 @@ const handleCreatePrivateModel = async () => {
creatingModel.value = true;
// 基于内置模型创建新模型(继承原模型的所有配置,只替换 apiKey
const systemModel = systemModelToClone.value;
const builtInModel = builtInModelToClone.value;
const createParams = {
modelName: apiKeyForm.modelName,
modelType: systemModel.modelType,
baseUrl: systemModel.baseUrl,
httpMethod: systemModel.httpMethod || 'POST',
headMsg: systemModel.headMsg || '',
isPrivate: systemModel.isPrivate ?? 1, // 继承原模型的公有/私有属性
enabled: systemModel.enabled ?? 1,
isChatModel: systemModel.isChatModel || 0,
modelType: builtInModel.modelType,
baseUrl: builtInModel.baseUrl,
httpMethod: builtInModel.httpMethod || 'POST',
headMsg: builtInModel.headMsg || '',
isPrivate: builtInModel.isPrivate ?? 1, // 继承原模型的公有/私有属性
enabled: builtInModel.enabled ?? 1,
isChatModel: builtInModel.isChatModel || 0,
apiKey: apiKeyForm.apiKey, // 使用用户输入的新 API Key
form: systemModel.form || {},
requestMapping: systemModel.requestMapping || {},
responseMapping: systemModel.responseMapping || {},
responseBody: systemModel.responseBody || {}, // 杩斿洖涓讳綋瀛楁
maxConcurrency: systemModel.maxConcurrency || 10,
queueLimit: systemModel.queueLimit || 100,
timeoutSeconds: systemModel.timeoutSeconds || 30,
expectedSeconds: systemModel.expectedSeconds || 15,
retryTimes: systemModel.retryTimes || 3,
retryQueueMaxSeconds: systemModel.retryQueueMaxSeconds || 60,
autoCleanSeconds: systemModel.autoCleanSeconds || 300,
remark: systemModel.remark || '',
tokenMapping: systemModel.tokenMapping || '', // Token鏄犲皠瀛楁
form: builtInModel.form || {},
requestMapping: builtInModel.requestMapping || {},
responseMapping: builtInModel.responseMapping || {},
responseBody: builtInModel.responseBody || {}, // 杩斿洖涓讳綋瀛楁
maxConcurrency: builtInModel.maxConcurrency || 10,
queueLimit: builtInModel.queueLimit || 100,
timeoutSeconds: builtInModel.timeoutSeconds || 30,
expectedSeconds: builtInModel.expectedSeconds || 15,
retryTimes: builtInModel.retryTimes || 3,
retryQueueMaxSeconds: builtInModel.retryQueueMaxSeconds || 60,
autoCleanSeconds: builtInModel.autoCleanSeconds || 300,
remark: builtInModel.remark || '',
tokenMapping: builtInModel.tokenMapping || '', // Token鏄犲皠瀛楁
};
const res: any = await addModelModule(createParams);
@@ -334,7 +334,7 @@ const handleClose = () => {
visible.value = false;
selectedModel.value = null;
apiKeyDialogVisible.value = false;
systemModelToClone.value = null;
builtInModelToClone.value = null;
};
// 鍔犺浇妯″瀷绫诲瀷鍒楄〃