150 lines
4.0 KiB
Vue
150 lines
4.0 KiB
Vue
|
||
<script lang="ts" setup>
|
||
import {Table} from '@/components/Table';
|
||
import {Delete, Edit, Plus} from '@element-plus/icons-vue';
|
||
import editCom from './edit.vue';
|
||
import {computed, h, nextTick, reactive, ref, watch, onMounted} from 'vue';
|
||
import {getColumns} from './composables/columns';
|
||
import {LLMProviders, ModelTypeEnum} from './composables/consts';
|
||
import {ModelApi} from '@/api/new-ai/model';
|
||
import {ElMessage, ElMessageBox} from 'element-plus';
|
||
import {getModels, ProviderEnum} from './composables/provider';
|
||
|
||
const formData = ref({
|
||
provider: ProviderEnum.OPENAI
|
||
});
|
||
const message = ElMessage;
|
||
const dialog = ElMessageBox;
|
||
const actionRef = ref();
|
||
const editRef = ref();
|
||
const tableData = ref([]);
|
||
const loading = ref(false);
|
||
// 获取模型列表
|
||
const loadData = async () => {
|
||
loading.value = true;
|
||
try {
|
||
const res = await ModelApi.getModelList({
|
||
provider: formData.value.provider,
|
||
type: ModelTypeEnum.CHAT
|
||
}).finally(() => {
|
||
loading.value = false;
|
||
});
|
||
console.log(res)
|
||
tableData.value = res;
|
||
} catch (error) {
|
||
console.error('Failed to load models:', error);
|
||
message.error('获取模型列表失败');
|
||
}
|
||
};
|
||
|
||
// 监听 provider 变化重新加载数据
|
||
watch(() => formData.value.provider, () => {
|
||
loadData();
|
||
});
|
||
|
||
// 初始加载
|
||
onMounted(() => {
|
||
loadData();
|
||
});
|
||
|
||
const columns = computed(() => {
|
||
nextTick();
|
||
return getColumns(formData.value.provider);
|
||
});
|
||
|
||
async function addModel() {
|
||
console.log(formData.value.provider);
|
||
editRef.value.show({provider: formData.value.provider, type: ModelTypeEnum.CHAT });
|
||
}
|
||
|
||
function handleEdit(record: any) {
|
||
editRef.value.show(record);
|
||
}
|
||
|
||
async function reloadTable() {
|
||
await loadData();
|
||
}
|
||
|
||
async function handleDel(record: any) {
|
||
dialog.confirm('确定要删除该模型吗?', '警告', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
}).then(async () => {
|
||
try {
|
||
await ModelApi.deleteModel(record.id);
|
||
await reloadTable();
|
||
message.success('模型删除成功');
|
||
} catch (error) {
|
||
console.error('Failed to delete model:', error);
|
||
message.error('删除模型失败');
|
||
}
|
||
}).catch(() => {
|
||
});
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<ContentWrap>
|
||
<div class="flex children">
|
||
<el-scrollbar class="h-full w-300px pl-10px pr-20px">
|
||
<div
|
||
v-for="(item,index) in LLMProviders" :key="index"
|
||
:class="{active: formData.provider === item.model}" class="menu"
|
||
@click="formData.provider = item.model">
|
||
<span>{{ item.name }}</span>
|
||
</div>
|
||
</el-scrollbar>
|
||
<div class="h-full flex-1 px-20px" >
|
||
<el-alert
|
||
class="w-full mb-10px min-alert"
|
||
title="对于完全适配OpenAI接口格式的模型都可在OpenAI中配置(只需要定义BaseUrl)"
|
||
type="warning"
|
||
show-icon
|
||
/>
|
||
<el-button :icon="Plus" class="my-10px" type="primary" @click="addModel">新增模型</el-button>
|
||
<Table :loading="loading" class="table-wrapper" height="100%" border :columns="columns" :data="tableData" >
|
||
<template #action="{row}">
|
||
<el-button text :icon="Edit" @click="handleEdit(row)"/>
|
||
<el-button text :icon="Delete" type="danger" @click="handleDel(row)"/>
|
||
</template>
|
||
</Table>
|
||
<editCom ref="editRef" @reload="reloadTable"/>
|
||
</div>
|
||
</div>
|
||
</ContentWrap>
|
||
</template>
|
||
|
||
<style lang="scss" scoped>
|
||
.children {
|
||
height: calc(100vh - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height) - (var(--app-content-padding) * 3)) !important;
|
||
box-sizing: border-box;
|
||
|
||
& > div:nth-child(2) {
|
||
width: calc(100% - 300px);
|
||
}
|
||
}
|
||
|
||
.table-wrapper {
|
||
height: calc(100% - 100px);
|
||
}
|
||
|
||
.menu {
|
||
transition: all .15s;
|
||
cursor: pointer;
|
||
padding: 12px 10px;
|
||
border-radius: 5px;
|
||
margin-bottom: 20px;
|
||
&.active {
|
||
color: #ffffff;
|
||
background-color: var(--el-color-primary);
|
||
}
|
||
|
||
&:hover {
|
||
&:not(&.active) {
|
||
background-color: var(--el-color-info-light-7);
|
||
}
|
||
}
|
||
}
|
||
</style>
|