Files
EasyFlow/easyflow-ui-admin/app/src/views/config/settings/Settings.vue
陈子默 7e7c236c2a fix: 修复管理端前端 lint 与构建问题
- 收敛 easyflow-ui-admin 的 lint、格式和类型问题

- 修正 demo 页面与管理端前端构建失败点

- 验证 pnpm lint 与 pnpm build 均已通过
2026-04-05 21:39:13 +08:00

204 lines
4.9 KiB
Vue

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { $t } from '@easyflow/locales';
import {
ElAlert,
ElButton,
ElForm,
ElFormItem,
ElInput,
ElMessage,
ElOption,
ElSelect,
} from 'element-plus';
import { api } from '#/api/request.js';
import providerList from '#/views/ai/model/modelUtils/providerList.json';
interface ProviderOptionExtra {
chatPath?: string;
llmEndpoint?: string;
}
interface ProviderOption {
label: string;
options?: ProviderOptionExtra;
value: string;
}
interface ModelProvider {
key: string;
options?: ProviderOptionExtra;
title: string;
}
interface LlmOption {
extra: Map<string, string | undefined>;
label: string;
value: string;
}
interface SettingsEntity {
chatgpt_api_key: string;
chatgpt_chatPath: string;
chatgpt_endpoint: string;
chatgpt_model_name: string;
chat_publish_base_url: string;
model_of_chat: string;
}
const providerOptions = ref<ProviderOption[]>(providerList as ProviderOption[]);
const brands = ref<ModelProvider[]>([]);
const llmOptions = ref<LlmOption[]>([]);
// 获取品牌接口数据
function getBrands() {
api.get('/api/v1/modelProvider/list').then((res) => {
if (res.errorCode === 0) {
brands.value = (res.data ?? []) as ModelProvider[];
llmOptions.value = formatLlmList(brands.value);
}
});
}
function getOptions() {
api
.get(
'/api/v1/sysOption/list?keys=model_of_chat&keys=chatgpt_endpoint&keys=chatgpt_chatPath&keys=chatgpt_api_key&keys=chatgpt_model_name&keys=chat_publish_base_url',
)
.then((res) => {
if (res.errorCode === 0) {
entity.value = {
...entity.value,
...res.data,
};
}
});
}
onMounted(() => {
getOptions();
getBrands();
});
const entity = ref<SettingsEntity>({
model_of_chat: '',
chatgpt_api_key: '',
chatgpt_chatPath: '',
chatgpt_endpoint: '',
chatgpt_model_name: '',
chat_publish_base_url: '',
});
function formatLlmList(data: ModelProvider[]): LlmOption[] {
return data.map((item) => {
const extra = new Map([
['chatPath', item.options?.chatPath],
['llmEndpoint', item.options?.llmEndpoint],
]);
return {
label: item.title,
value: item.key,
extra,
};
});
}
function handleChangeModel(value: string) {
const extra = providerList.find((item) => item.value === value);
entity.value.chatgpt_chatPath = extra?.options?.chatPath ?? '';
entity.value.chatgpt_endpoint = extra?.options?.llmEndpoint ?? '';
}
function handleSave() {
api.post('/api/v1/sysOption/save', entity.value).then((res) => {
if (res.errorCode === 0) {
ElMessage.success($t('message.saveOkMessage'));
}
});
}
</script>
<template>
<div class="settings-container">
<div class="settings-config-container border-border border">
<div class="mb-6">
{{ $t('settingsConfig.systemAIFunctionSettings') }}
</div>
<ElAlert
class="!mb-5"
:title="$t('settingsConfig.note')"
type="warning"
/>
<ElForm :model="entity" class="demo-form-inline" label-width="150px">
<ElFormItem :label="$t('settingsConfig.modelOfChat')">
<ElSelect
v-model="entity.model_of_chat"
clearable
@change="handleChangeModel"
>
<ElOption
v-for="item in providerOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</ElSelect>
</ElFormItem>
<ElFormItem :label="$t('settingsConfig.modelName')">
<ElInput v-model="entity.chatgpt_model_name" clearable />
</ElFormItem>
<ElFormItem label="Endpoint">
<ElInput v-model="entity.chatgpt_endpoint" clearable />
</ElFormItem>
<ElFormItem label="ChatPath">
<ElInput v-model="entity.chatgpt_chatPath" clearable />
</ElFormItem>
<ElFormItem label="ApiKey">
<ElInput v-model="entity.chatgpt_api_key" clearable />
</ElFormItem>
<ElFormItem :label="$t('settingsConfig.chatPublishBaseUrl')">
<ElInput
v-model="entity.chat_publish_base_url"
clearable
:placeholder="$t('settingsConfig.chatPublishBaseUrlPlaceholder')"
/>
</ElFormItem>
</ElForm>
<div class="settings-button-container">
<ElButton type="primary" @click="handleSave">
{{ $t('button.save') }}
</ElButton>
</div>
</div>
</div>
</template>
<style scoped>
.settings-container {
display: flex;
flex-direction: column;
height: 100%;
padding: 30px 143px;
}
.settings-config-container {
width: 100%;
padding: 20px;
background-color: var(--el-bg-color);
border-radius: 10px;
}
:deep(.el-form-item) {
margin-bottom: 25px;
}
.settings-notice {
margin-bottom: 20px;
color: var(--el-color-danger);
}
.settings-button-container {
display: flex;
justify-content: flex-end;
}
</style>