forked from github/dataease
feat(X-Pack): 数据填报批量上传数据
This commit is contained in:
parent
b045ad9b35
commit
ab6b49791a
@ -1,7 +1,7 @@
|
||||
package io.dataease.config;
|
||||
|
||||
import com.fit2cloud.autoconfigure.QuartzAutoConfiguration;
|
||||
import io.dataease.commons.utils.CommonThreadPool;
|
||||
import io.dataease.utils.CommonThreadPool;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.dataease.datasource.provider;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.dataease.commons.utils.CommonThreadPool;
|
||||
import io.dataease.dataset.utils.FieldUtils;
|
||||
import io.dataease.datasource.dao.auto.entity.CoreDatasource;
|
||||
import io.dataease.datasource.dao.auto.entity.CoreDriver;
|
||||
@ -16,10 +15,7 @@ import io.dataease.extensions.datasource.provider.ExtendedJdbcClassLoader;
|
||||
import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.CommonBeanFactory;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import io.dataease.utils.*;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.calcite.adapter.jdbc.JdbcSchema;
|
||||
|
@ -14,7 +14,6 @@ import io.dataease.api.ds.vo.CoreDatasourceTaskLogDTO;
|
||||
import io.dataease.api.ds.vo.ExcelFileData;
|
||||
import io.dataease.api.ds.vo.ExcelSheetData;
|
||||
import io.dataease.commons.constants.TaskStatus;
|
||||
import io.dataease.commons.utils.CommonThreadPool;
|
||||
import io.dataease.constant.LogOT;
|
||||
import io.dataease.constant.LogST;
|
||||
import io.dataease.dataset.manage.DatasetDataManage;
|
||||
|
@ -1,226 +0,0 @@
|
||||
import request from '@/config/axios'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
export function formatDate(value, dateType) {
|
||||
if (!value) {
|
||||
return value
|
||||
}
|
||||
switch (dateType) {
|
||||
case 'year':
|
||||
return dayjs(value).format('YYYY')
|
||||
case 'month':
|
||||
case 'monthrange':
|
||||
return dayjs(value).format('YYYY-MM')
|
||||
case 'datetime':
|
||||
case 'datetimerange':
|
||||
return dayjs(value).format('YYYY-MM-DD HH:mm:ss')
|
||||
default:
|
||||
return dayjs(value).format('YYYY-MM-DD')
|
||||
}
|
||||
}
|
||||
export interface ColumnItem {
|
||||
props: string
|
||||
label: string
|
||||
date: boolean
|
||||
dateType?: string
|
||||
type: string
|
||||
multiple: boolean
|
||||
rangeIndex?: number
|
||||
disabled?: boolean
|
||||
}
|
||||
export interface DataFillingOrFolder {
|
||||
name: string
|
||||
action?: string
|
||||
id?: number | string
|
||||
pid?: number | string
|
||||
nodeType: 'folder' | 'data-filling'
|
||||
union?: Array<{}>
|
||||
allFields?: Array<{}>
|
||||
}
|
||||
|
||||
export interface Tree {
|
||||
name: string
|
||||
value?: string | number
|
||||
id: string | number
|
||||
nodeType: string
|
||||
createBy?: string
|
||||
level: number
|
||||
leaf?: boolean
|
||||
pid: string | number
|
||||
type?: string
|
||||
createTime: number
|
||||
children?: Tree[]
|
||||
request: any
|
||||
}
|
||||
|
||||
export interface DfFormSetting {
|
||||
id?: string
|
||||
name?: string
|
||||
pid?: string
|
||||
datasource?: string
|
||||
tableName?: string
|
||||
forms: Array<DfFormItem>
|
||||
createIndex: boolean
|
||||
tableIndexes: Array<any>
|
||||
|
||||
creator?: string
|
||||
updater?: string
|
||||
createTime?: number
|
||||
updateTime?: number
|
||||
weight?: number
|
||||
}
|
||||
|
||||
export interface DfFormItem {
|
||||
type: string
|
||||
typeName: string
|
||||
icon: string
|
||||
order?: number
|
||||
value?: any
|
||||
id?: string
|
||||
settings: FormItemSetting
|
||||
old?: boolean
|
||||
removed?: boolean
|
||||
}
|
||||
|
||||
export interface FormItemSetting {
|
||||
name?: string
|
||||
placeholder?: string
|
||||
required?: boolean
|
||||
unique?: boolean
|
||||
inputType?: string
|
||||
optionSourceType?: 1 | 2
|
||||
optionDatasource?: number
|
||||
optionTable?: string
|
||||
optionColumn?: string
|
||||
optionOrder?: string
|
||||
multiple?: boolean
|
||||
dateType?: 'date' | 'daterange'
|
||||
rangeSeparator?: string
|
||||
startPlaceholder?: string
|
||||
endPlaceholder?: string
|
||||
options?: Array<FormItemSettingOptions>
|
||||
mapping: {
|
||||
columnName?: string
|
||||
columnName1?: string
|
||||
columnName2?: string
|
||||
type?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface FormItemSettingOptions {
|
||||
name: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface SimpleDatasource {
|
||||
id: string
|
||||
pid: string
|
||||
name: string
|
||||
type: string
|
||||
typeAlias: string
|
||||
status: string
|
||||
enableDataFill: boolean
|
||||
}
|
||||
|
||||
export const listDataFillingForms = async (data): Promise<any> => {
|
||||
return request
|
||||
.post({ url: '/data-filling/tree', data: { ...data, ...{ busiFlag: 'data-filling' } } })
|
||||
.then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
|
||||
export const createFolder = (data = {}): Promise<any> => {
|
||||
return request
|
||||
.post({ url: '/data-filling/save', data: { ...data, nodeType: 'folder' } })
|
||||
.then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
export const save = (data = {}): Promise<any> => {
|
||||
return request.post({ url: '/data-filling/save', data }).then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
|
||||
export const move = (data = {}): Promise<any> => {
|
||||
return request.post({ url: '/data-filling/move', data }).then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
|
||||
export const reName = (data = {}): Promise<any> => {
|
||||
return request.post({ url: '/data-filling/rename', data }).then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
export const listDatasourceList = (): Promise<Array<SimpleDatasource>> => {
|
||||
return request.get({ url: '/data-filling/datasource/list' }).then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
|
||||
export const getDataFilling = async (id: string): Promise<any> => {
|
||||
return request.get({ url: `/data-filling/get/${id}` }).then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteById = (id: string): Promise<any> => {
|
||||
return request.get({ url: '/data-filling/delete/' + id })
|
||||
}
|
||||
|
||||
export const deleteRowData = (formId: string, id: number): Promise<any> => {
|
||||
return request.get({ url: `/data-filling/form/${formId}/delete/${id}` })
|
||||
}
|
||||
|
||||
export const batchDeleteRowData = (formId: string, data: Array<any>): Promise<any> => {
|
||||
return request.post({ url: `/data-filling/form/${formId}/batch-delete`, data })
|
||||
}
|
||||
|
||||
export const getTableColumnData = (
|
||||
optionDatasource,
|
||||
optionTable,
|
||||
optionColumn,
|
||||
optionOrder
|
||||
): Promise<any> => {
|
||||
return request.post({
|
||||
url: `/data-filling/form/${optionDatasource}/options`,
|
||||
data: {
|
||||
optionTable: optionTable,
|
||||
optionColumn: optionColumn,
|
||||
optionOrder: optionOrder
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const searchTable = (id, data): Promise<any> => {
|
||||
return request.post({
|
||||
url: '/data-filling/form/' + id + '/tableData',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const saveFormRowData = (formId, data): Promise<any> => {
|
||||
return request
|
||||
.post({
|
||||
url: '/data-filling/form/' + formId + '/rowData/save',
|
||||
data
|
||||
})
|
||||
.then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
|
||||
export const saveTask = (data): Promise<any> => {
|
||||
return request.post({
|
||||
url: `/data-filling/task/save`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const getTaskInfo = (taskId): Promise<any> => {
|
||||
return request.get({
|
||||
url: `/data-filling/task/info/${taskId}`
|
||||
})
|
||||
}
|
@ -376,6 +376,7 @@ export default {
|
||||
commit_time: 'Commit Time',
|
||||
confirm_delete: 'Confirm delete?',
|
||||
add_data: 'Add Data',
|
||||
batch_upload: 'Upload Data',
|
||||
download_template: 'Download Template',
|
||||
insert_data: 'Insert Data',
|
||||
update_data: 'Update Data',
|
||||
|
@ -277,6 +277,7 @@ export default {
|
||||
commit_time: '提交時間',
|
||||
confirm_delete: '確認刪除?',
|
||||
add_data: '添加數據',
|
||||
batch_upload: '批量上傳',
|
||||
download_template: '下載模板',
|
||||
insert_data: '插入數據',
|
||||
update_data: '更新數據',
|
||||
|
@ -2707,6 +2707,7 @@ export default {
|
||||
commit_time: '提交时间',
|
||||
confirm_delete: '确认删除?',
|
||||
add_data: '添加数据',
|
||||
batch_upload: '批量上传',
|
||||
download_template: '下载模板',
|
||||
insert_data: '插入数据',
|
||||
update_data: '更新数据',
|
||||
|
@ -7,7 +7,6 @@ import type { BusiTreeRequest, BusiTreeNode } from '@/models/tree/TreeNode'
|
||||
import { pathValid } from '@/store/modules/permission'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
||||
import { listDataFillingForms } from '@/api/data-filling'
|
||||
const appStore = useAppStoreWithOut()
|
||||
const { wsCache } = useCache()
|
||||
export interface InnerInteractive {
|
||||
@ -22,9 +21,9 @@ interface InteractiveState {
|
||||
data: Record<number, InnerInteractive>
|
||||
}
|
||||
|
||||
const apiMap = [queryTreeApi, queryTreeApi, getDatasetTree, listDatasources, listDataFillingForms]
|
||||
const apiMap = [queryTreeApi, queryTreeApi, getDatasetTree, listDatasources]
|
||||
|
||||
const busiFlagMap = ['dashboard', 'dataV', 'dataset', 'datasource', 'data-filling']
|
||||
const busiFlagMap = ['dashboard', 'dataV', 'dataset', 'datasource']
|
||||
|
||||
export const interactiveStore = defineStore('interactive', {
|
||||
state: (): InteractiveState => ({
|
||||
|
@ -1,10 +1,16 @@
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
defineProps({
|
||||
name: propTypes.string.def(''),
|
||||
size: propTypes.number.def(0),
|
||||
showDel: propTypes.bool.def(false)
|
||||
})
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
name?: string
|
||||
size?: number
|
||||
showDel?: boolean
|
||||
}>(),
|
||||
{
|
||||
name: '',
|
||||
size: 0,
|
||||
showDel: false
|
||||
}
|
||||
)
|
||||
|
||||
const emits = defineEmits(['del'])
|
||||
const del = () => {
|
||||
|
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
||||
Subproject commit f02fc6a6f62bad5b32f2ac70111ea66dcf6c9dd9
|
||||
Subproject commit 02f340953f92c485ea48229baf5ae73e59033301
|
@ -12,10 +12,8 @@ import io.dataease.extensions.datasource.dto.SimpleDatasourceDTO;
|
||||
import io.dataease.model.BusiNodeRequest;
|
||||
import io.dataease.model.BusiNodeVO;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -110,4 +108,12 @@ public interface DataFillingApi {
|
||||
IPage<DfCommitLog> taskPager(@PathVariable("goPage") int goPage, @PathVariable("pageSize") int pageSize, @RequestBody DfCommitLogRequest request);
|
||||
|
||||
|
||||
@PostMapping("/form/{formId}/uploadFile")
|
||||
DfExcelData excelUpload(@RequestParam("file") MultipartFile file, @PathVariable("formId") Long formId) throws Exception;
|
||||
|
||||
@GetMapping("/form/{formId}/excelTemplate")
|
||||
void excelTemplate(@PathVariable("formId") Long formId);
|
||||
|
||||
@PostMapping("/form/{formId}/confirmUpload")
|
||||
void confirmUpload(@PathVariable("formId") Long formId, @RequestBody Map<String, String> data);
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package io.dataease.api.xpack.dataFilling.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Getter
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DatasourceOptionsRequest {
|
||||
|
||||
private String optionTable;
|
||||
|
@ -0,0 +1,26 @@
|
||||
package io.dataease.api.xpack.dataFilling.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DfExcelData implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1162581256875641808L;
|
||||
|
||||
private List<ExtTableField> formFields;
|
||||
|
||||
private List<RowDataDatum> dataList;
|
||||
|
||||
private String id;
|
||||
private String excelName;
|
||||
private String path;
|
||||
private String suffix;
|
||||
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
package io.dataease.api.xpack.dataFilling.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ExtTableField implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 9021129395822053871L;
|
||||
|
||||
private String type;
|
||||
|
||||
private String typeName;
|
||||
|
||||
private String icon;
|
||||
|
||||
private String id;
|
||||
|
||||
private ExtTableFieldSetting settings;
|
||||
|
||||
private boolean removed;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class ExtTableFieldSetting implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 8776508642526681125L;
|
||||
|
||||
private String name;
|
||||
|
||||
private boolean required;
|
||||
|
||||
private ExtTableFieldMapping mapping;
|
||||
|
||||
private String rangeSeparator;
|
||||
|
||||
private boolean unique;
|
||||
|
||||
private String inputType;
|
||||
|
||||
private String dateType;
|
||||
|
||||
private String placeholder;
|
||||
private String startPlaceholder;
|
||||
private String endPlaceholder;
|
||||
|
||||
private Integer optionSourceType;
|
||||
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long optionDatasource;
|
||||
private String optionTable;
|
||||
private String optionColumn;
|
||||
private String optionOrder;
|
||||
|
||||
private boolean multiple;
|
||||
|
||||
private boolean updateRuleCheck;
|
||||
|
||||
private List<Option> options;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Option implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -1681618296840344071L;
|
||||
|
||||
private String name;
|
||||
|
||||
private Object value;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class ExtTableFieldMapping implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 4233066732126872840L;
|
||||
|
||||
private String columnName;
|
||||
|
||||
//dateRange下对应两个字段
|
||||
private String columnName1;
|
||||
private String columnName2;
|
||||
|
||||
private String oldColumnName;
|
||||
private String oldColumnName1;
|
||||
private String oldColumnName2;
|
||||
|
||||
private BaseType type;
|
||||
|
||||
//长度
|
||||
private Integer size;
|
||||
//精度
|
||||
private Integer accuracy;
|
||||
|
||||
}
|
||||
|
||||
public enum BaseType {
|
||||
nvarchar, //字符串
|
||||
text, //长文本
|
||||
number, //整型数字
|
||||
decimal, //小数数字
|
||||
datetime //日期
|
||||
}
|
||||
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class TableField implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 85092190247927362L;
|
||||
|
||||
private String columnName;
|
||||
|
||||
private String oldColumnName;
|
||||
|
||||
private BaseType type;
|
||||
|
||||
private boolean required;
|
||||
|
||||
private boolean primaryKey;
|
||||
|
||||
//长度
|
||||
private Integer size;
|
||||
//精度
|
||||
private Integer accuracy;
|
||||
|
||||
private String comment;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package io.dataease.api.xpack.dataFilling.dto;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class RowDataDatum implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -2838784450721979776L;
|
||||
|
||||
private Long id;
|
||||
|
||||
private Map<String, Object> data;
|
||||
|
||||
private boolean insert;
|
||||
}
|
@ -2,8 +2,10 @@ package io.dataease.exception;
|
||||
|
||||
import io.dataease.result.ResultCode;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DEException extends RuntimeException {
|
||||
|
||||
private int code;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package io.dataease.commons.utils;
|
||||
package io.dataease.utils;
|
||||
|
||||
import io.dataease.utils.LogUtil;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
|
Loading…
Reference in New Issue
Block a user