diff --git a/core/core-backend/src/main/java/io/dataease/datasource/dao/auto/entity/CoreDatasource.java b/core/core-backend/src/main/java/io/dataease/datasource/dao/auto/entity/CoreDatasource.java index a141d413bf..ddf6d34292 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/dao/auto/entity/CoreDatasource.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/dao/auto/entity/CoreDatasource.java @@ -7,11 +7,11 @@ import java.io.Serializable; /** *

- * + * 数据源表 *

* * @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 + "}"; } } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/dao/auto/mapper/CoreDatasourceMapper.java b/core/core-backend/src/main/java/io/dataease/datasource/dao/auto/mapper/CoreDatasourceMapper.java index d6e7170bd1..a27bc9ad36 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/dao/auto/mapper/CoreDatasourceMapper.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/dao/auto/mapper/CoreDatasourceMapper.java @@ -6,11 +6,11 @@ import org.apache.ibatis.annotations.Mapper; /** *

- * Mapper 接口 + * 数据源表 Mapper 接口 *

* * @author fit2cloud - * @since 2023-09-26 + * @since 2024-07-09 */ @Mapper public interface CoreDatasourceMapper extends BaseMapper { diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java index a6ff053f04..b5acae0241 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java @@ -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 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 getField(ResultSet rs, DatasourceRequest datasourceRequest) throws Exception { List 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"); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java b/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java index 8db4b316a6..e57cc64e7c 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java @@ -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 toCreateTables = new ArrayList<>(); List toDeleteTables = new ArrayList<>(); if (dataSourceDTO.getType().equals(DatasourceConfiguration.DatasourceType.API.name())) { - List sourceTables = ApiUtils.getTables(sourceTableRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList()); + requestDatasource.setEnableDataFill(null); + List sourceTables = ApiUtils.getTables(sourceTableRequest).stream().map(DatasetTableDTO::getTableName).toList(); List datasetTableDTOS = ApiUtils.getTables(datasourceRequest); List 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 sourceTables = ExcelUtils.getTables(sourceTableRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList()); List 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 innerList(List ids) throws DEException { + List list = new ArrayList<>(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ids != null) { + if (ids.isEmpty()) { + return list; + } else { + queryWrapper.in(CoreDatasource::getId, ids); + } + } + List 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())) { diff --git a/core/core-backend/src/main/java/io/dataease/listener/XpackTaskStarter.java b/core/core-backend/src/main/java/io/dataease/listener/XpackTaskStarter.java index 0154a29f6f..eb83895a7c 100644 --- a/core/core-backend/src/main/java/io/dataease/listener/XpackTaskStarter.java +++ b/core/core-backend/src/main/java/io/dataease/listener/XpackTaskStarter.java @@ -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()); + } } } diff --git a/core/core-backend/src/main/java/io/dataease/menu/manage/MenuManage.java b/core/core-backend/src/main/java/io/dataease/menu/manage/MenuManage.java index 3319213d2f..56c0b8c20a 100644 --- a/core/core-backend/src/main/java/io/dataease/menu/manage/MenuManage.java +++ b/core/core-backend/src/main/java/io/dataease/menu/manage/MenuManage.java @@ -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); } } diff --git a/core/core-backend/src/main/resources/i18n/core_zh_CN.properties b/core/core-backend/src/main/resources/i18n/core_zh_CN.properties index d7b38b465d..92383858c6 100644 --- a/core/core-backend/src/main/resources/i18n/core_zh_CN.properties +++ b/core/core-backend/src/main/resources/i18n/core_zh_CN.properties @@ -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 diff --git a/core/core-frontend/src/api/data-filling.ts b/core/core-frontend/src/api/data-filling.ts new file mode 100644 index 0000000000..ff017ecf1d --- /dev/null +++ b/core/core-frontend/src/api/data-filling.ts @@ -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 + createIndex: boolean + tableIndexes: Array + + 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 + 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 => { + return request + .post({ url: '/data-filling/tree', data: { ...data, ...{ busiFlag: 'data-filling' } } }) + .then(res => { + return res?.data + }) +} + +export const createFolder = (data = {}): Promise => { + return request + .post({ url: '/data-filling/save', data: { ...data, nodeType: 'folder' } }) + .then(res => { + return res?.data + }) +} +export const save = (data = {}): Promise => { + return request.post({ url: '/data-filling/save', data }).then(res => { + return res?.data + }) +} + +export const move = (data = {}): Promise => { + return request.post({ url: '/data-filling/move', data }).then(res => { + return res?.data + }) +} + +export const reName = (data = {}): Promise => { + return request.post({ url: '/data-filling/rename', data }).then(res => { + return res?.data + }) +} +export const listDatasourceList = (): Promise> => { + return request.get({ url: '/data-filling/datasource/list' }).then(res => { + return res?.data + }) +} + +export const getDataFilling = async (id: string): Promise => { + return request.get({ url: `/data-filling/get/${id}` }).then(res => { + return res?.data + }) +} + +export const deleteById = (id: string): Promise => { + return request.get({ url: '/data-filling/delete/' + id }) +} + +export const deleteRowData = (formId: string, id: number): Promise => { + return request.get({ url: `/data-filling/form/${formId}/delete/${id}` }) +} + +export const batchDeleteRowData = (formId: string, data: Array): Promise => { + return request.post({ url: `/data-filling/form/${formId}/batch-delete`, data }) +} + +export const getTableColumnData = ( + optionDatasource, + optionTable, + optionColumn, + optionOrder +): Promise => { + return request.post({ + url: `/data-filling/form/${optionDatasource}/options`, + data: { + optionTable: optionTable, + optionColumn: optionColumn, + optionOrder: optionOrder + } + }) +} + +export const searchTable = (id, data): Promise => { + return request.post({ + url: '/data-filling/form/' + id + '/tableData', + data + }) +} + +export const saveFormRowData = (formId, data): Promise => { + return request + .post({ + url: '/data-filling/form/' + formId + '/rowData/save', + data + }) + .then(res => { + return res?.data + }) +} + +export const saveTask = (data): Promise => { + return request.post({ + url: `/data-filling/task/save`, + data + }) +} + +export const getTaskInfo = (taskId): Promise => { + return request.get({ + url: `/data-filling/task/info/${taskId}` + }) +} diff --git a/core/core-frontend/src/assets/svg/icon_file-doc_colorful.svg b/core/core-frontend/src/assets/svg/icon_file-doc_colorful.svg new file mode 100644 index 0000000000..7371ef72ab --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_file-doc_colorful.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/core/core-frontend/src/assets/svg/icon_multi-line_outlined.svg b/core/core-frontend/src/assets/svg/icon_multi-line_outlined.svg new file mode 100644 index 0000000000..24c4b1cc2c --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_multi-line_outlined.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/icon_radio_outlined.svg b/core/core-frontend/src/assets/svg/icon_radio_outlined.svg new file mode 100644 index 0000000000..2206cec10f --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_radio_outlined.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/icon_single-line_outlined.svg b/core/core-frontend/src/assets/svg/icon_single-line_outlined.svg new file mode 100644 index 0000000000..5cd8e7b53d --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_single-line_outlined.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/icon_todo_outlined.svg b/core/core-frontend/src/assets/svg/icon_todo_outlined.svg new file mode 100644 index 0000000000..633b9b1ece --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_todo_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/core/core-frontend/src/components/icon-custom/src/Icon.vue b/core/core-frontend/src/components/icon-custom/src/Icon.vue index cd5c87b9e4..7d967ce2b3 100644 --- a/core/core-frontend/src/components/icon-custom/src/Icon.vue +++ b/core/core-frontend/src/components/icon-custom/src/Icon.vue @@ -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({ diff --git a/core/core-frontend/src/hooks/web/useMoveLine.ts b/core/core-frontend/src/hooks/web/useMoveLine.ts index 7602ad59e8..f1413f3c0d 100644 --- a/core/core-frontend/src/hooks/web/useMoveLine.ts +++ b/core/core-frontend/src/hooks/web/useMoveLine.ts @@ -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') diff --git a/core/core-frontend/src/locales/en.ts b/core/core-frontend/src/locales/en.ts index 06d6fefd59..191e0af9fa 100644 --- a/core/core-frontend/src/locales/en.ts +++ b/core/core-frontend/src/locales/en.ts @@ -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' } } diff --git a/core/core-frontend/src/locales/tw.ts b/core/core-frontend/src/locales/tw.ts index 68e07d703e..aaed10e25f 100644 --- a/core/core-frontend/src/locales/tw.ts +++ b/core/core-frontend/src/locales/tw.ts @@ -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: '根據操作人名稱搜索' } } diff --git a/core/core-frontend/src/locales/zh-CN.ts b/core/core-frontend/src/locales/zh-CN.ts index c887e48ef2..d86105cc7f 100644 --- a/core/core-frontend/src/locales/zh-CN.ts +++ b/core/core-frontend/src/locales/zh-CN.ts @@ -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: '根据操作人名称搜索' } } diff --git a/core/core-frontend/src/store/modules/interactive.ts b/core/core-frontend/src/store/modules/interactive.ts index 40d7392e98..c1e8292a02 100644 --- a/core/core-frontend/src/store/modules/interactive.ts +++ b/core/core-frontend/src/store/modules/interactive.ts @@ -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 } -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 => ({ diff --git a/core/core-frontend/src/utils/validate.ts b/core/core-frontend/src/utils/validate.ts index 1cef68b90b..efb9858a7d 100644 --- a/core/core-frontend/src/utils/validate.ts +++ b/core/core-frontend/src/utils/validate.ts @@ -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_-]+)+$' diff --git a/core/core-frontend/src/views/visualized/data/datasource/form/EditorDetail.vue b/core/core-frontend/src/views/visualized/data/datasource/form/EditorDetail.vue index 655a31d5ce..40b39e85ec 100644 --- a/core/core-frontend/src/views/visualized/data/datasource/form/EditorDetail.vue +++ b/core/core-frontend/src/views/visualized/data/datasource/form/EditorDetail.vue @@ -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({ + + + { 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 = [] } } diff --git a/core/core-frontend/src/views/visualized/data/datasource/index.vue b/core/core-frontend/src/views/visualized/data/datasource/index.vue index 111f822778..97082ce1a2 100644 --- a/core/core-frontend/src/views/visualized/data/datasource/index.vue +++ b/core/core-frontend/src/views/visualized/data/datasource/index.vue @@ -366,7 +366,8 @@ const defaultInfo = { configuration: null, syncSetting: null, apiConfiguration: [], - weight: 0 + weight: 0, + enableDataFill: false } const nodeInfo = reactive(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 }) diff --git a/core/core-frontend/src/views/workbranch/ShortcutTable.vue b/core/core-frontend/src/views/workbranch/ShortcutTable.vue index 8d5ec781a5..f93c122177 100644 --- a/core/core-frontend/src/views/workbranch/ShortcutTable.vue +++ b/core/core-frontend/src/views/workbranch/ShortcutTable.vue @@ -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 => { + + @@ -419,6 +422,10 @@ const getEmptyDesc = (): string => { + innerList(List ids) throws DEException; + @DePermit({"#p0+':read'"}) @GetMapping("/hidePw/{datasourceId}") DatasourceDTO hidePw(@PathVariable("datasourceId") Long datasourceId) throws DEException; diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/report/vo/ReportGridVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/report/vo/ReportGridVO.java index 50c7d59ff9..7dcb97e930 100644 --- a/sdk/api/api-base/src/main/java/io/dataease/api/report/vo/ReportGridVO.java +++ b/sdk/api/api-base/src/main/java/io/dataease/api/report/vo/ReportGridVO.java @@ -27,5 +27,7 @@ public class ReportGridVO implements Serializable { private String creator; + private String updater; + private Long createTime; } diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/DataFillingApi.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/DataFillingApi.java new file mode 100644 index 0000000000..d86b7baa59 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/DataFillingApi.java @@ -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 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 listDatasourceList(); + + @PostMapping("/form/{optionDatasource}/options") + List 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 ids) throws Exception; + + @PostMapping("/form/{formId}/rowData/save") + DataFillFormTableDataResponse saveRowData(@PathVariable Long formId, @RequestBody Map 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 taskPager(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody DfTaskInfoRequest request); + + @PostMapping("/sub-task/page/{goPage}/{pageSize}") + IPage subTaskPager(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody DfSubTaskInfoRequest request); + + @PostMapping("/task/delete") + void batchDeleteTask(@RequestBody List 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 ids) throws Exception; + + @GetMapping("/sub-task/{id}/users/list/{type}") + List> listSubTaskUser(@PathVariable Long id, @PathVariable String type) throws Exception; + + @PostMapping("/user-task") + List 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 data) throws Exception; + + + @PostMapping("/log/page/{goPage}/{pageSize}") + IPage taskPager(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody DfCommitLogRequest request); + + +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/ColumnOption.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/ColumnOption.java new file mode 100644 index 0000000000..676eccf783 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/ColumnOption.java @@ -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; +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DataFillFormTableDataRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DataFillFormTableDataRequest.java new file mode 100644 index 0000000000..a843ddfff8 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DataFillFormTableDataRequest.java @@ -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 primaryKeyValueList; + +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DataFillFormTableDataResponse.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DataFillFormTableDataResponse.java new file mode 100644 index 0000000000..4918a5b904 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DataFillFormTableDataResponse.java @@ -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; + +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DataFillingDTO.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DataFillingDTO.java new file mode 100644 index 0000000000..e7187cdc61 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DataFillingDTO.java @@ -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; + + +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DatasourceOptionsRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DatasourceOptionsRequest.java new file mode 100644 index 0000000000..c20c24b4c5 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DatasourceOptionsRequest.java @@ -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; +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfCommitLog.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfCommitLog.java new file mode 100644 index 0000000000..60962f88a3 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfCommitLog.java @@ -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; +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfCommitLogRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfCommitLogRequest.java new file mode 100644 index 0000000000..f5de44a938 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfCommitLogRequest.java @@ -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; +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfSubTaskInfoRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfSubTaskInfoRequest.java new file mode 100644 index 0000000000..600a2a1831 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfSubTaskInfoRequest.java @@ -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; + +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfSubTaskVo.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfSubTaskVo.java new file mode 100644 index 0000000000..17c17cc84b --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfSubTaskVo.java @@ -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; + + +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfTaskInfoRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfTaskInfoRequest.java new file mode 100644 index 0000000000..955028e675 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfTaskInfoRequest.java @@ -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 uidList; + + private List lastStatusList; + + private List statusList; + + private List timeList; + + private String keyword; + + private Boolean timeDesc; +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfUserTaskData.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfUserTaskData.java new file mode 100644 index 0000000000..8bce741982 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfUserTaskData.java @@ -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 dataIds; + + private List subInstances; + + private String form; + + private String formExtSetting; + + +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfUserTaskRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfUserTaskRequest.java new file mode 100644 index 0000000000..42a8bcdf2b --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfUserTaskRequest.java @@ -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; +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfUserTaskVo.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfUserTaskVo.java new file mode 100644 index 0000000000..0d369925a6 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/DfUserTaskVo.java @@ -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; + +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/TaskInfoGridVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/TaskInfoGridVO.java new file mode 100644 index 0000000000..d3c9ce1423 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/TaskInfoGridVO.java @@ -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; + +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/TaskInfoVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/TaskInfoVO.java new file mode 100644 index 0000000000..79c934c8cc --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/dataFilling/dto/TaskInfoVO.java @@ -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 reciFlagList; + + @JsonSerialize(using = LongArray2StringSerialize.class) + private List uidList; + + @JsonSerialize(using = LongArray2StringSerialize.class) + private List 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; + +} diff --git a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/user/api/UserApi.java b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/user/api/UserApi.java index ab368e28f2..8ffbbdc5c5 100644 --- a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/user/api/UserApi.java +++ b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/user/api/UserApi.java @@ -194,4 +194,12 @@ public interface UserApi { @PostMapping("/subOrgUser") List subOrgUser(@RequestBody List oidList); + List getRecipientUserIds(UserReciRequest request); + + List getUserIdByAccount(String account); + + List getUserIdByName(String name); + + List> listUserInfosByIds(List ids); + } diff --git a/sdk/common/src/main/java/io/dataease/constant/AuthResourceEnum.java b/sdk/common/src/main/java/io/dataease/constant/AuthResourceEnum.java index bef3c219ee..40cdd10ff2 100644 --- a/sdk/common/src/main/java/io/dataease/constant/AuthResourceEnum.java +++ b/sdk/common/src/main/java/io/dataease/constant/AuthResourceEnum.java @@ -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; diff --git a/sdk/common/src/main/java/io/dataease/constant/BusiResourceEnum.java b/sdk/common/src/main/java/io/dataease/constant/BusiResourceEnum.java index 7d582d0ce8..fcb1143930 100644 --- a/sdk/common/src/main/java/io/dataease/constant/BusiResourceEnum.java +++ b/sdk/common/src/main/java/io/dataease/constant/BusiResourceEnum.java @@ -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; diff --git a/sdk/common/src/main/java/io/dataease/constant/DadaFillingFinishTaskEnum.java b/sdk/common/src/main/java/io/dataease/constant/DadaFillingFinishTaskEnum.java new file mode 100644 index 0000000000..532e1bf3a4 --- /dev/null +++ b/sdk/common/src/main/java/io/dataease/constant/DadaFillingFinishTaskEnum.java @@ -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(); + } +} diff --git a/sdk/common/src/main/java/io/dataease/utils/LongArray2StringSerialize.java b/sdk/common/src/main/java/io/dataease/utils/LongArray2StringSerialize.java new file mode 100644 index 0000000000..0858600837 --- /dev/null +++ b/sdk/common/src/main/java/io/dataease/utils/LongArray2StringSerialize.java @@ -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> { + + @Override + public void serialize(List longs, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + List list = new ArrayList<>(); + for (Long str : longs) { + if (str != null) { + list.add(str.toString()); + } + } + jsonGenerator.writeObject(list); + } +} diff --git a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/DatasourceDTO.java b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/DatasourceDTO.java index 81ee90d0b4..79af9509e6 100644 --- a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/DatasourceDTO.java +++ b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/DatasourceDTO.java @@ -89,4 +89,6 @@ public class DatasourceDTO implements Serializable { * 任务状态 */ private String taskStatus; + + private Boolean enableDataFill; } diff --git a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/DatasourceRequest.java b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/DatasourceRequest.java index 1eb97c02a9..e8392f7655 100644 --- a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/DatasourceRequest.java +++ b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/DatasourceRequest.java @@ -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 dsList; + private List tableFieldWithValues; public DatasourceRequest() { } diff --git a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/SimpleDatasourceDTO.java b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/SimpleDatasourceDTO.java new file mode 100644 index 0000000000..4c0c938d77 --- /dev/null +++ b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/SimpleDatasourceDTO.java @@ -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; +} diff --git a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/TableField.java b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/TableField.java index ba0f94468f..fb2474b6c2 100644 --- a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/TableField.java +++ b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/TableField.java @@ -19,7 +19,9 @@ public class TableField { private Integer deExtractType; private int extField; private String jsonPath; + private boolean primary; List value; + private int inCount; } diff --git a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/TableFieldWithValue.java b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/TableFieldWithValue.java new file mode 100644 index 0000000000..211d94492e --- /dev/null +++ b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/TableFieldWithValue.java @@ -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()); + } +} diff --git a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/provider/Provider.java b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/provider/Provider.java index da431d3a75..ab7f5c9251 100644 --- a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/provider/Provider.java +++ b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/provider/Provider.java @@ -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 lPorts = new HashMap<>(); @Getter