- 收敛管理端公共 Modal 链路,新增表单弹窗与普通内容弹窗包装\n- 迁移 Bot、知识库、插件、工作流、资源、MCP、数据中枢与系统管理页面级弹窗\n- 统一内容区工具栏、列表容器、导航与顶部按钮的视觉密度和交互节奏
273 lines
7.3 KiB
Vue
273 lines
7.3 KiB
Vue
<script setup lang="ts">
|
|
import type { FormInstance } from 'element-plus';
|
|
|
|
import { onMounted, ref, watch } from 'vue';
|
|
|
|
import { EasyFlowFormModal } from '@easyflow/common-ui';
|
|
|
|
import { Plus } from '@element-plus/icons-vue';
|
|
import {
|
|
ElButton,
|
|
ElForm,
|
|
ElFormItem,
|
|
ElIcon,
|
|
ElInput,
|
|
ElMessage,
|
|
ElMessageBox,
|
|
ElOption,
|
|
ElSelect,
|
|
ElTable,
|
|
ElTableColumn,
|
|
} from 'element-plus';
|
|
|
|
import { api } from '#/api/request';
|
|
import { $t } from '#/locales';
|
|
|
|
const emit = defineEmits(['reload']);
|
|
// vue
|
|
onMounted(() => {
|
|
getFieldType();
|
|
getYesOrNo();
|
|
});
|
|
defineExpose({
|
|
openDialog,
|
|
});
|
|
const saveForm = ref<FormInstance>();
|
|
// variables
|
|
const dialogVisible = ref(false);
|
|
const isAdd = ref(true);
|
|
const entity = ref<any>({
|
|
deptId: '',
|
|
tableName: '',
|
|
tableDesc: '',
|
|
actualTable: '',
|
|
status: '',
|
|
options: '',
|
|
});
|
|
const btnLoading = ref(false);
|
|
const rules = ref({
|
|
tableName: [
|
|
{ required: true, message: $t('message.required'), trigger: 'blur' },
|
|
{
|
|
pattern: /^[a-z][a-z0-9_]*$/,
|
|
message: $t('datacenterTable.nameRegx'),
|
|
},
|
|
],
|
|
fields: [
|
|
{
|
|
required: true,
|
|
validator: (_: any, value: any, callback: any) => {
|
|
if (!value || value.length === 0) {
|
|
callback(new Error($t('datacenterTable.noFieldError')));
|
|
} else {
|
|
// 检查字段数组中的fieldName和fieldDesc字段
|
|
value.forEach((field: any) => {
|
|
if (!field.fieldName || !field.fieldDesc) {
|
|
callback(new Error($t('datacenterTable.fieldInfoError')));
|
|
}
|
|
if (!/^[a-z][a-z0-9_]*$/.test(field.fieldName)) {
|
|
callback(new Error($t('datacenterTable.nameRegx')));
|
|
}
|
|
});
|
|
callback();
|
|
}
|
|
},
|
|
trigger: 'blur',
|
|
},
|
|
],
|
|
});
|
|
const fieldsData = ref();
|
|
const removeFields = ref<any[]>([]);
|
|
const loadFields = ref(false);
|
|
const fieldTypes = ref<any>([]);
|
|
const yesOrNoDict = ref<any>([]);
|
|
watch(
|
|
() => fieldsData.value,
|
|
(newVal) => {
|
|
entity.value.fields = newVal;
|
|
},
|
|
{ deep: true },
|
|
);
|
|
|
|
// functions
|
|
function getDetailInfo(tableId: any) {
|
|
loadFields.value = true;
|
|
api
|
|
.get(`/api/v1/datacenterTable/detailInfo?tableId=${tableId}`)
|
|
.then((res) => {
|
|
loadFields.value = false;
|
|
fieldsData.value = res.data.fields;
|
|
});
|
|
}
|
|
function openDialog(row: any) {
|
|
fieldsData.value = [];
|
|
removeFields.value = [];
|
|
if (row.id) {
|
|
getDetailInfo(row.id);
|
|
isAdd.value = false;
|
|
}
|
|
entity.value = row;
|
|
dialogVisible.value = true;
|
|
}
|
|
function save() {
|
|
saveForm.value?.validate((valid) => {
|
|
if (valid) {
|
|
if (fieldsData.value.length === 0) {
|
|
ElMessage.error($t('message.required'));
|
|
return;
|
|
}
|
|
const obj = {
|
|
...entity.value,
|
|
fields: [...fieldsData.value, ...removeFields.value],
|
|
};
|
|
btnLoading.value = true;
|
|
api
|
|
.post('/api/v1/datacenterTable/saveTable', obj)
|
|
.then((res) => {
|
|
btnLoading.value = false;
|
|
if (res.errorCode === 0) {
|
|
ElMessage.success(res.message);
|
|
emit('reload');
|
|
closeDialog();
|
|
}
|
|
})
|
|
.catch(() => {
|
|
btnLoading.value = false;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
function closeDialog() {
|
|
saveForm.value?.resetFields();
|
|
isAdd.value = true;
|
|
entity.value = {};
|
|
dialogVisible.value = false;
|
|
}
|
|
function addField() {
|
|
fieldsData.value.push({
|
|
fieldName: '',
|
|
fieldDesc: '',
|
|
fieldType: 1,
|
|
required: 0,
|
|
handleDelete: false,
|
|
rowKey: Date.now().toString(),
|
|
});
|
|
}
|
|
function deleteField(row: any, $index: number) {
|
|
ElMessageBox.confirm($t('message.deleteAlert'), $t('message.noticeTitle'), {
|
|
confirmButtonText: $t('message.ok'),
|
|
cancelButtonText: $t('message.cancel'),
|
|
type: 'warning',
|
|
beforeClose: (action, _, done) => {
|
|
if (action === 'confirm') {
|
|
if (row.id) {
|
|
row.handleDelete = true;
|
|
removeFields.value.push(row);
|
|
}
|
|
fieldsData.value.splice($index, 1);
|
|
done();
|
|
} else {
|
|
done();
|
|
}
|
|
},
|
|
}).catch(() => {});
|
|
}
|
|
function getFieldType() {
|
|
api.get('/api/v1/dict/items/fieldType').then((res) => {
|
|
fieldTypes.value = res.data;
|
|
});
|
|
}
|
|
function getYesOrNo() {
|
|
api.get('/api/v1/dict/items/yesOrNo').then((res) => {
|
|
yesOrNoDict.value = res.data;
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<EasyFlowFormModal
|
|
v-model:open="dialogVisible"
|
|
:closable="!btnLoading"
|
|
:title="isAdd ? $t('button.add') : $t('button.edit')"
|
|
:before-close="closeDialog"
|
|
width="800px"
|
|
:confirm-loading="btnLoading"
|
|
:confirm-text="$t('button.save')"
|
|
:submitting="btnLoading"
|
|
@confirm="save"
|
|
>
|
|
<ElForm
|
|
ref="saveForm"
|
|
:model="entity"
|
|
status-icon
|
|
:rules="rules"
|
|
label-position="top"
|
|
class="easyflow-modal-form easyflow-modal-form--compact"
|
|
>
|
|
<ElFormItem prop="tableName" :label="$t('datacenterTable.tableName')">
|
|
<ElInput :disabled="!isAdd" v-model.trim="entity.tableName" />
|
|
</ElFormItem>
|
|
<ElFormItem prop="tableDesc" :label="$t('datacenterTable.tableDesc')">
|
|
<ElInput v-model.trim="entity.tableDesc" />
|
|
</ElFormItem>
|
|
<ElFormItem prop="fields" :label="$t('datacenterTable.fields')">
|
|
<div v-loading="loadFields" class="w-full">
|
|
<ElTable :data="fieldsData">
|
|
<ElTableColumn :label="$t('datacenterTable.fieldName')">
|
|
<template #default="{ row }">
|
|
<ElInput v-model.trim="row.fieldName" />
|
|
</template>
|
|
</ElTableColumn>
|
|
<ElTableColumn :label="$t('datacenterTable.fieldDesc')">
|
|
<template #default="{ row }">
|
|
<ElInput v-model.trim="row.fieldDesc" />
|
|
</template>
|
|
</ElTableColumn>
|
|
<ElTableColumn :label="$t('datacenterTable.fieldType')">
|
|
<template #default="{ row }">
|
|
<ElSelect v-model.trim="row.fieldType" :disabled="!!row.id">
|
|
<ElOption
|
|
v-for="item in fieldTypes"
|
|
:key="item.value"
|
|
:label="item.label"
|
|
:value="item.value"
|
|
/>
|
|
</ElSelect>
|
|
</template>
|
|
</ElTableColumn>
|
|
<ElTableColumn :label="$t('datacenterTable.required')">
|
|
<template #default="{ row }">
|
|
<ElSelect v-model.trim="row.required">
|
|
<ElOption
|
|
v-for="item in yesOrNoDict"
|
|
:key="item.value"
|
|
:label="item.label"
|
|
:value="item.value"
|
|
/>
|
|
</ElSelect>
|
|
</template>
|
|
</ElTableColumn>
|
|
<ElTableColumn :label="$t('common.handle')" width="80">
|
|
<template #default="{ row, $index }">
|
|
<ElButton link type="danger" @click="deleteField(row, $index)">
|
|
{{ $t('button.delete') }}
|
|
</ElButton>
|
|
</template>
|
|
</ElTableColumn>
|
|
</ElTable>
|
|
<div class="mt-3">
|
|
<ElButton plain type="primary" @click="addField">
|
|
<ElIcon class="mr-1">
|
|
<Plus />
|
|
</ElIcon>
|
|
{{ $t('button.add') }}
|
|
</ElButton>
|
|
</div>
|
|
</div>
|
|
</ElFormItem>
|
|
</ElForm>
|
|
</EasyFlowFormModal>
|
|
</template>
|
|
|
|
<style scoped></style>
|