|
@@ -0,0 +1,306 @@
|
|
|
|
+<template>
|
|
|
|
+ <el-dialog
|
|
|
|
+ :direction="direction || 'rtl'"
|
|
|
|
+ width="900px"
|
|
|
|
+ :model-value="show"
|
|
|
|
+ :wrapperClosable="false"
|
|
|
|
+ class="upload-drawer dataset-file-upload"
|
|
|
|
+ title="上传文件"
|
|
|
|
+ v-bind="$attrs"
|
|
|
|
+ @close="onClose"
|
|
|
|
+ >
|
|
|
|
+ <div
|
|
|
|
+ v-loading="uploadLoading"
|
|
|
|
+ element-loading-spinner="el-icon-loading"
|
|
|
|
+ element-loading-text="上传中"
|
|
|
|
+ style="padding: 0 20px; overflow: auto"
|
|
|
|
+ >
|
|
|
|
+ <el-form label-width="80px" size="small">
|
|
|
|
+ <el-form-item label="上传文件" required>
|
|
|
|
+ <el-upload
|
|
|
|
+ ref="upload"
|
|
|
|
+ :action="fileUploadUrl + '/bi-api/cube/file/structure'"
|
|
|
|
+ :before-upload="beforeUpload"
|
|
|
|
+ :data="{ columnNameType: fileForm.columnNameType }"
|
|
|
|
+ :headers="fileUploadHeaders"
|
|
|
|
+ :on-success="uploadSuccess"
|
|
|
|
+ class="upload" :limit="1"
|
|
|
|
+ :on-remove="onRemove"
|
|
|
|
+ >
|
|
|
|
+ <el-button size="small" type="primary" @click.prevent="handleClick" ref="uploadBtn">点击上传</el-button>
|
|
|
|
+ </el-upload>
|
|
|
|
+ <div class="tips ml-10" style="font-size: 12px; color: rgba(160, 160, 160, 1);margin-left: 3px;">
|
|
|
|
+ <el-icon>
|
|
|
|
+ <InfoFilled/>
|
|
|
|
+ </el-icon>
|
|
|
|
+ 单文件上传,支持 xlsx、xls、csv 格式文件,默认选择第一个sheet
|
|
|
|
+ </div>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="物理表名" required>
|
|
|
|
+ <el-input v-model="fileForm.tableName" :maxlength="30" placeholder="请使用英文/数字/下划线"></el-input>
|
|
|
|
+ <div class="tips ml-10" style="font-size: 12px; color: rgba(160, 160, 160, 1)">
|
|
|
|
+ <el-icon>
|
|
|
|
+ <InfoFilled/>
|
|
|
|
+ </el-icon>
|
|
|
|
+ 物理表名字段:由英文,数字,下划线组成,字母开头
|
|
|
|
+ </div>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="备注表名" required>
|
|
|
|
+ <el-input v-model="fileForm.tableComment"></el-input>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="选择分类">
|
|
|
|
+ <el-select v-model="fileForm.classifyId">
|
|
|
|
+ <el-option :value="0" label="全部"></el-option>
|
|
|
|
+ <el-option
|
|
|
|
+ v-for="(item, i) of systemStore.state.tableCategoryList"
|
|
|
|
+ :key="i"
|
|
|
|
+ :label="item.categoryName"
|
|
|
|
+ :value="item.id"
|
|
|
|
+ ></el-option>
|
|
|
|
+ </el-select>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="物理字段创建类型" label-width="112">
|
|
|
|
+ <el-radio @change="getTableColumnList" v-model="columnNameType" label="pinyinAllColumnName">全拼</el-radio>
|
|
|
|
+ <el-radio @change="getTableColumnList" v-model="columnNameType" label="pinyinFirstLetterColumnName">
|
|
|
|
+ 拼音首字母
|
|
|
|
+ </el-radio>
|
|
|
|
+ <el-radio @change="getTableColumnList" v-model="columnNameType" label="systemColumnName">系统默认</el-radio>
|
|
|
|
+ <div class="tips" style="font-size: 12px; color: rgba(160, 160, 160, 1)">
|
|
|
|
+ <i class="el-icon-info"></i>
|
|
|
|
+ 文件上传后,创建的物理表名和字段名将会按照此配置创建
|
|
|
|
+ </div>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="字段大小写转换" label-width="100">
|
|
|
|
+ <el-radio @change="getTableColumnList" v-model="isCase" label="xiaoxie">小写</el-radio>
|
|
|
|
+ <el-radio @change="getTableColumnList" v-model="isCase" label="daxie">大写</el-radio>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <div style="font-size: 14px; margin-bottom: 20px; display: flex">字段配置</div>
|
|
|
|
+ </el-form>
|
|
|
|
+ <el-table :data="fileForm.tableColumnList" size="default">
|
|
|
|
+ <el-table-column label="原始字段">
|
|
|
|
+ <template v-slot="{ row }">
|
|
|
|
+ <el-input v-model="row.comment" size="small"></el-input>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="物理字段">
|
|
|
|
+ <template v-slot="{ row }">
|
|
|
|
+ <el-input v-model="row.columnName" size="small" :maxlength="30" :show-word-limit="isOracle"></el-input>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="数据类型">
|
|
|
|
+ <template v-slot="{ row }">
|
|
|
|
+ <el-select v-model="row.columnType" size="small" @change="changeString(row)">
|
|
|
|
+ <el-option label="整形" value="INT"></el-option>
|
|
|
|
+ <el-option label="数字" value="NUMBER"></el-option>
|
|
|
|
+ <el-option label="日期" value="DATETIME"></el-option>
|
|
|
|
+ <el-option label="字符串" value="STRING"></el-option>
|
|
|
|
+ <el-option label="长字符串" value="LARGE_STRING"></el-option>
|
|
|
|
+ <el-option label="长整数" value="BIGINT"></el-option>
|
|
|
|
+ </el-select>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="字段长度">
|
|
|
|
+ <template v-slot="{ row }">
|
|
|
|
+ <el-input-number
|
|
|
|
+ :value="row.columnSize || 255" min="0" size="small" style="width: 120px"
|
|
|
|
+ v-model="row.columnSize" v-if="row.columnType === 'STRING' || row.columnType === 'NUMBER'"
|
|
|
|
+ ></el-input-number>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="字段位数" width="200">
|
|
|
|
+ <template #header>
|
|
|
|
+ <div style="display: flex; align-items: center; gap: 10px">
|
|
|
|
+ 字段位数:
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="decimalDigits" @change="changeDecimalDigits" style="width: 70px"
|
|
|
|
+ size="small" placeholder="批量设置"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-slot="{ row }">
|
|
|
|
+ <el-input-number
|
|
|
|
+ size="small" min="0" :value="row.decimalDigits || 4" style="width: 120px"
|
|
|
|
+ v-model="row.decimalDigits" v-if="row.columnType === 'NUMBER'"
|
|
|
|
+ ></el-input-number>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="dialog-btns">
|
|
|
|
+ <el-button size="default" @click="$emit('closeDrawer')">取消</el-button>
|
|
|
|
+ <el-button size="default" type="primary" @click="onUploadConfirm">确定</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </el-dialog>
|
|
|
|
+</template>
|
|
|
|
+<script>
|
|
|
|
+import {getToken} from '@/utils/auth';
|
|
|
|
+import {dateFormat} from "/@/utils";
|
|
|
|
+import {tableFileUpload, getDatasourceDetail} from '@/api/ds';
|
|
|
|
+import useSystemStore from "/@/stores/modules/system";
|
|
|
|
+import {ElMessage, ElMessageBox, ElLoading} from "element-plus";
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ props: ['show', 'direction', 'datasourceId', "categoryId",],
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ fileUploadUrl: window._CONFIG.APIHead,
|
|
|
|
+ fileUploadHeaders: {Authorization: getToken()},
|
|
|
|
+ fileForm: {file: null, tableName: '', tableComment: '', tableColumnList: [], dsId: 0, classifyId: 0},
|
|
|
|
+ uploadLoading: false,
|
|
|
|
+ isOracle: false,
|
|
|
|
+ decimalDigits: '',
|
|
|
|
+ columnNameType: 'pinyinAllColumnName',
|
|
|
|
+ isCase: 'xiaoxie',
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ ...mapStores(useSystemStore),
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ show(val) {
|
|
|
|
+ this.fileForm.classifyId = this.categoryId
|
|
|
|
+ if (!val) {
|
|
|
|
+ this.fileForm = {...this.fileForm, file: null, tableName: '', tableComment: '', tableColumnList: []};
|
|
|
|
+ try {
|
|
|
|
+ this.$refs.upload.clearFiles();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.log(e)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ created() {
|
|
|
|
+ getDatasourceDetail({id: this.datasourceId}).then(res => {
|
|
|
|
+ if (res.data.dsTypeSyl === 'oracle') {
|
|
|
|
+ this.isOracle = true;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ onClose() {
|
|
|
|
+ this.$emit('closeDrawer')
|
|
|
|
+ },
|
|
|
|
+ handleClick(event) {
|
|
|
|
+ if (this.fileForm.file) {
|
|
|
|
+ event.preventDefault()
|
|
|
|
+ event.stopPropagation()
|
|
|
|
+ ElMessageBox.confirm('确定覆盖当前文件?', '提示', {
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
+ cancelButtonText: '取消',
|
|
|
|
+ type: 'warning'
|
|
|
|
+ }).then(() => {
|
|
|
|
+ this.$refs.upload.clearFiles()
|
|
|
|
+ this.onRemove()
|
|
|
|
+ this.$refs.uploadBtn.$el.click()
|
|
|
|
+ }).catch(() => {
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 文件上传确认提交
|
|
|
|
+ onUploadConfirm() {
|
|
|
|
+ if (!this.fileForm.file) {
|
|
|
|
+ return ElMessage({type: 'error', message: '请上传文件'});
|
|
|
|
+ }
|
|
|
|
+ if (!this.fileForm.tableName) {
|
|
|
|
+ return ElMessage({type: 'error', message: '请填写表名'});
|
|
|
|
+ }
|
|
|
|
+ if (!this.fileForm.tableComment) {
|
|
|
|
+ return ElMessage({type: 'error', message: '请填写表注释名'});
|
|
|
|
+ }
|
|
|
|
+ if (!/^[a-zA-Z][_\d\w]*$/g.test(this.fileForm.tableName)) {
|
|
|
|
+ return ElMessage({type: 'error', message: '请检查表名拼写'});
|
|
|
|
+ }
|
|
|
|
+ if (this.datasourceId) {
|
|
|
|
+ this.fileForm.dsId = this.datasourceId;
|
|
|
|
+ }
|
|
|
|
+ let data = {...this.fileForm};
|
|
|
|
+ delete data.tableColumnList;
|
|
|
|
+ let formData = new FormData();
|
|
|
|
+ Object.keys(data).forEach(k => formData.append(k, data[k]));
|
|
|
|
+ formData.append('tableColumnList', JSON.stringify(this.fileForm.tableColumnList));
|
|
|
|
+ this.uploadLoading = true;
|
|
|
|
+ tableFileUpload(formData).then(res => {
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
+ ElMessage({type: 'success', message: '上传成功'});
|
|
|
|
+ this.$emit('closeDrawer')
|
|
|
|
+ } else {
|
|
|
|
+ ElMessage({type: 'error', message: res.msg});
|
|
|
|
+ }
|
|
|
|
+ }).finally(() => (this.uploadLoading = false));
|
|
|
|
+ },
|
|
|
|
+ // 文件上传成功后
|
|
|
|
+ uploadSuccess(response, file) {
|
|
|
|
+ if (response.code === 200) {
|
|
|
|
+ this.structure = response.data
|
|
|
|
+ this.fileForm.file = file.raw;
|
|
|
|
+ this.getTableColumnList();
|
|
|
|
+ this.fileForm.tableComment = file.name.split('.')[0];
|
|
|
|
+ this.fileForm.tableName = 'file_table_' + dateFormat(new Date(), 'YYYYmmdd_HHMMSS');
|
|
|
|
+ } else {
|
|
|
|
+ ElMessage({type: 'error', message: response.msg || '服务器错误'});
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ onRemove() {
|
|
|
|
+ this.fileForm.file = null
|
|
|
|
+ this.fileForm.tableComment = ''
|
|
|
|
+ this.fileForm.tableName = ''
|
|
|
|
+ this.fileForm.tableColumnList = []
|
|
|
|
+ },
|
|
|
|
+ getTableColumnList() {
|
|
|
|
+ this.fileForm.tableColumnList = this.structure.map(i => {
|
|
|
|
+ i.columnName = i[this.columnNameType];
|
|
|
|
+ i.columnName = this.isCase === 'xiaoxie' ? i.columnName.toLowerCase() : i.columnName.toUpperCase();
|
|
|
|
+ i.columnSize = i.columnSize || 255;
|
|
|
|
+ i.decimalDigits = i.decimalDigits || 4;
|
|
|
|
+ return i;
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ // excel文件上传校验
|
|
|
|
+ beforeUpload(file) {
|
|
|
|
+ let nameArr = file.name.split('.');
|
|
|
|
+ if (!['xlsx', 'xls', 'csv'].includes(nameArr[nameArr.length - 1])) {
|
|
|
|
+ ElMessage({type: 'error', message: '请检查文件格式'});
|
|
|
|
+ return false;
|
|
|
|
+ } else {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ changeDecimalDigits(val) {
|
|
|
|
+ this.fileForm.tableColumnList = this.fileForm.tableColumnList.map(i => ({...i, decimalDigits: val || 4}));
|
|
|
|
+ },
|
|
|
|
+ changeString(row) {
|
|
|
|
+ if (row.columnType === 'NUMBER') {
|
|
|
|
+ row.columnSize = 20;
|
|
|
|
+ } else {
|
|
|
|
+ row.columnSize = 255;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+</script>
|
|
|
|
+<style lang="scss">
|
|
|
|
+.dataset-file-upload {
|
|
|
|
+ max-height: 80% !important;
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ .el-dialog__header {
|
|
|
|
+ flex: 0 0 56px;
|
|
|
|
+ margin: 0;
|
|
|
|
+ }
|
|
|
|
+ .el-dialog__body {
|
|
|
|
+ flex: 1;
|
|
|
|
+ overflow-y: auto;
|
|
|
|
+ }
|
|
|
|
+ .upload {
|
|
|
|
+ width: 100%;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ .el-upload-list__item {
|
|
|
|
+ margin-top: 0;
|
|
|
|
+ }
|
|
|
|
+ .el-upload-list {
|
|
|
|
+ flex: 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|