perf: 卡片入口视觉效果重做

This commit is contained in:
2026-03-11 20:30:36 +08:00
parent 0a8a7c8046
commit 219fa566ef
6 changed files with 507 additions and 259 deletions

View File

@@ -1,11 +1,5 @@
<script setup lang="ts">
import type { FormInstance } from 'element-plus';
import { onMounted, ref } from 'vue';
import { EasyFlowFormModal } from '@easyflow/common-ui';
import { Plus, Remove } from '@element-plus/icons-vue';
import type {FormInstance} from 'element-plus';
import {
ElForm,
ElFormItem,
@@ -18,13 +12,20 @@ import {
ElSelect,
} from 'element-plus';
import { api } from '#/api/request';
import {onMounted, ref} from 'vue';
import {EasyFlowFormModal} from '@easyflow/common-ui';
import {Plus, Remove} from '@element-plus/icons-vue';
import {api} from '#/api/request';
import UploadAvatar from '#/components/upload/UploadAvatar.vue';
import { $t } from '#/locales';
import {$t} from '#/locales';
const emit = defineEmits(['reload']);
const embeddingLlmList = ref<any>([]);
const rerankerLlmList = ref<any>([]);
const categoryList = ref<any[]>([]);
interface headersType {
label: string;
value: string;
@@ -46,6 +47,11 @@ onMounted(() => {
api.get('/api/v1/model/list?supportRerankerLlmList=true').then((res) => {
rerankerLlmList.value = res.data;
});
api.get('/api/v1/pluginCategory/list').then((res) => {
if (res.errorCode === 0) {
categoryList.value = res.data;
}
});
});
defineExpose({
openDialog,
@@ -57,6 +63,7 @@ const isAdd = ref(true);
const tempAddHeaders = ref<headersType[]>([]);
const entity = ref<any>({
alias: '',
categoryIds: [],
deptId: '',
icon: '',
title: '',
@@ -91,6 +98,7 @@ const rules = ref({
// functions
function openDialog(row: any) {
tempAddHeaders.value = [];
if (row.id) {
isAdd.value = false;
if (row.headers) {
@@ -100,26 +108,62 @@ function openDialog(row: any) {
entity.value = {
...row,
authType: row.authType || 'none',
categoryIds: row.categoryIds?.map((item: any) => item.id) || [],
};
dialogVisible.value = true;
}
async function syncPluginCategories(pluginId: string, categoryIds: string[]) {
if (!pluginId) {
return;
}
const relationRes = await api.post(
'/api/v1/pluginCategoryMapping/updateRelation',
{
pluginId,
categoryIds,
},
);
if (relationRes.errorCode !== 0) {
throw new Error(relationRes.message || 'sync categories failed');
}
}
function save() {
saveForm.value?.validate((valid) => {
if (valid) {
btnLoading.value = true;
const plainEntity = { ...entity.value };
const plainHeaders = [...tempAddHeaders.value];
const categoryIds = [...(plainEntity.categoryIds || [])];
delete plainEntity.categoryIds;
if (isAdd.value) {
api
.post('/api/v1/plugin/plugin/save', {
...plainEntity,
headers: plainHeaders,
})
.then((res) => {
.then(async (res) => {
if (res.errorCode === 0) {
const pluginId =
res.data?.id ||
res.data ||
plainEntity.id ||
entity.value.id ||
'';
await syncPluginCategories(pluginId, categoryIds);
dialogVisible.value = false;
ElMessage.success($t('message.saveOkMessage'));
emit('reload');
} else {
ElMessage.error(res.message);
}
})
.catch((error) => {
ElMessage.error(error?.message || $t('message.saveFailMessage'));
})
.finally(() => {
btnLoading.value = false;
});
} else {
api
@@ -127,12 +171,21 @@ function save() {
...plainEntity,
headers: plainHeaders,
})
.then((res) => {
.then(async (res) => {
if (res.errorCode === 0) {
await syncPluginCategories(entity.value.id, categoryIds);
dialogVisible.value = false;
ElMessage.success($t('message.updateOkMessage'));
emit('reload');
} else {
ElMessage.error(res.message);
}
})
.catch((error) => {
ElMessage.error(error?.message || $t('message.saveFailMessage'));
})
.finally(() => {
btnLoading.value = false;
});
}
}
@@ -141,6 +194,7 @@ function save() {
function closeDialog() {
saveForm.value?.resetFields();
isAdd.value = true;
tempAddHeaders.value = [];
entity.value = {};
dialogVisible.value = false;
}
@@ -199,6 +253,22 @@ function removeHeader(index: number) {
:placeholder="$t('plugin.placeholder.description')"
/>
</ElFormItem>
<ElFormItem prop="categoryIds" :label="$t('plugin.category')">
<ElSelect
v-model="entity.categoryIds"
multiple
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="3"
>
<ElOption
v-for="item in categoryList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</ElSelect>
</ElFormItem>
<ElFormItem prop="Headers" label="Headers">
<div
class="headers-container-reduce flex flex-row gap-4"