feat(X-Pack): 增加数据填报功能

This commit is contained in:
ulleo 2024-08-07 14:17:41 +08:00
parent 2ad432a3e8
commit b04d91b240
54 changed files with 1836 additions and 38 deletions

View File

@ -7,11 +7,11 @@ import java.io.Serializable;
/**
* <p>
*
* 数据源表
* </p>
*
* @author fit2cloud
* @since 2023-09-26
* @since 2024-07-09
*/
@TableName("core_datasource")
public class CoreDatasource implements Serializable {
@ -89,6 +89,11 @@ public class CoreDatasource implements Serializable {
*/
private String taskStatus;
/**
* 开启数据填报
*/
private Boolean enableDataFill;
public Long getId() {
return id;
}
@ -201,6 +206,14 @@ public class CoreDatasource implements Serializable {
this.taskStatus = taskStatus;
}
public Boolean getEnableDataFill() {
return enableDataFill;
}
public void setEnableDataFill(Boolean enableDataFill) {
this.enableDataFill = enableDataFill;
}
@Override
public String toString() {
return "CoreDatasource{" +
@ -218,6 +231,7 @@ public class CoreDatasource implements Serializable {
", status = " + status +
", qrtzInstance = " + qrtzInstance +
", taskStatus = " + taskStatus +
", enableDataFill = " + enableDataFill +
"}";
}
}

View File

@ -6,11 +6,11 @@ import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper 接口
* 数据源表 Mapper 接口
* </p>
*
* @author fit2cloud
* @since 2023-09-26
* @since 2024-07-09
*/
@Mapper
public interface CoreDatasourceMapper extends BaseMapper<CoreDatasource> {

View File

@ -26,10 +26,10 @@ import org.apache.calcite.adapter.jdbc.JdbcSchema;
import org.apache.calcite.jdbc.CalciteConnection;
import org.apache.calcite.schema.Schema;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.io.File;
import java.io.IOException;
@ -54,6 +54,7 @@ public class CalciteProvider extends Provider {
private final String FILE_PATH = "/opt/dataease2.0/drivers";
private final String CUSTOM_PATH = "/opt/dataease2.0/custom-drivers/";
private static String split = "DE";
@Resource
private CommonThreadPool commonThreadPool;
@ -214,7 +215,9 @@ public class CalciteProvider extends Provider {
List<TableField> datasetTableFields = new ArrayList<>();
DatasourceSchemaDTO datasourceSchemaDTO = datasourceRequest.getDsList().entrySet().iterator().next().getValue();
datasourceRequest.setDatasource(datasourceSchemaDTO);
DatasourceConfiguration datasourceConfiguration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), DatasourceConfiguration.class);
String table = datasourceRequest.getTable();
if (StringUtils.isEmpty(table)) {
ResultSet resultSet = null;
@ -371,11 +374,20 @@ public class CalciteProvider extends Provider {
// schema
ResultSet resultSet = null;
try (ConnectionObj con = getConnection(datasourceRequest.getDatasource());
Statement statement = getStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout())) {
PreparedStatement statement = getPreparedStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout(), datasourceRequest.getQuery())) {
if (DatasourceConfiguration.DatasourceType.valueOf(value.getType()) == DatasourceConfiguration.DatasourceType.oracle) {
statement.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA = " + datasourceConfiguration.getSchema());
}
resultSet = statement.executeQuery(datasourceRequest.getQuery());
if (CollectionUtils.isNotEmpty(datasourceRequest.getTableFieldWithValues())) {
LogUtil.info("execWithPreparedStatement sql: " + datasourceRequest.getQuery());
for (int i = 0; i < datasourceRequest.getTableFieldWithValues().size(); i++) {
statement.setObject(i + 1, datasourceRequest.getTableFieldWithValues().get(i).getValue(), datasourceRequest.getTableFieldWithValues().get(i).getType());
LogUtil.info("execWithPreparedStatement param[" + (i + 1) + "]: " + datasourceRequest.getTableFieldWithValues().get(i).getValue());
}
}
resultSet = statement.executeQuery();
fieldList = getField(resultSet, datasourceRequest);
dataList = getData(resultSet, datasourceRequest);
} catch (SQLException e) {
@ -397,6 +409,88 @@ public class CalciteProvider extends Provider {
return map;
}
@Override
public void exec(DatasourceRequest datasourceRequest) throws DEException {
DatasourceSchemaDTO value = datasourceRequest.getDsList().entrySet().iterator().next().getValue();
datasourceRequest.setDatasource(value);
DatasourceConfiguration datasourceConfiguration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), DatasourceConfiguration.class);
// schema
ResultSet resultSet = null;
try (ConnectionObj con = getConnection(datasourceRequest.getDatasource());
PreparedStatement statement = getPreparedStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout(), datasourceRequest.getQuery())) {
if (DatasourceConfiguration.DatasourceType.valueOf(value.getType()) == DatasourceConfiguration.DatasourceType.oracle) {
statement.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA = " + datasourceConfiguration.getSchema());
}
if (CollectionUtils.isNotEmpty(datasourceRequest.getTableFieldWithValues())) {
LogUtil.info("execWithPreparedStatement sql: " + datasourceRequest.getQuery());
for (int i = 0; i < datasourceRequest.getTableFieldWithValues().size(); i++) {
statement.setObject(i + 1, datasourceRequest.getTableFieldWithValues().get(i).getValue(), datasourceRequest.getTableFieldWithValues().get(i).getType());
LogUtil.info("execWithPreparedStatement param[" + (i + 1) + "]: " + datasourceRequest.getTableFieldWithValues().get(i).getValue());
}
}
statement.execute();
} catch (SQLException e) {
DEException.throwException("SQL ERROR: " + e.getMessage());
} catch (Exception e) {
DEException.throwException("Data source connection exception: " + e.getMessage());
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
@Override
public int executeUpdate(DatasourceRequest datasourceRequest) throws DEException {
DatasourceSchemaDTO value = datasourceRequest.getDsList().entrySet().iterator().next().getValue();
datasourceRequest.setDatasource(value);
DatasourceConfiguration datasourceConfiguration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), DatasourceConfiguration.class);
// schema
ResultSet resultSet = null;
try (ConnectionObj con = getConnection(datasourceRequest.getDatasource());
PreparedStatement statement = getPreparedStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout(), datasourceRequest.getQuery())) {
if (DatasourceConfiguration.DatasourceType.valueOf(value.getType()) == DatasourceConfiguration.DatasourceType.oracle) {
statement.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA = " + datasourceConfiguration.getSchema());
}
if (CollectionUtils.isNotEmpty(datasourceRequest.getTableFieldWithValues())) {
LogUtil.info("execWithPreparedStatement sql: " + datasourceRequest.getQuery());
for (int i = 0; i < datasourceRequest.getTableFieldWithValues().size(); i++) {
statement.setObject(i + 1, datasourceRequest.getTableFieldWithValues().get(i).getValue(), datasourceRequest.getTableFieldWithValues().get(i).getType());
LogUtil.info("execWithPreparedStatement param[" + (i + 1) + "]: " + datasourceRequest.getTableFieldWithValues().get(i).getValue());
}
}
return statement.executeUpdate();
} catch (SQLException e) {
DEException.throwException("SQL ERROR: " + e.getMessage());
} catch (Exception e) {
DEException.throwException("Data source connection exception: " + e.getMessage());
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return 0;
}
private List<TableField> getField(ResultSet rs, DatasourceRequest datasourceRequest) throws Exception {
List<TableField> fieldList = new ArrayList<>();
ResultSetMetaData metaData = rs.getMetaData();
@ -588,14 +682,14 @@ public class CalciteProvider extends Provider {
String[] databasePrams = matcher.group(3).split("\\?");
database = databasePrams[0];
}
sql = String.format("SELECT COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'", database, datasourceRequest.getTable());
sql = String.format("SELECT COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT,IF(COLUMN_KEY='PRI',1,0) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'", database, datasourceRequest.getTable());
break;
case oracle:
configuration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), Oracle.class);
if (StringUtils.isEmpty(configuration.getSchema())) {
DEException.throwException(Translator.get("i18n_schema_is_empty"));
}
sql = String.format("SELECT a.COLUMN_NAME , a.DATA_TYPE , b.COMMENTS FROM all_tab_columns a LEFT JOIN all_col_comments b ON a.owner = b.owner AND a.table_name = b.table_name AND a.column_name = b.column_name WHERE a.owner = '%s' AND a.table_name = '%s' ORDER BY a.table_name, a.column_id", configuration.getSchema(), datasourceRequest.getTable());
sql = String.format("SELECT a.COLUMN_NAME , a.DATA_TYPE , b.COMMENTS ,0 FROM all_tab_columns a LEFT JOIN all_col_comments b ON a.owner = b.owner AND a.table_name = b.table_name AND a.column_name = b.column_name WHERE a.owner = '%s' AND a.table_name = '%s' ORDER BY a.table_name, a.column_id", configuration.getSchema(), datasourceRequest.getTable());
break;
case db2:
configuration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), Db2.class);
@ -611,7 +705,7 @@ public class CalciteProvider extends Provider {
}
sql = String.format("SELECT \n" +
" c.name ,t.name ,ep.value \n" +
" c.name ,t.name ,ep.value, 0 \n" +
"FROM \n" +
" sys.columns AS c\n" +
"LEFT JOIN sys.extended_properties AS ep ON c.object_id = ep.major_id AND c.column_id = ep.minor_id\n" +
@ -627,7 +721,8 @@ public class CalciteProvider extends Provider {
sql = String.format("SELECT\n" +
" a.attname AS ColumnName,\n" +
" t.typname,\n" +
" b.description AS ColumnDescription\n" +
" b.description AS ColumnDescription,\n" +
" 0\n" +
"FROM\n" +
" pg_class c\n" +
" JOIN pg_attribute a ON a.attrelid = c.oid\n" +
@ -646,7 +741,8 @@ public class CalciteProvider extends Provider {
sql = String.format("SELECT\n" +
" a.attname AS ColumnName,\n" +
" t.typname,\n" +
" b.description AS ColumnDescription\n" +
" b.description AS ColumnDescription,\n" +
" 0\n" +
"FROM\n" +
" pg_class c\n" +
" JOIN pg_attribute a ON a.attrelid = c.oid\n" +
@ -675,7 +771,8 @@ public class CalciteProvider extends Provider {
sql = String.format(" SELECT\n" +
" name,\n" +
" type,\n" +
" comment\n" +
" comment,\n" +
" 0\n" +
"FROM\n" +
" system.columns\n" +
"WHERE\n" +
@ -702,6 +799,10 @@ public class CalciteProvider extends Provider {
tableField.setDeExtractType(deType);
tableField.setDeType(deType);
tableField.setName(resultSet.getString(3));
try {
tableField.setPrimary(resultSet.getInt(4) > 0);
} catch (Exception e) {
}
return tableField;
}
@ -1092,6 +1193,32 @@ public class CalciteProvider extends Provider {
}
}
public Statement getStatement(Connection connection, int queryTimeout) {
if (connection == null) {
DEException.throwException("Failed to get connection!");
}
Statement stat = null;
try {
stat = connection.createStatement();
stat.setQueryTimeout(queryTimeout);
} catch (Exception e) {
DEException.throwException(e.getMessage());
}
return stat;
}
public PreparedStatement getPreparedStatement(Connection connection, int queryTimeout, String sql) throws Exception {
if (connection == null) {
throw new Exception("Failed to get connection!");
}
PreparedStatement stat = connection.prepareStatement(sql);
try {
stat.setQueryTimeout(queryTimeout);
} catch (Exception e) {
}
return stat;
}
protected boolean isDefaultClassLoader(String customDriver) {
return StringUtils.isEmpty(customDriver) || customDriver.equalsIgnoreCase("default");
}

View File

@ -1,5 +1,6 @@
package io.dataease.datasource.server;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -356,7 +357,8 @@ public class DatasourceServer implements DatasourceApi {
List<String> toCreateTables = new ArrayList<>();
List<String> toDeleteTables = new ArrayList<>();
if (dataSourceDTO.getType().equals(DatasourceConfiguration.DatasourceType.API.name())) {
List<String> sourceTables = ApiUtils.getTables(sourceTableRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList());
requestDatasource.setEnableDataFill(null);
List<String> sourceTables = ApiUtils.getTables(sourceTableRequest).stream().map(DatasetTableDTO::getTableName).toList();
List<DatasetTableDTO> datasetTableDTOS = ApiUtils.getTables(datasourceRequest);
List<String> tables = datasetTableDTOS.stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList());
checkName(datasetTableDTOS.stream().map(DatasetTableDTO::getName).collect(Collectors.toList()));
@ -410,6 +412,7 @@ public class DatasourceServer implements DatasourceApi {
dataSourceManage.checkName(dataSourceDTO);
dataSourceManage.innerEdit(requestDatasource);
} else if (dataSourceDTO.getType().equals(DatasourceConfiguration.DatasourceType.Excel.name())) {
requestDatasource.setEnableDataFill(null);
List<String> sourceTables = ExcelUtils.getTables(sourceTableRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList());
List<String> tables = ExcelUtils.getTables(datasourceRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList());
if (dataSourceDTO.getEditType() == 0) {
@ -439,6 +442,9 @@ public class DatasourceServer implements DatasourceApi {
dataSourceManage.innerEdit(requestDatasource);
}
} else {
if (!LicenseUtil.licenseValid()) {
requestDatasource.setEnableDataFill(null);
}
checkParams(dataSourceDTO.getConfiguration());
dataSourceManage.checkName(dataSourceDTO);
dataSourceManage.innerEdit(requestDatasource);
@ -515,12 +521,39 @@ public class DatasourceServer implements DatasourceApi {
return getDatasourceDTOById(datasourceId, false);
}
@Override
public DatasourceDTO innerGet(Long datasourceId) throws DEException {
return getDatasourceDTOById(datasourceId, false);
}
@Override
public List<DatasourceDTO> innerList(List<Long> ids) throws DEException {
List<DatasourceDTO> list = new ArrayList<>();
LambdaQueryWrapper<CoreDatasource> queryWrapper = new LambdaQueryWrapper<>();
if (ids != null) {
if (ids.isEmpty()) {
return list;
} else {
queryWrapper.in(CoreDatasource::getId, ids);
}
}
List<CoreDatasource> dsList = datasourceMapper.selectList(queryWrapper);
for (CoreDatasource datasource : dsList) {
list.add(convertCoreDatasource(datasource.getId(), false, datasource));
}
return list;
}
private DatasourceDTO getDatasourceDTOById(Long datasourceId, boolean hidePw) throws DEException {
DatasourceDTO datasourceDTO = new DatasourceDTO();
CoreDatasource datasource = datasourceMapper.selectById(datasourceId);
if (datasource == null) {
DEException.throwException("不存在的数据源!");
}
return convertCoreDatasource(datasourceId, hidePw, datasource);
}
private DatasourceDTO convertCoreDatasource(Long datasourceId, boolean hidePw, CoreDatasource datasource) {
DatasourceDTO datasourceDTO = new DatasourceDTO();
BeanUtils.copyBean(datasourceDTO, datasource);
if (datasourceDTO.getType().equalsIgnoreCase(DatasourceConfiguration.DatasourceType.API.toString())) {

View File

@ -1,5 +1,6 @@
package io.dataease.listener;
import io.dataease.job.schedule.DeDataFillingTaskExecutor;
import io.dataease.job.schedule.DeTaskExecutor;
import io.dataease.license.utils.LicenseUtil;
import io.dataease.utils.LogUtil;
@ -16,6 +17,9 @@ public class XpackTaskStarter implements ApplicationRunner {
@Resource
private DeTaskExecutor deTaskExecutor;
@Resource
private DeDataFillingTaskExecutor deDataFillingTaskExecutor;
@Override
public void run(ApplicationArguments args) {
try {
@ -24,5 +28,11 @@ public class XpackTaskStarter implements ApplicationRunner {
} catch (Exception e) {
LogUtil.error(e.getMessage(), e.getCause());
}
try {
LicenseUtil.validate();
deDataFillingTaskExecutor.init();
} catch (Exception e) {
LogUtil.error(e.getMessage(), e.getCause());
}
}
}

View File

@ -100,6 +100,8 @@ public class MenuManage {
|| coreMenu.getId().equals(28L)
|| coreMenu.getId().equals(35L)
|| coreMenu.getId().equals(40L)
|| coreMenu.getId().equals(50L);
|| coreMenu.getId().equals(50L)
|| coreMenu.getId().equals(60L)
|| coreMenu.getId().equals(61L);
}
}

View File

@ -12,6 +12,7 @@ i18n_menu.template-setting=\u6A21\u677F\u7BA1\u7406
i18n_menu.view=\u6570\u636E\u5C55\u793A
i18n_menu.data=\u6570\u636E\u51C6\u5907
i18n_menu.panel=\u4EEA\u8868\u677F
i18n_menu.data-filling-manage=\u6570\u636E\u586B\u62A5
i18n_menu.screen=\u6570\u636E\u5927\u5C4F
i18n_menu.dataset=\u6570\u636E\u96C6
i18n_menu.datasource=\u6570\u636E\u6E90
@ -43,7 +44,7 @@ i18n_table_duplicate=\u76F8\u540C\u8282\u70B9\u9700\u91CD\u65B0\u62D6\u5165\u624
i18n_no_column_permission=\u6CA1\u6709\u5217\u6743\u9650
i18n_fetch_error=SQL\u6267\u884C\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u8868\u3001\u5B57\u6BB5\u3001\u5173\u8054\u5173\u7CFB\u7B49\u4FE1\u606F\u662F\u5426\u6B63\u786E\u5E76\u91CD\u65B0\u7F16\u8F91\u3002
i18n_no_datasource_permission=\u65E0\u6570\u636E\u6E90\u8BBF\u95EE\u6743\u9650
i18n_no_dataset_permission=\u65e0\u6570\u636e\u96c6\u8bbf\u95ee\u6743\u9650
i18n_no_dataset_permission=\u65E0\u6570\u636E\u96C6\u8BBF\u95EE\u6743\u9650
i18n_not_full=\u5F53\u524D\u6570\u636E\u6E90\u4E0D\u652F\u6301\u5168\u8FDE\u63A5
i18n_field_circular_ref=\u5B57\u6BB5\u5B58\u5728\u5FAA\u73AF\u5F15\u7528

View File

@ -0,0 +1,226 @@
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}`
})
}

View File

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 2.5C4 1.94772 4.44772 1.5 5 1.5H14.8608C14.9949 1.5 15.1234 1.55387 15.2174 1.64951L19.8566 6.36941C19.9485 6.46292 20 6.58879 20 6.7199V21.5C20 22.0523 19.5523 22.5 19 22.5H5C4.44772 22.5 4 22.0523 4 21.5V2.5Z" fill="#3370FF"/>
<path d="M15 1.51978C15.0817 1.54345 15.1567 1.58778 15.2174 1.64952L19.8566 6.36942C19.8946 6.40806 19.9256 6.45223 19.949 6.50001H16.1351C15.5082 6.50001 15 5.99179 15 5.36488V1.51978Z" fill="#2B5FD9"/>
<path d="M8.07282 10.1818H15.6546C15.745 10.1818 15.8183 10.2551 15.8183 10.3455V11.1091C15.8183 11.1995 15.745 11.2727 15.6546 11.2727H8.07282C7.98244 11.2727 7.90918 11.1995 7.90918 11.1091V10.3455C7.90918 10.2551 7.98244 10.1818 8.07282 10.1818ZM8.07282 13.4546H15.6546C15.745 13.4546 15.8183 13.5278 15.8183 13.6182V14.3818C15.8183 14.4722 15.745 14.5455 15.6546 14.5455H8.07282C7.98244 14.5455 7.90918 14.4722 7.90918 14.3818V13.6182C7.90918 13.5278 7.98244 13.4546 8.07282 13.4546ZM8.07282 16.7273H12.1092C12.1996 16.7273 12.2728 16.8005 12.2728 16.8909V17.6546C12.2728 17.7449 12.1996 17.8182 12.1092 17.8182H8.07282C7.98244 17.8182 7.90918 17.7449 7.90918 17.6546V16.8909C7.90918 16.8005 7.98244 16.7273 8.07282 16.7273Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,11 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_8693_7580)">
<path d="M1.33332 2H14.6667C15.0348 2 15.3333 2.29848 15.3333 2.66667V13.3333C15.3333 13.7015 15.0348 14 14.6667 14H1.33332C0.965133 14 0.666656 13.7015 0.666656 13.3333V2.66667C0.666656 2.29848 0.965133 2 1.33332 2ZM1.99999 3.33333V12.6667H14V3.33333H1.99999Z" fill="#646A73"/>
<path d="M4.66667 5.02255C4.66667 4.82618 4.50748 4.66699 4.31112 4.66699H3.68889C3.49253 4.66699 3.33334 4.82618 3.33334 5.02255L3.33325 7.00033C3.33325 7.19669 3.49244 7.35588 3.68881 7.35588H4.31103C4.5074 7.35588 4.66659 7.19669 4.66659 7.00033L4.66667 5.02255Z" fill="#646A73"/>
</g>
<defs>
<clipPath id="clip0_8693_7580">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 812 B

View File

@ -0,0 +1,11 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_8693_4607)">
<path d="M7.99999 15.3337C12.0501 15.3337 15.3333 12.0504 15.3333 8.00033C15.3333 3.95024 12.0501 0.666992 7.99999 0.666992C3.9499 0.666992 0.666656 3.95024 0.666656 8.00033C0.666656 12.0504 3.9499 15.3337 7.99999 15.3337ZM7.99999 14.0003C4.68628 14.0003 1.99999 11.314 1.99999 8.00033C1.99999 4.68662 4.68628 2.00033 7.99999 2.00033C11.3137 2.00033 14 4.68662 14 8.00033C14 11.314 11.3137 14.0003 7.99999 14.0003Z" fill="#646A73"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.00001 10.6663C9.47277 10.6663 10.6667 9.47243 10.6667 7.99967C10.6667 6.52692 9.47277 5.33301 8.00001 5.33301C6.52725 5.33301 5.33334 6.52692 5.33334 7.99967C5.33334 9.47243 6.52725 10.6663 8.00001 10.6663Z" fill="#646A73"/>
</g>
<defs>
<clipPath id="clip0_8693_4607">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 959 B

View File

@ -0,0 +1,11 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_8096_189573)">
<path d="M1.33335 4H14.6667C15.0349 4 15.3334 4.29848 15.3334 4.66667V11.3333C15.3334 11.7015 15.0349 12 14.6667 12H1.33335C0.965164 12 0.666687 11.7015 0.666687 11.3333V4.66667C0.666687 4.29848 0.965164 4 1.33335 4ZM2.00002 5.33333V10.6667H14V5.33333H2.00002Z" fill="#646A73"/>
<path d="M4.66665 7.02255C4.66665 6.82618 4.50746 6.66699 4.31109 6.66699H3.68887C3.4925 6.66699 3.33331 6.82618 3.33331 7.02255V8.9781C3.33331 9.17447 3.4925 9.33366 3.68887 9.33366H4.31109C4.50746 9.33366 4.66665 9.17447 4.66665 8.9781V7.02255Z" fill="#646A73"/>
</g>
<defs>
<clipPath id="clip0_8096_189573">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 797 B

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.66666 1.77734H13.3333C13.8242 1.77734 14.2222 2.17531 14.2222 2.66623V13.3329C14.2222 13.8238 13.8242 14.2218 13.3333 14.2218H2.66666C2.17574 14.2218 1.77777 13.8238 1.77777 13.3329V2.66623C1.77777 2.17531 2.17574 1.77734 2.66666 1.77734ZM3.1111 3.11068V12.8885H12.8889V3.11068H3.1111ZM10.5524 5.52146C10.6566 5.41732 10.8254 5.41732 10.9296 5.52146L11.4952 6.08715C11.5994 6.19129 11.5994 6.36013 11.4952 6.46427L7.47259 10.4869C7.463 10.4965 7.45285 10.5052 7.44226 10.5131L7.35921 10.5961C7.25571 10.6996 7.08815 10.7003 6.98375 10.5978L4.63634 8.29133C4.53063 8.18747 4.52988 8.01734 4.63467 7.91255L5.20034 7.34688C5.30383 7.24339 5.47139 7.24265 5.57579 7.34523L7.16611 8.90778L10.5524 5.52146Z" fill="#646A73"/>
</svg>

After

Width:  |  Height:  |  Size: 834 B

View File

@ -661,6 +661,11 @@ import wizard_quick_start from '@/assets/svg/wizard_quick_start.svg'
import wordCloudDark from '@/assets/svg/word-cloud-dark.svg'
import wordCloudOrigin from '@/assets/svg/word-cloud-origin.svg'
import wordCloud from '@/assets/svg/word-cloud.svg'
import icon_multi_line_outlined from '@/assets/svg/icon_multi-line_outlined.svg'
import icon_radio_outlined from '@/assets/svg/icon_radio_outlined.svg'
import icon_single_line_outlined from '@/assets/svg/icon_single-line_outlined.svg'
import icon_todo_outlined from '@/assets/svg/icon_todo_outlined.svg'
import icon_file_doc_colorful from '@/assets/svg/icon_file-doc_colorful.svg'
const iconMap = {
'401': _401,
'403': _403,
@ -1062,6 +1067,10 @@ const iconMap = {
'icon_right-association': icon_rightAssociation,
icon_right_outlined: icon_right_outlined,
icon_scroll_filled: icon_scroll_filled,
icon_radio_outlined: icon_radio_outlined,
icon_todo_outlined: icon_todo_outlined,
'icon_single-line_outlined': icon_single_line_outlined,
'icon_multi-line_outlined': icon_multi_line_outlined,
'icon_search-outline_outlined': icon_searchOutline_outlined,
icon_search: icon_search,
'icon_share-label_filled': icon_shareLabel_filled,
@ -1320,7 +1329,8 @@ const iconMap = {
wizard_quick_start: wizard_quick_start,
'word-cloud-dark': wordCloudDark,
'word-cloud-origin': wordCloudOrigin,
'word-cloud': wordCloud
'word-cloud': wordCloud,
'icon_file-doc_colorful': icon_file_doc_colorful
}
const props = defineProps({

View File

@ -1,7 +1,7 @@
import { ref, onBeforeUnmount, onMounted } from 'vue'
import { useCache } from '@/hooks/web/useCache'
type Sidebar = 'DATASET' | 'DASHBOARD' | 'DATASOURCE'
type Sidebar = 'DATASET' | 'DASHBOARD' | 'DATASOURCE' | 'DATA-FILLING'
export const useMoveLine = (type: Sidebar) => {
const { wsCache } = useCache('localStorage')

View File

@ -1,5 +1,15 @@
export default {
common: {
component: {
input: 'Input',
textarea: 'Textarea',
select: 'Select',
radio: 'Radio',
checkbox: 'Checkbox',
date: 'Date Picker',
dateRange: 'Date Range Picker',
add_component_hint: 'Click or drag the component on the left to add a field'
},
inputText: 'Please input',
account: 'Account',
email: 'Email',
@ -250,5 +260,163 @@ export default {
template_manage: {
name_already_exists_type: 'Classification name already exists',
the_same_category: 'The template name already exists under the same category'
},
data_fill: {
data_fill: 'Data Filling',
permission: 'Data Filling Permission',
enable: 'Enable',
enable_hint: 'Cannot disable after enable',
new_folder: 'New Folder',
form_manage: 'Form Manage',
my_job: 'My Job',
form: {
mobile_number_format_is_incorrect: 'Incorrect format of mobile phone number',
email_format_is_incorrect: 'The mailbox format is incorrect',
name: 'Name',
rename: 'Rename',
untitled: 'Untitled',
create_new_form: 'Create New Form',
copy_new_form: 'Copy Form',
edit_form: 'Edit Form',
title: 'Title',
no_form: 'Click to Create New',
form_list_name: 'Form List',
create_form: 'Create Form',
please_select: 'Please Select',
component: 'Component',
component_setting: 'Component Setting',
hint: 'Hint',
option: 'Option',
form_setting: 'Form Setting',
input_limit_50: 'No more than 50 characters',
confirm_delete: 'Confirm delete? (The tables created in database will not be deleted)',
list: 'Form List',
record: 'Fill Record',
task_manage: 'Task Manage',
form_name: 'Form Name',
commit_type: 'Form Commit Type',
commit_type_append: 'Append',
commit_type_update: 'Update',
commit_rule: 'Update Rules',
commit_rule_add: 'Add Update Rule',
commit_rule_settings: 'Update Rule Settings',
commit_rule_set: 'Set',
folder: 'Folder',
datasource: 'Datasource',
table: 'Table',
creator: 'Creator',
createTime: 'Create Time',
operation: 'Operation',
operator: 'Operator',
operate_time: 'Operate Time',
modify: 'Modify',
show: 'Show',
delete: 'Delete',
show_data: 'Show Data',
text: 'Text',
number: 'Number',
tel: 'Tel',
email: 'Email',
duplicate_error: 'Duplicate',
value_not_exists: 'Value Not Exists',
range_separator: 'Range Separator',
start_hint_word: 'Start Hint Word',
end_hint_word: 'End Hint Word',
input_type: 'Input Type',
date_type: 'Date Format',
check: 'Check',
set_required: 'Set Required',
set_unique: 'Set Unique',
set_multiple: 'Set Multiple',
use_datetime: 'Use Datetime',
custom: 'Custom',
use_datasource: 'Bind Datasource',
bind_column: 'Bind Column',
bind_complete: 'Bind',
option_value: 'Options',
add_option: 'Add Option',
form_name_cannot_none: 'Form name cannot be null',
form_update_rule_none: 'Update Rules cannot be null',
form_components_cannot_null: 'Form components cannot be null',
option_list_cannot_empty: 'Option list cannot be empty',
option_list_datasource_cannot_empty: 'Datasource Settings of option list cannot be empty',
component_setting_error: 'Component setting error',
table_name: 'Table',
form_column: 'Form Column',
column_name: 'Table Column',
column_type: 'Table Column Type',
create_index: 'Create Index',
add_index: 'Add Index',
index_name: 'Index Name',
create_index_hint:
'MySQL versions earlier than 8.0 or MariaDB versions earlier than 10.8.0 do not support Descending indexes',
index_column: 'Index Column',
order: 'Sort',
order_asc: 'Asc',
order_desc: 'Desc',
order_none: 'Default Order',
add_column: 'Add Column',
please_insert_start: 'Start Time Column Name',
please_insert_end: 'End Time Column Name',
save_form: 'Save Form',
default: 'default',
default_built_in: 'Built-in Database'
},
database: {
nvarchar: 'Nvarchar',
text: 'Text',
number: 'Number',
decimal: 'Decimal',
datetime: 'Datetime'
},
data: {
confirm_delete: 'Confirm delete?',
add_data: 'Add Data',
download_template: 'Download Template',
insert_data: 'Insert Data',
update_data: 'Update Data',
delete_data: 'Delete Data',
recent_committer: 'Recent Committer',
recent_commit_time: 'Recent Commit Time',
start: 'Start',
end: 'End',
id_is: 'ID [',
data_not_found: '] Not Found'
},
task: {
name: 'Name',
creator: 'Creator',
create_time: 'Create Time',
rate_type: 'Rate Type',
task_status: 'Status',
add_task: 'Add Task',
task_name: 'Task Name',
task_remain_time: 'Remaining Validity',
task_sender: 'Task Sender',
start_filling: 'Start Filling',
task_distribute_time: 'Distribution Time',
task_expiration_time: 'Expiration Time',
task_finished_time: 'Finished Time',
task_end_time: 'End Time',
edit_data: 'Edit Data',
show_data: 'Show Data',
confirm_enable: 'Confirm enable task?',
confirm_disable: 'Confirm disable task?',
edit_task: 'Edit Task',
create_task: 'Create Task',
edit: 'Edit',
stop: 'Stop',
start: 'Start',
delete: 'Delete',
no_time_limit: 'No Time Limit',
todo: 'Todo',
finished: 'Committed',
expired: 'Expired',
task_finish_in: 'Task Finished in ',
task_finish_in_suffix: '',
open_sub_task: 'Open Sub Tasks'
},
on_the_left: 'Please select a form on the left',
search_by_commit_name: 'Search by operator name'
}
}

View File

@ -1,5 +1,15 @@
export default {
common: {
component: {
input: '單行輸入',
textarea: '多行輸入',
select: '下拉框',
radio: '單選',
checkbox: '多選框',
date: '日期',
dateRange: '時間范圍',
add_component_hint: '點擊或拖拽左側組件添加字段'
},
inputText: '请输入',
add: '添加',
account: '账号',
@ -152,5 +162,162 @@ export default {
template_manage: {
name_already_exists_type: '分类名称已存在',
the_same_category: '同一分类下该模板名称已存在'
},
data_fill: {
data_fill: '數據填報',
permission: '填報權限',
enable: '開啟',
enable_hint: '數據填報開啟后可將表單數據存放至數據源中一旦開啟后后期不允許關閉',
new_folder: '新建文件夾',
form_manage: '表單管理',
my_job: '我的填報',
form: {
mobile_number_format_is_incorrect: '手機號碼格式不正確',
email_format_is_incorrect: '郵箱格式不正確',
name: '名稱',
rename: '重命名',
untitled: '未命名表單',
create_new_form: '新建表單',
copy_new_form: '復制表單',
edit_form: '編輯表單',
title: '標題',
no_form: '暫無表單點擊',
form_list_name: '填報表單',
create_form: '新建表單',
please_select: '請選擇',
component: '組件',
component_setting: '組件設置',
hint: '提示詞',
input_limit_50: '不超過50個字符',
option: '選項',
form_setting: '表單設置',
confirm_delete: '確認刪除(不會刪除已創建的數據庫表)',
list: '表單數據',
record: '提交記錄',
task_manage: '任務管理',
form_name: '表單名稱',
commit_type: '表單提交方式',
commit_type_append: '數據追加',
commit_type_update: '數據更新',
commit_rule: '更新條件',
commit_rule_add: '添加更新規則',
commit_rule_settings: '更新規則設置',
commit_rule_set: '已設置',
folder: '所屬文件夾',
datasource: '數據源',
table: '數據庫表',
creator: '創建人',
createTime: '創建時間',
operation: '操作',
operator: '操作人',
operate_time: '操作時間',
modify: '修改',
show: '查看',
delete: '刪除',
show_data: '查看數據',
text: '普通文本',
number: '數字',
tel: '手機號',
email: '郵箱',
duplicate_error: '重復',
value_not_exists: '值不存在',
range_separator: '分割字符',
start_hint_word: '開始提示詞',
end_hint_word: '結束提示詞',
input_type: '格式類型',
date_type: '展示粒度',
check: '校驗',
set_required: '設置為必填項',
set_unique: '不允許重復值',
set_multiple: '允許多選',
use_datetime: '使用日期時間',
custom: '自定義',
use_datasource: '綁定數據源',
bind_column: '綁定字段',
bind_complete: '已綁定',
option_value: '選項值',
add_option: '添加選項值',
form_name_cannot_none: '表單名稱不能為空',
form_update_rule_none: '請配置更新規則',
form_components_cannot_null: '請添加表單組件',
option_list_cannot_empty: '選項值不能為空',
option_list_datasource_cannot_empty: '選項值綁定數據源配置不能為空',
component_setting_error: '組件設置錯誤',
table_name: '數據庫表名',
form_column: '表單字段',
column_name: '數據庫表字段名稱',
column_type: '數據庫字段類型',
create_index: '創建索引',
add_index: '新增索引',
index_name: '索引名稱',
create_index_hint: 'MySQL 8.0 MariaDB 10.8.0 以下版本不支持索引降序排序',
index_column: '索引字段',
order: '排序',
order_asc: '升序',
order_desc: '降序',
order_none: '默認排序',
add_column: '新增字段',
please_insert_start: '請輸入開始時間',
please_insert_end: '請輸入結束時間',
save_form: '保存表單',
default: '默認',
default_built_in: '內建數據庫'
},
database: {
nvarchar: '字符串',
text: '長文本',
number: '整型數字',
decimal: '小數數字',
datetime: '日期'
},
data: {
confirm_delete: '確認刪除?',
add_data: '添加數據',
download_template: '下載模板',
insert_data: '插入數據',
update_data: '更新數據',
delete_data: '刪除數據',
recent_committer: '最近提交人',
recent_commit_time: '最近提交時間',
start: '開始',
end: '結束',
id_is: 'ID為[',
data_not_found: ']的數據不存在'
},
task: {
name: '名稱',
creator: '創建人',
create_time: '創建時間',
rate_type: '任務下發模式',
task_status: '任務狀態',
add_task: '添加任務',
task_name: '任務名稱',
task_remain_time: '任務有效期',
task_sender: '任務下發人',
start_filling: '立即填報',
task_distribute_time: '任務下發時間',
task_expiration_time: '任務過期時間',
task_finished_time: '任務完成時間',
task_end_time: '任務截止時間',
edit_data: '編輯數據',
show_data: '查看數據',
confirm_enable: '確認啟動任務單次任務會新建下發任務',
confirm_disable: '確認停止任務',
edit_task: '編輯任務',
create_task: '新建任務',
edit: '編輯',
stop: '停止',
start: '啟動',
delete: '刪除',
no_time_limit: '不限時',
todo: '待辦項',
finished: '已提交',
expired: '已過期',
task_finish_in: '在任務下發',
task_finish_in_suffix: '內完成填報',
open_sub_task: '查看子任務'
},
on_the_left: '請在左側選擇表單',
search_by_commit_name: '根據操作人名稱搜索'
}
}

View File

@ -1,5 +1,15 @@
export default {
common: {
component: {
input: '单行输入',
textarea: '多行输入',
select: '下拉框',
radio: '单选',
checkbox: '多选框',
date: '日期',
dateRange: '时间范围',
add_component_hint: '点击或拖拽左侧组件添加字段'
},
inputText: '请输入',
add: '添加',
account: '账号',
@ -2562,6 +2572,10 @@ export default {
once_a_day: '每天',
once_a_week: '每周',
once_a_month: '每月',
hour: '小时',
day: '天',
week: '周',
month: '月',
week_mon: '一',
week_tue: '二',
week_wed: '三',
@ -2578,5 +2592,162 @@ export default {
variable: {
give_up: 's',
save_apply: '保存并应用'
},
data_fill: {
data_fill: '数据填报',
permission: '填报权限',
enable: '开启',
enable_hint: '数据填报开启后可将表单数据存放至数据源中一旦开启后后期不允许关闭',
new_folder: '新建文件夹',
form_manage: '表单管理',
my_job: '我的填报',
form: {
special_characters_are_not_supported: '不支持特殊字符',
mobile_number_format_is_incorrect: '手机号码格式不正确',
name: '名称',
rename: '重命名',
untitled: '未命名表单',
create_new_form: '新建表单',
copy_new_form: '复制表单',
edit_form: '编辑表单',
title: '标题',
no_form: '暂无表单点击',
form_list_name: '填报表单',
create_form: '新建表单',
please_select: '请选择',
component: '组件',
component_setting: '组件设置',
hint: '提示词',
input_limit_50: '不超过50个字符',
option: '选项',
form_setting: '表单设置',
confirm_delete: '确认删除(不会删除已创建的数据库表)',
list: '表单数据',
record: '提交记录',
task_manage: '任务管理',
form_name: '表单名称',
commit_type: '表单提交方式',
commit_type_append: '数据追加',
commit_type_update: '数据更新',
commit_rule: '更新条件',
commit_rule_add: '添加更新规则',
commit_rule_settings: '更新规则设置',
commit_rule_set: '已设置',
folder: '所属文件夹',
datasource: '数据源',
table: '数据库表',
creator: '创建人',
createTime: '创建时间',
operation: '操作',
operator: '操作人',
operate_time: '操作时间',
modify: '修改',
show: '查看',
delete: '删除',
show_data: '查看数据',
text: '普通文本',
number: '数字',
tel: '手机号',
email: '邮箱',
duplicate_error: '重复',
value_not_exists: '值不存在',
range_separator: '分割字符',
start_hint_word: '开始提示词',
end_hint_word: '结束提示词',
input_type: '格式类型',
date_type: '展示粒度',
check: '校验',
set_required: '设置为必填项',
set_unique: '不允许重复值',
set_multiple: '允许多选',
use_datetime: '使用日期时间',
custom: '自定义',
use_datasource: '绑定数据源',
bind_column: '绑定字段',
bind_complete: '已绑定',
option_value: '选项值',
add_option: '添加选项值',
form_name_cannot_none: '表单名称不能为空',
form_update_rule_none: '请配置更新规则',
form_components_cannot_null: '请添加表单组件',
option_list_cannot_empty: '选项值不能为空',
option_list_datasource_cannot_empty: '选项值绑定数据源配置不能为空',
component_setting_error: '组件设置错误',
table_name: '数据库表名',
form_column: '表单字段',
column_name: '数据库表字段名称',
column_type: '数据库字段类型',
create_index: '创建索引',
add_index: '新增索引',
index_name: '索引名称',
create_index_hint: 'MySQL 8.0 MariaDB 10.8.0 以下版本不支持索引降序排序',
index_column: '索引字段',
order: '排序',
order_asc: '升序',
order_desc: '降序',
order_none: '默认排序',
add_column: '新增字段',
please_insert_start: '请输入开始时间',
please_insert_end: '请输入结束时间',
save_form: '保存表单',
default: '默认',
default_built_in: '内建数据库'
},
database: {
nvarchar: '字符串',
text: '长文本',
number: '整型数字',
decimal: '小数数字',
datetime: '日期'
},
data: {
confirm_delete: '确认删除?',
add_data: '添加数据',
download_template: '下载模板',
insert_data: '插入数据',
update_data: '更新数据',
delete_data: '删除数据',
recent_committer: '最近提交人',
recent_commit_time: '最近提交时间',
start: '开始',
end: '结束',
id_is: 'ID为[',
data_not_found: ']的数据不存在'
},
task: {
name: '名称',
creator: '创建人',
create_time: '创建时间',
rate_type: '任务下发模式',
task_status: '任务状态',
task_name: '任务名称',
add_task: '添加任务',
task_remain_time: '任务有效期',
task_sender: '任务下发人',
start_filling: '立即填报',
task_distribute_time: '任务下发时间',
task_expiration_time: '任务过期时间',
task_finished_time: '任务完成时间',
task_end_time: '任务截止时间',
edit_data: '编辑数据',
show_data: '查看数据',
confirm_enable: '确认启动任务单次任务会新建下发任务',
confirm_disable: '确认停止任务',
edit_task: '编辑任务',
create_task: '新建任务',
edit: '编辑',
stop: '停止',
start: '启动',
delete: '删除',
no_time_limit: '不限时',
todo: '待办项',
finished: '已提交',
expired: '已过期',
task_finish_in: '在任务下发',
task_finish_in_suffix: '内完成填报',
open_sub_task: '查看子任务'
},
on_the_left: '请在左侧选择表单',
search_by_commit_name: '根据操作人名称搜索'
}
}

View File

@ -1,5 +1,5 @@
import { defineStore } from 'pinia'
import { store } from '../index'
import { store } from '@/store'
import { queryTreeApi } from '@/api/visualization/dataVisualization'
import { getDatasetTree } from '@/api/dataset'
import { listDatasources } from '@/api/datasource'
@ -7,6 +7,7 @@ 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 {
@ -21,9 +22,9 @@ interface InteractiveState {
data: Record<number, InnerInteractive>
}
const apiMap = [queryTreeApi, queryTreeApi, getDatasetTree, listDatasources]
const apiMap = [queryTreeApi, queryTreeApi, getDatasetTree, listDatasources, listDataFillingForms]
const busiFlagMap = ['dashboard', 'dataV', 'dataset', 'datasource']
const busiFlagMap = ['dashboard', 'dataV', 'dataset', 'datasource', 'data-filling']
export const interactiveStore = defineStore('interactive', {
state: (): InteractiveState => ({

View File

@ -12,3 +12,5 @@ export function validUsername(str) {
}
export const PHONE_REGEX = '^1[3|4|5|7|8][0-9]{9}$'
export const EMAIL_REGEX = '^[a-zA-Z0-9_._-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$'

View File

@ -14,6 +14,7 @@ import { CustomPassword } from '@/components/custom-password'
import { ElForm, ElMessage, ElMessageBox } from 'element-plus-secondary'
import Cron from '@/components/cron/src/Cron.vue'
import { ComponentPublicInstance } from 'vue'
import { XpackComponent } from '@/components/plugin'
const { t } = useI18n()
const prop = defineProps({
form: {
@ -28,6 +29,7 @@ const prop = defineProps({
configuration?: Configuration
apiConfiguration?: ApiConfiguration[]
paramsConfiguration?: ApiConfiguration[]
enableDataFill?: boolean
}>({
id: 0,
name: '',
@ -340,16 +342,16 @@ const setItemRef = (ele: ComponentPublicInstance | null | Element) => {
}
const copyItem = (item?: ApiConfiguration) => {
var newItem = JSON.parse(JSON.stringify(item))
const newItem = JSON.parse(JSON.stringify(item))
newItem.deTableName = ''
newItem.serialNumber =
form.value.apiConfiguration[form.value.apiConfiguration.length - 1].serialNumber + 1
var reg = new RegExp(item.name + '_copy_' + '([0-9]*)', 'gim')
var number = 0
for (var i = 1; i < form.value.apiConfiguration.length; i++) {
var match = form.value.apiConfiguration[i].name.match(reg)
const reg = new RegExp(item.name + '_copy_' + '([0-9]*)', 'gim')
let number = 0
for (let i = 1; i < form.value.apiConfiguration.length; i++) {
const match = form.value.apiConfiguration[i].name.match(reg)
if (match !== null) {
var num = match[0].substring(
const num = match[0].substring(
form.value.apiConfiguration[i].name.length + 5,
match[0].length - 1
)
@ -413,7 +415,7 @@ const resetForm = () => {
}
const returnItem = apiItem => {
var find = false
let find = false
if (apiItem.type !== 'params') {
apiItem.status = 'Success'
for (let i = 0; i < form.value.apiConfiguration.length; i++) {
@ -1227,6 +1229,12 @@ defineExpose({
</el-col>
</el-row>
</template>
<!-- 数据填报 -->
<XpackComponent
:form="form"
jsname="L2NvbXBvbmVudC9kYXRhLWZpbGxpbmcvRGF0YXNvdXJjZUVuYWJsZURhdGFGaWxsaW5n"
/>
</template>
</el-form>
<el-form

View File

@ -432,7 +432,7 @@ const saveDS = () => {
return
} else if (currentDsType.value === 'API') {
for (var i = 0; i < request.apiConfiguration.length; i++) {
for (let i = 0; i < request.apiConfiguration.length; i++) {
if (
request.apiConfiguration[i].deTableName === '' ||
request.apiConfiguration[i].deTableName === undefined ||
@ -445,7 +445,7 @@ const saveDS = () => {
uuid.v1().replaceAll('-', '').substring(0, 10)
}
request.apiConfiguration[i].jsonFields = []
for (var j = 0; j < request.apiConfiguration[i].fields.length; j++) {
for (let j = 0; j < request.apiConfiguration[i].fields.length; j++) {
request.apiConfiguration[i].fields[j].value = []
}
}

View File

@ -366,7 +366,8 @@ const defaultInfo = {
configuration: null,
syncSetting: null,
apiConfiguration: [],
weight: 0
weight: 0,
enableDataFill: false
}
const nodeInfo = reactive<Node>(cloneDeep(defaultInfo))
const infoList = computed(() => {
@ -504,7 +505,8 @@ const handleNodeClick = data => {
fileName,
size,
description,
lastSyncTime
lastSyncTime,
enableDataFill
} = res.data
if (configuration) {
configuration = JSON.parse(Base64.decode(configuration))
@ -531,7 +533,8 @@ const handleNodeClick = data => {
apiConfiguration: apiConfigurationStr,
paramsConfiguration: paramsStr,
weight: data.weight,
lastSyncTime
lastSyncTime,
enableDataFill
})
activeTab.value = ''
activeName.value = 'config'
@ -628,7 +631,8 @@ const editDatasource = (editType?: number) => {
fileName,
size,
description,
lastSyncTime
lastSyncTime,
enableDataFill
} = res.data
if (configuration) {
configuration = JSON.parse(Base64.decode(configuration))
@ -656,6 +660,7 @@ const editDatasource = (editType?: number) => {
apiConfiguration: apiConfigurationStr,
paramsConfiguration: paramsStr,
lastSyncTime,
enableDataFill,
isPlugin: arr && arr.length > 0,
staticMap: arr[0]?.staticMap
})

View File

@ -15,6 +15,7 @@ import ShareGrid from '@/views/share/share/ShareGrid.vue'
import ShareHandler from '@/views/share/share/ShareHandler.vue'
import { useAppStoreWithOut } from '@/store/modules/app'
import { useEmbedded } from '@/store/modules/embedded'
import { XpackComponent } from '@/components/plugin'
const userStore = useUserStoreWithOut()
const { resolve } = useRouter()
const { t } = useI18n()
@ -263,6 +264,8 @@ const getEmptyDesc = (): string => {
</span>
</template>
</el-tab-pane>
<XpackComponent jsname="L21lbnUvZGF0YS9kYXRhLWZpbGxpbmcvZmlsbC9UYWJQYW5l" />
</el-tabs>
<!-- <XpackComponent jsname="c2hhcmUtcGFuZWw=" @loaded="panelLoad" /> -->
<!-- <XpackComponent :active-name="activeName" jsname="c2hhcmU=" @set-loading="setLoading" /> -->
@ -419,6 +422,10 @@ const getEmptyDesc = (): string => {
</el-table-column>
</GridTable>
</div>
<XpackComponent
jsname="L21lbnUvZGF0YS9kYXRhLWZpbGxpbmcvZmlsbC9UYWJQYW5lVGFibGU="
v-if="activeName === 'data-filling'"
/>
</div>
<el-empty
class="dashboard-type"

@ -1 +1 @@
Subproject commit a3398f5493e2ac0fcc5df37345c10afe419853bc
Subproject commit c1ebcdfa542695abd58790d921c23ed4afaaf65d

View File

@ -74,6 +74,9 @@ public interface DatasourceApi {
@GetMapping("/get/{datasourceId}")
DatasourceDTO get(@PathVariable("datasourceId") Long datasourceId) throws DEException;
DatasourceDTO innerGet(Long datasourceId) throws DEException;
List<DatasourceDTO> innerList(List<Long> ids) throws DEException;
@DePermit({"#p0+':read'"})
@GetMapping("/hidePw/{datasourceId}")
DatasourceDTO hidePw(@PathVariable("datasourceId") Long datasourceId) throws DEException;

View File

@ -27,5 +27,7 @@ public class ReportGridVO implements Serializable {
private String creator;
private String updater;
private Long createTime;
}

View File

@ -0,0 +1,111 @@
package io.dataease.api.xpack.dataFilling;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.api.report.dto.ReportInstanceMsgRequest;
import io.dataease.api.report.vo.ReportGridVO;
import io.dataease.api.xpack.dataFilling.dto.*;
import io.dataease.auth.DeApiPath;
import io.dataease.exception.DEException;
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 java.util.List;
import java.util.Map;
import static io.dataease.constant.AuthResourceEnum.DATA_FILLING;
@Tag(name = "数据填报")
@ApiSupport(order = 1000, author = "fit2cloud-someone")
@DeApiPath(value = "/data-filling", rt = DATA_FILLING)
public interface DataFillingApi {
@PostMapping("tree")
List<BusiNodeVO> tree(@RequestBody BusiNodeRequest request) throws DEException;
@GetMapping("/get/{id}")
DataFillingDTO get(@PathVariable("id") Long id);
@PostMapping("/move")
DataFillingDTO move(@RequestBody DataFillingDTO dataFillingDTO);
@PostMapping("/save")
DataFillingDTO save(@RequestBody DataFillingDTO dataFillingDTO) throws Exception;
@PostMapping("/rename")
DataFillingDTO rename(@RequestBody DataFillingDTO dataFillingDTO);
@GetMapping("delete/{id}")
void delete(@PathVariable("id") Long id);
@GetMapping("/datasource/list")
List<SimpleDatasourceDTO> listDatasourceList();
@PostMapping("/form/{optionDatasource}/options")
List<ColumnOption> listColumnData(@PathVariable("optionDatasource") Long optionDatasource, @RequestBody DatasourceOptionsRequest request) throws Exception;
@PostMapping("/form/{id}/tableData")
DataFillFormTableDataResponse tableData(@PathVariable Long id, @RequestBody DataFillFormTableDataRequest request) throws Exception;
@GetMapping("/form/{formId}/delete/{id}")
void deleteRowData(@PathVariable Long formId, @PathVariable Long id) throws Exception;
@PostMapping("/form/{formId}/batch-delete")
void batchDeleteRowData(@PathVariable Long formId, @RequestBody List<Long> ids) throws Exception;
@PostMapping("/form/{formId}/rowData/save")
DataFillFormTableDataResponse saveRowData(@PathVariable Long formId, @RequestBody Map<String, Object> data) throws Exception;
@GetMapping("/task/info/{taskId}")
TaskInfoVO info(@PathVariable("taskId") Long taskId);
@PostMapping("/task/save")
Long save(@RequestBody TaskInfoVO task);
@PostMapping("/task/logMsg")
String logMsg(@RequestBody ReportInstanceMsgRequest request);
@PostMapping("/task/page/{goPage}/{pageSize}")
IPage<ReportGridVO> taskPager(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody DfTaskInfoRequest request);
@PostMapping("/sub-task/page/{goPage}/{pageSize}")
IPage<DfSubTaskVo> subTaskPager(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody DfSubTaskInfoRequest request);
@PostMapping("/task/delete")
void batchDeleteTask(@RequestBody List<Long> ids) throws Exception;
@GetMapping("/task/{id}/stop")
void stopTask(@PathVariable Long id) throws Exception;
@GetMapping("/task/{id}/start")
void startTask(@PathVariable Long id) throws Exception;
@PostMapping("/sub-task/delete")
void batchDeleteSubTask(@RequestBody List<Long> ids) throws Exception;
@GetMapping("/sub-task/{id}/users/list/{type}")
List<Map<String, Object>> listSubTaskUser(@PathVariable Long id, @PathVariable String type) throws Exception;
@PostMapping("/user-task")
List<DfUserTaskVo> listUserTask(@RequestBody DfUserTaskRequest request) throws Exception;
@GetMapping("/user-task/list/{id}")
DfUserTaskData listUserTaskData(@PathVariable Long id) throws Exception;
@PostMapping("/user-task/saveData/{id}")
DataFillFormTableDataResponse saveFormRowData(@PathVariable Long id, @RequestBody Map<String, Object> data) throws Exception;
@PostMapping("/log/page/{goPage}/{pageSize}")
IPage<DfCommitLog> taskPager(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody DfCommitLogRequest request);
}

View File

@ -0,0 +1,23 @@
package io.dataease.api.xpack.dataFilling.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ColumnOption implements Serializable {
@Serial
private static final long serialVersionUID = -422787778573500470L;
private String name;
private Object value;
}

View File

@ -0,0 +1,31 @@
package io.dataease.api.xpack.dataFilling.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
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 DataFillFormTableDataRequest implements Serializable {
@Serial
private static final long serialVersionUID = -314618516232771747L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private long currentPage;
private long pageSize;
private boolean withoutLogs = false;
private List<String> primaryKeyValueList;
}

View File

@ -0,0 +1,28 @@
package io.dataease.api.xpack.dataFilling.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
@Data
@Accessors(chain = true)
public class DataFillFormTableDataResponse implements Serializable {
@Serial
private static final long serialVersionUID = -6463885075511811532L;
private Object data;
private String fields;
private long total;
private long currentPage;
private long pageSize;
private String key;
}

View File

@ -0,0 +1,91 @@
package io.dataease.api.xpack.dataFilling.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class DataFillingDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 名称
*/
private String name;
/**
* 父级ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long pid;
/**
* folder/form 目录或文件夹
*/
private String nodeType;
/**
* 表名
*/
private String tableName;
/**
* 数据源
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long datasource;
/**
* 表单内容
*/
private String forms;
/**
* 是否创建索引
*/
private Boolean createIndex;
/**
* 索引
*/
private String tableIndexes;
/**
* 创建人
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long createBy;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新人
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long updateBy;
/**
* 更新时间
*/
private Long updateTime;
private String creator;
private String updater;
}

View File

@ -0,0 +1,11 @@
package io.dataease.api.xpack.dataFilling.dto;
import lombok.Getter;
@Getter
public class DatasourceOptionsRequest {
private String optionTable;
private String optionColumn;
private String optionOrder;
}

View File

@ -0,0 +1,37 @@
package io.dataease.api.xpack.dataFilling.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
@Data
@Accessors(chain = true)
public class DfCommitLog implements Serializable {
@Serial
private static final long serialVersionUID = 3175509273615697110L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@JsonSerialize(using = ToStringSerializer.class)
private Long formId;
@JsonSerialize(using = ToStringSerializer.class)
private Long dataId;
/**
* 操作 0删除 1插入 2更新
*/
private Integer operate;
private Long commitBy;
private String committer;
private Long commitTime;
}

View File

@ -0,0 +1,17 @@
package io.dataease.api.xpack.dataFilling.dto;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class DfCommitLogRequest implements Serializable {
@Serial
private static final long serialVersionUID = 8186544152722934919L;
private Long formId;
private Integer operate;
}

View File

@ -0,0 +1,18 @@
package io.dataease.api.xpack.dataFilling.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class DfSubTaskInfoRequest implements Serializable {
@Serial
private static final long serialVersionUID = 3478936079850972546L;
@JsonSerialize(using = ToStringSerializer.class)
private Long taskId;
}

View File

@ -0,0 +1,56 @@
package io.dataease.api.xpack.dataFilling.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
@Accessors(chain = true)
public class DfSubTaskVo implements Serializable {
@Serial
private static final long serialVersionUID = 7440756474905083085L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@JsonSerialize(using = ToStringSerializer.class)
private Long taskId;
private Long startTime;
private Long endTime;
/**
* 任务下发状态
*/
private Integer execStatus;
/**
* 任务状态
* 1进行中/ 0已过期 根据endTime判断
*/
private Integer status;
/**
* 所有任务项 subInstance 个数
*/
private int totalCount;
private int unfinishedCount;
/**
* 完成率
* (totalCount - unfinishedCount) / totalCount
*/
private BigDecimal finishedRate;
private int totalUserCount;
private int unfinishedUserCount;
}

View File

@ -0,0 +1,25 @@
package io.dataease.api.xpack.dataFilling.dto;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
@Data
public class DfTaskInfoRequest implements Serializable {
@Serial
private static final long serialVersionUID = 3478936079850972546L;
private List<Long> uidList;
private List<Integer> lastStatusList;
private List<Integer> statusList;
private List<Long> timeList;
private String keyword;
private Boolean timeDesc;
}

View File

@ -0,0 +1,56 @@
package io.dataease.api.xpack.dataFilling.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.dataease.utils.LongArray2StringSerialize;
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 DfUserTaskData implements Serializable {
@Serial
private static final long serialVersionUID = -3635512734559897349L;
@Data
@Accessors(chain = true)
public static class DfSubInstance implements Serializable {
@Serial
private static final long serialVersionUID = 4847820854888692033L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@JsonSerialize(using = ToStringSerializer.class)
private Long taskId;
@JsonSerialize(using = ToStringSerializer.class)
private Long pid;
@JsonSerialize(using = ToStringSerializer.class)
private Long uid;
@JsonSerialize(using = ToStringSerializer.class)
private Long formId;
@JsonSerialize(using = ToStringSerializer.class)
private Long dataId;
private Long finishTime;
private Integer status;
}
@JsonSerialize(using = ToStringSerializer.class)
private Long formId;
private String formTitle;
@JsonSerialize(using = LongArray2StringSerialize.class)
private List<Long> dataIds;
private List<DfSubInstance> subInstances;
private String form;
private String formExtSetting;
}

View File

@ -0,0 +1,19 @@
package io.dataease.api.xpack.dataFilling.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
@Data
@Accessors(chain = true)
public class DfUserTaskRequest implements Serializable {
@Serial
private static final long serialVersionUID = 3930338226463461223L;
private String type;
private String taskName;
}

View File

@ -0,0 +1,42 @@
package io.dataease.api.xpack.dataFilling.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.dataease.utils.LongArray2StringSerialize;
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 DfUserTaskVo implements Serializable {
@Serial
private static final long serialVersionUID = 2573431692696582629L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@JsonSerialize(using = ToStringSerializer.class)
private Long taskId;
@JsonSerialize(using = ToStringSerializer.class)
private Long formId;
private String taskName;
private Long startTime;
private Long endTime;
private Long finishTime;
@JsonSerialize(using = ToStringSerializer.class)
private Long assignBy;
private String assigner;
}

View File

@ -0,0 +1,38 @@
package io.dataease.api.xpack.dataFilling.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.dataease.utils.LongArray2StringSerialize;
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 TaskInfoGridVO implements Serializable {
@Serial
private static final long serialVersionUID = -5178055146669970633L;
@JsonSerialize(using= ToStringSerializer.class)
private Long id;
private String name;
private Long lastExecTime;
private Integer lastExecStatus;
private Integer status;
private Long nextExecTime;
private String creatBy;
private String creator;
private Long createTime;
}

View File

@ -0,0 +1,73 @@
package io.dataease.api.xpack.dataFilling.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.dataease.utils.LongArray2StringSerialize;
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 TaskInfoVO implements Serializable {
@Serial
private static final long serialVersionUID = 7074759598819246816L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@JsonSerialize(using = ToStringSerializer.class)
private Long formId;
private String name;
private List<Integer> reciFlagList;
@JsonSerialize(using = LongArray2StringSerialize.class)
private List<Long> uidList;
@JsonSerialize(using = LongArray2StringSerialize.class)
private List<Long> ridList;
private Integer fillType;
private Integer fitType;
private String fitColumn;
private Integer rateType;
private String rateVal;
private Long startTime;
private Long endTime;
@JsonSerialize(using = ToStringSerializer.class)
private Long createBy;
private String creator;
private Long createTime;
@JsonSerialize(using = ToStringSerializer.class)
private Long updateBy;
private String updater;
private Long updateTime;
private Integer publishRangeTime;
private Integer publishRangeTimeType;
private Integer status;
private Integer lastExecStatus;
private Long lastExecTime;
private Long nextExecTime;
private String formExtSetting;
}

View File

@ -194,4 +194,12 @@ public interface UserApi {
@PostMapping("/subOrgUser")
List<UserItem> subOrgUser(@RequestBody List<Long> oidList);
List<Long> getRecipientUserIds(UserReciRequest request);
List<Long> getUserIdByAccount(String account);
List<Long> getUserIdByName(String name);
List<Map<String, Object>> listUserInfosByIds(List<Long> ids);
}

View File

@ -2,7 +2,7 @@ package io.dataease.constant;
public enum AuthResourceEnum {
PANEL(2, 1), SCREEN(3, 2), DATASET(5, 3), DATASOURCE(6, 4), SYSTEM(7, 0), USER(8, 5), ROLE(8, 6), ORG(9, 7), SYNC_DATASOURCE(23, 8), TASK(24, 9), SUMMARY(22, 10);
PANEL(2, 1), SCREEN(3, 2), DATASET(5, 3), DATASOURCE(6, 4), SYSTEM(7, 0), USER(8, 5), ROLE(8, 6), ORG(9, 7), SYNC_DATASOURCE(23, 8), TASK(24, 9), SUMMARY(22, 10), DATA_FILLING(60, 11);
private long menuId;

View File

@ -2,7 +2,7 @@ package io.dataease.constant;
public enum BusiResourceEnum {
PANEL(1), SCREEN(2), DATASET(3), DATASOURCE(4);
PANEL(1), SCREEN(2), DATASET(3), DATASOURCE(4), DATA_FILLING(8);
private int flag;

View File

@ -0,0 +1,29 @@
package io.dataease.constant;
import java.util.Arrays;
public enum DadaFillingFinishTaskEnum {
OPEN(0), FINISHED(1);
private Integer flag;
public Integer getFlag() {
return flag;
}
public void setFlag(Integer flag) {
this.flag = flag;
}
DadaFillingFinishTaskEnum(Integer flag) {
this.flag = flag;
}
DadaFillingFinishTaskEnum() {
}
public static DadaFillingFinishTaskEnum fromValue(Integer flag) {
return Arrays.stream(values()).filter(v -> v.flag.equals(flag)).findFirst().get();
}
}

View File

@ -0,0 +1,23 @@
package io.dataease.utils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class LongArray2StringSerialize extends JsonSerializer<List<Long>> {
@Override
public void serialize(List<Long> longs, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
List<String> list = new ArrayList<>();
for (Long str : longs) {
if (str != null) {
list.add(str.toString());
}
}
jsonGenerator.writeObject(list);
}
}

View File

@ -89,4 +89,6 @@ public class DatasourceDTO implements Serializable {
* 任务状态
*/
private String taskStatus;
private Boolean enableDataFill;
}

View File

@ -4,6 +4,7 @@ import lombok.Data;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -24,6 +25,7 @@ public class DatasourceRequest implements Serializable {
private boolean previewData = false;
private boolean totalPageFlag;
private Map<Long, DatasourceSchemaDTO> dsList;
private List<TableFieldWithValue> tableFieldWithValues;
public DatasourceRequest() {
}

View File

@ -0,0 +1,24 @@
package io.dataease.extensions.datasource.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class SimpleDatasourceDTO implements Serializable {
@Serial
private static final long serialVersionUID = 2255370172449547802L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@JsonSerialize(using = ToStringSerializer.class)
private Long pid;
private String name;
private String type;
private String typeAlias;
private String status;
private Boolean enableDataFill;
}

View File

@ -19,7 +19,9 @@ public class TableField {
private Integer deExtractType;
private int extField;
private String jsonPath;
private boolean primary;
List<Object> value;
private int inCount;
}

View File

@ -0,0 +1,29 @@
package io.dataease.extensions.datasource.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
@Getter
@Setter
@Accessors(chain = true)
public class TableFieldWithValue implements Serializable {
@Serial
private static final long serialVersionUID = -8852504196142402103L;
private Object value;
private String filedName;
private String typeName;
private Integer type;
public static TableFieldWithValue copy(TableFieldWithValue tableFieldWithValue) {
return new TableFieldWithValue()
.setValue(tableFieldWithValue.getValue())
.setFiledName(tableFieldWithValue.getFiledName())
.setTypeName(tableFieldWithValue.getTypeName())
.setType(tableFieldWithValue.getType());
}
}

View File

@ -92,6 +92,11 @@ public abstract class Provider {
*/
public abstract void hidePW(DatasourceDTO datasourceDTO);
public abstract void exec(DatasourceRequest datasourceRequest) throws DEException;
public abstract int executeUpdate(DatasourceRequest datasourceRequest) throws DEException;
@Getter
private static final Map<Long, Integer> lPorts = new HashMap<>();
@Getter