Files
EasyFlow/easyflow-ui-admin/app/src/views/config/settings/Settings.vue
陈子默 d244a0404d fix: 收口管理端页面权限与工作流运行授权
- 页面选项接口改用所属页面权限并返回最小数据视图

- 统一校验工作流引用、租户、状态与定时任务执行主体

- 补充聊天记录权限迁移和权限隔离回归测试
2026-08-07 12:51:21 +08:00

166 lines
4.1 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 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[]);
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();
});
const entity = ref<SettingsEntity>({
model_of_chat: '',
chatgpt_api_key: '',
chatgpt_chatPath: '',
chatgpt_endpoint: '',
chatgpt_model_name: '',
chat_publish_base_url: '',
});
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>