初始化
This commit is contained in:
158
easyflow-ui-admin/app/src/views/datacenter/BatchImportModal.vue
Normal file
158
easyflow-ui-admin/app/src/views/datacenter/BatchImportModal.vue
Normal file
@@ -0,0 +1,158 @@
|
||||
<script setup lang="ts">
|
||||
import type { UploadFile } from 'element-plus';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import { downloadFileFromBlob } from '@easyflow/utils';
|
||||
|
||||
import {
|
||||
ElButton,
|
||||
ElDialog,
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElUpload,
|
||||
} from 'element-plus';
|
||||
|
||||
import { api } from '#/api/request';
|
||||
import uploadIcon from '#/assets/datacenter/upload.png';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
const props = withDefaults(defineProps<BatchImportModalProps>(), {
|
||||
title: 'title',
|
||||
});
|
||||
const emit = defineEmits(['reload']);
|
||||
export interface BatchImportModalProps {
|
||||
tableId: any;
|
||||
title?: string;
|
||||
}
|
||||
// vue
|
||||
onMounted(() => {});
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
// variables
|
||||
const dialogVisible = ref(false);
|
||||
const downloadLoading = ref(false);
|
||||
const fileList = ref<any[]>([]);
|
||||
const currentFile = ref<File | null>();
|
||||
const btnLoading = ref(false);
|
||||
// functions
|
||||
function openDialog() {
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
function closeDialog() {
|
||||
fileList.value = [];
|
||||
currentFile.value = null;
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
function onFileChange(uploadFile: UploadFile) {
|
||||
currentFile.value = uploadFile.raw;
|
||||
return false;
|
||||
}
|
||||
function downloadTemplate() {
|
||||
downloadLoading.value = true;
|
||||
api
|
||||
.download(`/api/v1/datacenterTable/getTemplate?tableId=${props.tableId}`)
|
||||
.then((res) => {
|
||||
downloadLoading.value = false;
|
||||
downloadFileFromBlob({
|
||||
fileName: 'template.xlsx',
|
||||
source: res,
|
||||
});
|
||||
});
|
||||
}
|
||||
function handleUpload() {
|
||||
if (!currentFile.value) {
|
||||
ElMessage.warning($t('datacenterTable.uploadDesc'));
|
||||
return;
|
||||
}
|
||||
const formData = new FormData();
|
||||
formData.append('file', currentFile.value);
|
||||
formData.append('tableId', props.tableId);
|
||||
btnLoading.value = true;
|
||||
api.postFile('/api/v1/datacenterTable/importData', formData).then((res) => {
|
||||
btnLoading.value = false;
|
||||
if (res.errorCode === 0) {
|
||||
const arr: any[] = res.data.errorRows;
|
||||
let html = '';
|
||||
for (const element of arr) {
|
||||
html += `<p>${JSON.stringify(element)}</p><br>`;
|
||||
}
|
||||
closeDialog();
|
||||
ElMessageBox.alert(
|
||||
`<strong>${$t('datacenterTable.totalNum')}:</strong>${res.data.totalCount}
|
||||
<strong>${$t('datacenterTable.successNum')}:</strong>${res.data.successCount}
|
||||
<strong>${$t('datacenterTable.failNum')}:</strong>${res.data.errorCount}<br>
|
||||
<strong>${$t('datacenterTable.failList')}:</strong>${html}`,
|
||||
$t('datacenterTable.importComplete'),
|
||||
{
|
||||
confirmButtonText: $t('message.ok'),
|
||||
dangerouslyUseHTMLString: true,
|
||||
callback: () => {
|
||||
emit('reload');
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ElDialog
|
||||
v-model="dialogVisible"
|
||||
draggable
|
||||
:title="props.title"
|
||||
:before-close="closeDialog"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<ElUpload
|
||||
:file-list="fileList"
|
||||
drag
|
||||
action="#"
|
||||
accept=".xlsx,.xls,.csv"
|
||||
:auto-upload="false"
|
||||
:on-change="onFileChange"
|
||||
:limit="1"
|
||||
>
|
||||
<div class="flex flex-col items-center">
|
||||
<img alt="" :src="uploadIcon" class="h-12 w-12" />
|
||||
<div class="text-base font-medium">
|
||||
{{ $t('datacenterTable.uploadTitle') }}
|
||||
</div>
|
||||
<div class="desc text-[13px]">
|
||||
{{ $t('datacenterTable.uploadDesc') }}
|
||||
</div>
|
||||
</div>
|
||||
</ElUpload>
|
||||
<ElButton
|
||||
:disabled="downloadLoading"
|
||||
type="primary"
|
||||
link
|
||||
@click="downloadTemplate"
|
||||
>
|
||||
{{ $t('datacenterTable.downloadTemplate') }}
|
||||
</ElButton>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="closeDialog">
|
||||
{{ $t('button.cancel') }}
|
||||
</ElButton>
|
||||
<ElButton
|
||||
:disabled="btnLoading"
|
||||
:loading="btnLoading"
|
||||
type="primary"
|
||||
@click="handleUpload"
|
||||
>
|
||||
{{ $t('button.confirm') }}
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.desc {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,272 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { $t } from '@easyflow/locales';
|
||||
|
||||
import {
|
||||
ArrowLeft,
|
||||
Delete,
|
||||
MoreFilled,
|
||||
Plus,
|
||||
Upload,
|
||||
} from '@element-plus/icons-vue';
|
||||
import {
|
||||
ElButton,
|
||||
ElDropdown,
|
||||
ElDropdownItem,
|
||||
ElDropdownMenu,
|
||||
ElIcon,
|
||||
ElImage,
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
} from 'element-plus';
|
||||
|
||||
import { api } from '#/api/request';
|
||||
import tableIcon from '#/assets/datacenter/table2x.png';
|
||||
import PageData from '#/components/page/PageData.vue';
|
||||
import PageSide from '#/components/page/PageSide.vue';
|
||||
import { router } from '#/router';
|
||||
import { useDictStore } from '#/store';
|
||||
import BatchImportModal from '#/views/datacenter/BatchImportModal.vue';
|
||||
import RecordModal from '#/views/datacenter/RecordModal.vue';
|
||||
|
||||
const pageDataRef = ref();
|
||||
const route = useRoute();
|
||||
const tableId = ref(route.query.tableId);
|
||||
onMounted(() => {
|
||||
initDict();
|
||||
getDetailInfo(tableId.value);
|
||||
getHeaders(tableId.value);
|
||||
});
|
||||
const detailInfo = ref<any>({});
|
||||
const fieldList = ref<any[]>([]);
|
||||
const headers = ref<any[]>([]);
|
||||
const activeMenu = ref('2');
|
||||
const recordModal = ref();
|
||||
const batchImportModal = ref();
|
||||
const dictStore = useDictStore();
|
||||
const categoryData = [
|
||||
{ key: '2', name: $t('datacenterTable.data') },
|
||||
{ key: '1', name: $t('datacenterTable.structure') },
|
||||
];
|
||||
function initDict() {
|
||||
dictStore.fetchDictionary('fieldType');
|
||||
dictStore.fetchDictionary('yesOrNo');
|
||||
}
|
||||
function getDetailInfo(id: any) {
|
||||
api.get(`/api/v1/datacenterTable/detailInfo?tableId=${id}`).then((res) => {
|
||||
detailInfo.value = res.data;
|
||||
fieldList.value = res.data.fields;
|
||||
});
|
||||
}
|
||||
function getHeaders(id: any) {
|
||||
api.get(`/api/v1/datacenterTable/getHeaders?tableId=${id}`).then((res) => {
|
||||
headers.value = res.data;
|
||||
});
|
||||
}
|
||||
function showDialog(row: any) {
|
||||
recordModal.value.openDialog({ ...row });
|
||||
}
|
||||
function remove(row: any) {
|
||||
ElMessageBox.confirm($t('message.deleteAlert'), $t('message.noticeTitle'), {
|
||||
confirmButtonText: $t('message.ok'),
|
||||
cancelButtonText: $t('message.cancel'),
|
||||
type: 'warning',
|
||||
beforeClose: (action, instance, done) => {
|
||||
if (action === 'confirm') {
|
||||
instance.confirmButtonLoading = true;
|
||||
api
|
||||
.post(
|
||||
`/api/v1/datacenterTable/removeValue`,
|
||||
{},
|
||||
{
|
||||
params: {
|
||||
tableId: tableId.value,
|
||||
id: row.id,
|
||||
},
|
||||
},
|
||||
)
|
||||
.then((res) => {
|
||||
instance.confirmButtonLoading = false;
|
||||
if (res.errorCode === 0) {
|
||||
ElMessage.success(res.message);
|
||||
refresh();
|
||||
done();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
instance.confirmButtonLoading = false;
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},
|
||||
}).catch(() => {});
|
||||
}
|
||||
function refresh() {
|
||||
pageDataRef.value.setQuery({});
|
||||
}
|
||||
function openImportModal() {
|
||||
batchImportModal.value.openDialog();
|
||||
}
|
||||
function changeTab(category: any) {
|
||||
activeMenu.value = category.key;
|
||||
if (category.key === '2' && pageDataRef.value) {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-background-deep flex h-full flex-col gap-6 p-6">
|
||||
<BatchImportModal
|
||||
:table-id="tableId"
|
||||
:title="$t('button.batchImport')"
|
||||
ref="batchImportModal"
|
||||
@reload="refresh"
|
||||
/>
|
||||
<RecordModal
|
||||
ref="recordModal"
|
||||
:form-items="headers"
|
||||
:table-id="tableId"
|
||||
@reload="refresh"
|
||||
/>
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-4">
|
||||
<ElIcon class="cursor-pointer" @click="router.back()">
|
||||
<ArrowLeft />
|
||||
</ElIcon>
|
||||
<div class="flex items-center gap-3">
|
||||
<ElImage :src="tableIcon" class="h-9 w-9 rounded-full" />
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<div class="text-base font-medium">{{ detailInfo.tableName }}</div>
|
||||
<div class="desc text-sm">{{ detailInfo.tableDesc }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center" v-if="activeMenu === '2'">
|
||||
<ElButton type="primary" @click="showDialog({})">
|
||||
<ElIcon class="mr-1">
|
||||
<Plus />
|
||||
</ElIcon>
|
||||
{{ $t('button.addLine') }}
|
||||
</ElButton>
|
||||
<ElButton type="primary" @click="openImportModal">
|
||||
<ElIcon class="mr-1">
|
||||
<Upload />
|
||||
</ElIcon>
|
||||
{{ $t('button.batchImport') }}
|
||||
</ElButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex h-full max-h-[calc(100vh-191px)] gap-3">
|
||||
<PageSide
|
||||
label-key="name"
|
||||
value-key="key"
|
||||
:menus="categoryData"
|
||||
default-selected="2"
|
||||
@change="changeTab"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="bg-background border-border flex-1 overflow-auto rounded-lg border p-5"
|
||||
>
|
||||
<ElTable v-show="activeMenu === '1'" :data="fieldList">
|
||||
<ElTableColumn
|
||||
prop="fieldName"
|
||||
:label="$t('datacenterTableFields.fieldName')"
|
||||
/>
|
||||
<ElTableColumn
|
||||
prop="fieldDesc"
|
||||
:label="$t('datacenterTableFields.fieldDesc')"
|
||||
/>
|
||||
<ElTableColumn
|
||||
prop="fieldType"
|
||||
:label="$t('datacenterTableFields.fieldType')"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ dictStore.getDictLabel('fieldType', row.fieldType) }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
prop="required"
|
||||
:label="$t('datacenterTableFields.required')"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ dictStore.getDictLabel('yesOrNo', row.required) }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</ElTable>
|
||||
<PageData
|
||||
v-show="activeMenu === '2'"
|
||||
ref="pageDataRef"
|
||||
page-url="/api/v1/datacenterTable/getPageData"
|
||||
:extra-query-params="{ tableId }"
|
||||
:page-size="10"
|
||||
>
|
||||
<template #default="{ pageList }">
|
||||
<ElTable :data="pageList">
|
||||
<ElTableColumn
|
||||
v-for="item in headers"
|
||||
:key="item.key"
|
||||
:prop="item.key"
|
||||
:label="item.title"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<div v-if="item.fieldType === 5">
|
||||
{{
|
||||
1 === row[item.key] ? $t('common.yes') : $t('common.no')
|
||||
}}
|
||||
</div>
|
||||
<div v-else-if="item.fieldType === 4">
|
||||
{{ parseFloat(row[item.key]) }}
|
||||
</div>
|
||||
<div v-else>{{ row[item.key] }}</div>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
:label="$t('common.handle')"
|
||||
width="90"
|
||||
align="right"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center gap-3">
|
||||
<ElButton link type="primary" @click="showDialog(row)">
|
||||
{{ $t('button.edit') }}
|
||||
</ElButton>
|
||||
|
||||
<ElDropdown>
|
||||
<ElButton link :icon="MoreFilled" />
|
||||
|
||||
<template #dropdown>
|
||||
<ElDropdownMenu>
|
||||
<ElDropdownItem @click="remove(row)">
|
||||
<ElButton link :icon="Delete" type="danger">
|
||||
{{ $t('button.delete') }}
|
||||
</ElButton>
|
||||
</ElDropdownItem>
|
||||
</ElDropdownMenu>
|
||||
</template>
|
||||
</ElDropdown>
|
||||
</div>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</ElTable>
|
||||
</template>
|
||||
</PageData>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.desc {
|
||||
color: #75808d;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,175 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInstance } from 'element-plus';
|
||||
|
||||
import { markRaw, onMounted, ref } from 'vue';
|
||||
|
||||
import { Delete, MoreFilled, Plus } from '@element-plus/icons-vue';
|
||||
import {
|
||||
ElButton,
|
||||
ElDropdown,
|
||||
ElDropdownItem,
|
||||
ElDropdownMenu,
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
} from 'element-plus';
|
||||
|
||||
import { api } from '#/api/request';
|
||||
import HeaderSearch from '#/components/headerSearch/HeaderSearch.vue';
|
||||
import PageData from '#/components/page/PageData.vue';
|
||||
import { $t } from '#/locales';
|
||||
import { router } from '#/router';
|
||||
import { useDictStore } from '#/store';
|
||||
|
||||
import DatacenterTableModal from './DatacenterTableModal.vue';
|
||||
|
||||
onMounted(() => {
|
||||
initDict();
|
||||
});
|
||||
|
||||
const pageDataRef = ref();
|
||||
const saveDialog = ref();
|
||||
const dictStore = useDictStore();
|
||||
const headerButtons = [
|
||||
{
|
||||
key: 'create',
|
||||
text: $t('button.add'),
|
||||
icon: markRaw(Plus),
|
||||
type: 'primary',
|
||||
data: { action: 'create' },
|
||||
permission: '/api/v1/datacenterTable/save',
|
||||
},
|
||||
];
|
||||
|
||||
function initDict() {
|
||||
dictStore.fetchDictionary('dataStatus');
|
||||
}
|
||||
const handleSearch = (params: string) => {
|
||||
pageDataRef.value.setQuery({ tableName: params, isQueryOr: true });
|
||||
};
|
||||
function reset(formEl?: FormInstance) {
|
||||
formEl?.resetFields();
|
||||
pageDataRef.value.setQuery({});
|
||||
}
|
||||
function showDialog(row: any) {
|
||||
saveDialog.value.openDialog({ ...row });
|
||||
}
|
||||
function remove(row: any) {
|
||||
ElMessageBox.confirm($t('message.deleteAlert'), $t('message.noticeTitle'), {
|
||||
confirmButtonText: $t('message.ok'),
|
||||
cancelButtonText: $t('message.cancel'),
|
||||
type: 'warning',
|
||||
beforeClose: (action, instance, done) => {
|
||||
if (action === 'confirm') {
|
||||
instance.confirmButtonLoading = true;
|
||||
api
|
||||
.get(`/api/v1/datacenterTable/removeTable?tableId=${row.id}`)
|
||||
.then((res) => {
|
||||
instance.confirmButtonLoading = false;
|
||||
if (res.errorCode === 0) {
|
||||
ElMessage.success(res.message);
|
||||
reset();
|
||||
done();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
instance.confirmButtonLoading = false;
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},
|
||||
}).catch(() => {});
|
||||
}
|
||||
function toDetailPage(row: any) {
|
||||
router.push({
|
||||
name: 'TableDetail',
|
||||
query: {
|
||||
tableId: row.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex h-full flex-col gap-6 p-6">
|
||||
<DatacenterTableModal ref="saveDialog" @reload="reset" />
|
||||
<HeaderSearch
|
||||
:buttons="headerButtons"
|
||||
@search="handleSearch"
|
||||
@button-click="showDialog({})"
|
||||
/>
|
||||
|
||||
<div class="bg-background border-border flex-1 rounded-lg border p-5">
|
||||
<PageData
|
||||
ref="pageDataRef"
|
||||
page-url="/api/v1/datacenterTable/page"
|
||||
:page-size="10"
|
||||
>
|
||||
<template #default="{ pageList }">
|
||||
<ElTable :data="pageList" border>
|
||||
<ElTableColumn
|
||||
prop="tableName"
|
||||
:label="$t('datacenterTable.tableName')"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ row.tableName }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
prop="tableDesc"
|
||||
:label="$t('datacenterTable.tableDesc')"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ row.tableDesc }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
prop="created"
|
||||
:label="$t('datacenterTable.created')"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ row.created }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
:label="$t('common.handle')"
|
||||
width="140"
|
||||
align="right"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center">
|
||||
<ElButton link type="primary" @click="toDetailPage(row)">
|
||||
{{ $t('button.view') }}
|
||||
</ElButton>
|
||||
<ElButton link type="primary" @click="showDialog(row)">
|
||||
{{ $t('button.edit') }}
|
||||
</ElButton>
|
||||
</div>
|
||||
|
||||
<ElDropdown>
|
||||
<ElButton link :icon="MoreFilled" />
|
||||
|
||||
<template #dropdown>
|
||||
<ElDropdownMenu>
|
||||
<ElDropdownItem @click="remove(row)">
|
||||
<ElButton link :icon="Delete" type="danger">
|
||||
{{ $t('button.delete') }}
|
||||
</ElButton>
|
||||
</ElDropdownItem>
|
||||
</ElDropdownMenu>
|
||||
</template>
|
||||
</ElDropdown>
|
||||
</div>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</ElTable>
|
||||
</template>
|
||||
</PageData>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,280 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInstance } from 'element-plus';
|
||||
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import {
|
||||
ElButton,
|
||||
ElDialog,
|
||||
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>
|
||||
<ElDialog
|
||||
v-model="dialogVisible"
|
||||
draggable
|
||||
:title="isAdd ? $t('button.add') : $t('button.edit')"
|
||||
:before-close="closeDialog"
|
||||
:close-on-click-modal="false"
|
||||
width="800px"
|
||||
>
|
||||
<ElForm
|
||||
label-width="100px"
|
||||
ref="saveForm"
|
||||
:model="entity"
|
||||
status-icon
|
||||
:rules="rules"
|
||||
>
|
||||
<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-width="0">
|
||||
<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>
|
||||
<template #footer>
|
||||
<ElButton @click="closeDialog">
|
||||
{{ $t('button.cancel') }}
|
||||
</ElButton>
|
||||
<ElButton
|
||||
type="primary"
|
||||
@click="save"
|
||||
:loading="btnLoading"
|
||||
:disabled="btnLoading"
|
||||
>
|
||||
{{ $t('button.save') }}
|
||||
</ElButton>
|
||||
</template>
|
||||
</ElDialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
154
easyflow-ui-admin/app/src/views/datacenter/RecordModal.vue
Normal file
154
easyflow-ui-admin/app/src/views/datacenter/RecordModal.vue
Normal file
@@ -0,0 +1,154 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInstance } from 'element-plus';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
ElButton,
|
||||
ElDatePicker,
|
||||
ElDialog,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
ElInputNumber,
|
||||
ElMessage,
|
||||
} from 'element-plus';
|
||||
|
||||
import { api } from '#/api/request';
|
||||
import DictSelect from '#/components/dict/DictSelect.vue';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
const props = withDefaults(defineProps<RecordModalProps>(), {});
|
||||
const emit = defineEmits(['reload']);
|
||||
// vue
|
||||
export interface RecordModalProps {
|
||||
formItems: any[];
|
||||
tableId: any;
|
||||
}
|
||||
onMounted(() => {});
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
const saveForm = ref<FormInstance>();
|
||||
// variables
|
||||
const dialogVisible = ref(false);
|
||||
const isAdd = ref(true);
|
||||
const entity = ref<any>({});
|
||||
const btnLoading = ref(false);
|
||||
const rules = ref({});
|
||||
|
||||
// functions
|
||||
function openDialog(row: any) {
|
||||
if (row.id) {
|
||||
isAdd.value = false;
|
||||
}
|
||||
entity.value = row;
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
function save() {
|
||||
saveForm.value?.validate((valid) => {
|
||||
if (valid) {
|
||||
const data: Record<string, any> = {};
|
||||
for (const formItem of props.formItems) {
|
||||
data[formItem.key] = entity.value[formItem.key];
|
||||
}
|
||||
data.tableId = props.tableId;
|
||||
data.id = entity.value.id;
|
||||
btnLoading.value = true;
|
||||
api
|
||||
.postForm('/api/v1/datacenterTable/saveValue', data)
|
||||
.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;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ElDialog
|
||||
v-model="dialogVisible"
|
||||
draggable
|
||||
:title="isAdd ? $t('button.add') : $t('button.edit')"
|
||||
:before-close="closeDialog"
|
||||
:close-on-click-modal="false"
|
||||
width="800px"
|
||||
>
|
||||
<ElForm
|
||||
label-width="100px"
|
||||
ref="saveForm"
|
||||
:model="entity"
|
||||
status-icon
|
||||
:rules="rules"
|
||||
>
|
||||
<ElFormItem
|
||||
v-for="item in props.formItems"
|
||||
:rules="
|
||||
item.required
|
||||
? [
|
||||
{
|
||||
required: true,
|
||||
message: `${item.title}${$t('message.notEmpty')}`,
|
||||
},
|
||||
]
|
||||
: []
|
||||
"
|
||||
:key="item.key"
|
||||
:prop="item.key"
|
||||
:label="item.title"
|
||||
>
|
||||
<ElInput v-if="item.fieldType === 1" v-model.trim="entity[item.key]" />
|
||||
<ElInputNumber
|
||||
v-if="item.fieldType === 2"
|
||||
v-model.number="entity[item.key]"
|
||||
:precision="0"
|
||||
/>
|
||||
<ElDatePicker
|
||||
v-if="item.fieldType === 3"
|
||||
v-model="entity[item.key]"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
<ElInputNumber
|
||||
v-if="item.fieldType === 4"
|
||||
v-model="entity[item.key]"
|
||||
:precision="2"
|
||||
/>
|
||||
<DictSelect
|
||||
v-if="item.fieldType === 5"
|
||||
v-model="entity[item.key]"
|
||||
dict-code="yesOrNo"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<template #footer>
|
||||
<ElButton @click="closeDialog">
|
||||
{{ $t('button.cancel') }}
|
||||
</ElButton>
|
||||
<ElButton
|
||||
type="primary"
|
||||
@click="save"
|
||||
:loading="btnLoading"
|
||||
:disabled="btnLoading"
|
||||
>
|
||||
{{ $t('button.save') }}
|
||||
</ElButton>
|
||||
</template>
|
||||
</ElDialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user