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 d2f6d4d8c5..926674c050 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 @@ -20,7 +20,7 @@ i18n_menu.org=\u7EC4\u7EC7\u7BA1\u7406 i18n_menu.auth=\u6743\u9650\u914D\u7F6E i18n_menu.sync=\u540C\u6B65\u7BA1\u7406 i18n_menu.summary=\u6982\u89C8 -i18n_menu.ds=\u6570\u636E\u6E90\u7BA1\u7406 +i18n_menu.ds=\u6570\u636e\u8fde\u63a5\u7ba1\u7406 i18n_menu.task=\u4EFB\u52A1\u7BA1\u7406 i18n_menu.embedded=\u5D4C\u5165\u5F0F\u7BA1\u7406 i18n_menu.platform=\u5E73\u53F0\u5BF9\u63A5 diff --git a/core/core-frontend/src/api/sync/syncDatasource.ts b/core/core-frontend/src/api/sync/syncDatasource.ts new file mode 100644 index 0000000000..5a9686c8fd --- /dev/null +++ b/core/core-frontend/src/api/sync/syncDatasource.ts @@ -0,0 +1,47 @@ +import request from '@/config/axios' + +export const sourceDsPageApi = (page: number, limit: number, data) => { + return request.post({ url: `/sync/datasource/source/pager/${page}/${limit}`, data }) +} + +export const targetDsPageApi = (page: number, limit: number, data) => { + return request.post({ url: `/sync/datasource/target/pager/${page}/${limit}`, data }) +} +export const latestUseApi = () => { + return request.post({ url: '/sync/datasource/latestUse', data: {} }) +} + +export const validateApi = data => { + return request.post({ url: '/sync/datasource/validate', data }) +} + +export const getSchemaApi = data => { + return request.post({ url: '/sync/datasource/getSchema', data }) +} + +export const saveApi = data => { + return request.post({ url: '/sync/datasource/save', data }) +} + +export const getByIdApi = (id: string) => { + return request.get({ url: `/sync/datasource/get/${id}` }) +} + +export const updateApi = data => { + return request.post({ url: '/sync/datasource/update', data }) +} + +export const deleteByIdApi = (id: string) => { + return request.post({ url: `/sync/datasource/delete/${id}` }) +} + +export const batchDelApi = (ids: string[]) => { + return request.post({ url: `/sync/datasource/batchDel`, data: ids }) +} + +/** + * 获取源数据库字段集合以及目标数据库数据类型集合 + */ +export const getFieldListApi = data => { + return request.post({ url: `/sync/datasource/fields`, data }) +} diff --git a/core/core-frontend/src/api/sync/syncSummary.ts b/core/core-frontend/src/api/sync/syncSummary.ts new file mode 100644 index 0000000000..801c83f963 --- /dev/null +++ b/core/core-frontend/src/api/sync/syncSummary.ts @@ -0,0 +1,26 @@ +import request from '@/config/axios' + +interface IResourceCount { + jobCount: number + datasourceCount: number + jobLogCount: number +} + +export const getResourceCount = () => { + return request + .get({ + url: 'sync/summary/resourceCount', + method: 'get' + }) + .then(res => { + return res.data as IResourceCount + }) +} + +export const getJobLogLienChartInfo = () => { + return request.post({ + url: '/sync/summary/logChartData', + method: 'post', + data: '' + }) +} diff --git a/core/core-frontend/src/api/sync/syncTask.ts b/core/core-frontend/src/api/sync/syncTask.ts new file mode 100644 index 0000000000..d359119601 --- /dev/null +++ b/core/core-frontend/src/api/sync/syncTask.ts @@ -0,0 +1,224 @@ +import request from '@/config/axios' + +export interface IGetTaskInfoReq { + id?: string + name?: string +} + +export interface ITaskInfoInsertReq { + [key: string]: any +} + +export interface ISchedulerOption { + interval: number + unit: string +} + +export interface ISource { + type: string + query: string + tables: string + datasourceId: string + tableExtract: string + dsTableList?: IDsTable[] + dsList?: [] + fieldList?: ITableField[] + targetFieldTypeList?: string[] + incrementCheckbox?: string + incrementField?: string +} + +export interface ITableField { + id: string + fieldSource: string + fieldName: string + fieldType: string + remarks: string + fieldSize: number + fieldPk: boolean + fieldIndex: boolean +} + +export interface ITargetProperty { + /** + * 启用分区on + */ + partitionEnable: string + /** + * 分区类型 + * DateRange 日期 + * NumberRange 数值 + * List 列 + */ + partitionType: string + /** + * 启用动态分区on + */ + dynamicPartitionEnable: string + /** + * 动态分区结束偏移量 + */ + dynamicPartitionEnd: number + /** + * 动态分区间隔单位 + * HOUR WEEK DAY MONTH YEAR + */ + dynamicPartitionTimeUnit: string + /** + * 手动分区列值 + * 多个以','隔开 + */ + manualPartitionColumnValue: string + /** + * 手动分区数值区间开始值 + */ + manualPartitionStart: number + /** + * 手动分区数值区间结束值 + */ + manualPartitionEnd: number + /** + * 手动分区数值区间间隔 + */ + manualPartitionInterval: number + /** + * 手动分区日期区间 + * 2023-09-08 - 2023-09-15 + */ + manualPartitionTimeRange: string + /** + * 手动分区日期区间间隔单位 + */ + manualPartitionTimeUnit: string + /** + * 分区字段 + */ + partitionColumn: string +} + +export interface ITarget { + createTable?: string + type: string + fieldList: ITableField[] + tableName: string + datasourceId: string + targetProperty: string + dsList?: [] + multipleSelection?: ITableField[] + property: ITargetProperty +} + +export class ITaskInfoRes { + id: string + + name: string + + schedulerType: string + + schedulerConf: string + + schedulerOption: ISchedulerOption + + taskKey: string + + desc: string + + executorTimeout: number + + executorFailRetryCount: number + + source: ISource + + target: ITarget + + status: string + startTime: string + stopTime: string + + constructor( + id: string, + name: string, + schedulerType: string, + schedulerConf: string, + taskKey: string, + desc: string, + executorTimeout: number, + executorFailRetryCount: number, + source: ISource, + target: ITarget, + status: string, + startTime: string, + stopTime: string, + schedulerOption: ISchedulerOption + ) { + this.id = id + this.name = name + this.schedulerType = schedulerType + this.schedulerConf = schedulerConf + this.taskKey = taskKey + this.desc = desc + this.executorTimeout = executorTimeout + this.executorFailRetryCount = executorFailRetryCount + this.source = source + this.target = target + this.status = status + this.startTime = startTime + this.stopTime = stopTime + this.schedulerOption = schedulerOption + } +} + +export interface ITaskInfoUpdateReq { + [key: string]: any +} + +export interface IDsTable { + datasourceId: string + name: string + remark: string + enableCheck: string + datasetPath: string +} + +export const getDatasourceListByTypeApi = (type: string) => { + return request.get({ url: `/sync/datasource/list/${type}` }) +} +export const getTaskInfoListApi = (current: number, size: number, data) => { + return request.post({ url: `/sync/task/pager/${current}/${size}`, data: data }) +} + +export const executeOneApi = (id: string) => { + return request.get({ url: `/sync/task/execute/${id}` }) +} + +export const startTaskApi = (id: string) => { + return request.get({ url: `/sync/task/start/${id}` }) +} + +export const stopTaskApi = (id: string) => { + return request.get({ url: `/sync/task/stop/${id}` }) +} + +export const addApi = (data: ITaskInfoInsertReq) => { + return request.post({ url: `/sync/task/add`, data: data }) +} + +export const removeApi = (taskId: string) => { + return request.delete({ url: `/sync/task/remove/${taskId}` }) +} + +export const batchRemoveApi = (taskIds: string[]) => { + return request.post({ url: `/sync/task/batch/del`, data: taskIds }) +} + +export const modifyApi = (data: ITaskInfoUpdateReq) => { + return request.post({ url: `/sync/task/update`, data: data }) +} + +export const findTaskInfoByIdApi = (taskId: string) => { + return request.get({ url: `/sync/task/get/${taskId}` }) +} + +export const getDatasourceTableListApi = (dsId: string) => { + return request.get({ url: `/sync/datasource/table/list/${dsId}` }) +} diff --git a/core/core-frontend/src/api/sync/syncTaskLog.ts b/core/core-frontend/src/api/sync/syncTaskLog.ts new file mode 100644 index 0000000000..d9b6ffc3f6 --- /dev/null +++ b/core/core-frontend/src/api/sync/syncTaskLog.ts @@ -0,0 +1,20 @@ +import request from '@/config/axios' + +export const getTaskLogListApi = (current: number, size: number, data: any) => { + return request.post({ + url: `/sync/task/log/pager/${current}/${size}`, + data: data + }) +} + +export const removeApi = (logId: string) => { + return request.delete({ url: `/sync/task/log/delete/${logId}` }) +} + +export const getTaskLogDetailApi = (logId: string, fromLineNum: number) => { + return request.get({ url: `/sync/task/log/detail/${logId}/${fromLineNum}` }) +} + +export const clear = (clearData: {}) => { + return request.post({ url: `/sync/task/log/clear`, data: clearData }) +} diff --git a/core/core-frontend/src/assets/svg/icon_sync_close_log_details.svg b/core/core-frontend/src/assets/svg/icon_sync_close_log_details.svg new file mode 100644 index 0000000000..7c0dc4cbc5 --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_sync_close_log_details.svg @@ -0,0 +1,3 @@ + + + diff --git a/core/core-frontend/src/assets/svg/icon_sync_datasource.svg b/core/core-frontend/src/assets/svg/icon_sync_datasource.svg new file mode 100644 index 0000000000..1e3fc9db1d --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_sync_datasource.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/icon_sync_log_number.svg b/core/core-frontend/src/assets/svg/icon_sync_log_number.svg new file mode 100644 index 0000000000..49869e0981 --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_sync_log_number.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/icon_sync_logs_outlined.svg b/core/core-frontend/src/assets/svg/icon_sync_logs_outlined.svg new file mode 100644 index 0000000000..e310452c05 --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_sync_logs_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/core/core-frontend/src/assets/svg/icon_sync_target_to_datasource.svg b/core/core-frontend/src/assets/svg/icon_sync_target_to_datasource.svg new file mode 100644 index 0000000000..d84bc12a9e --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_sync_target_to_datasource.svg @@ -0,0 +1,3 @@ + + + diff --git a/core/core-frontend/src/assets/svg/icon_sync_task_number.svg b/core/core-frontend/src/assets/svg/icon_sync_task_number.svg new file mode 100644 index 0000000000..bce4a1e198 --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_sync_task_number.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/core/core-frontend/src/components/drawer-filter/src/DrawerTimeFilter.vue b/core/core-frontend/src/components/drawer-filter/src/DrawerTimeFilter.vue index 8fd955d120..68ef025353 100644 --- a/core/core-frontend/src/components/drawer-filter/src/DrawerTimeFilter.vue +++ b/core/core-frontend/src/components/drawer-filter/src/DrawerTimeFilter.vue @@ -1,46 +1,66 @@ @@ -48,108 +68,42 @@ defineExpose({
{{ title }}
- {{ $t(ele.name) }} - - - - - - - - +
- diff --git a/core/core-frontend/src/components/drawer-main/src/DrawerMain.vue b/core/core-frontend/src/components/drawer-main/src/DrawerMain.vue index 14b167ef36..13853900ea 100644 --- a/core/core-frontend/src/components/drawer-main/src/DrawerMain.vue +++ b/core/core-frontend/src/components/drawer-main/src/DrawerMain.vue @@ -14,7 +14,8 @@ const props = defineProps({ type: propTypes.string, field: propTypes.string, option: propTypes.array, - title: propTypes.string + title: propTypes.string, + property: propTypes.shape({}) }) ), title: propTypes.string @@ -126,7 +127,8 @@ defineExpose({ :ref="el => (myRefs[index] = el)" v-if="component.type === 'time'" :title="component.title" - @filter-change="v => filterChange(v, component.field, 'eq')" + :property="component.property" + @filter-change="v => filterChange(v, component.field, component.operator)" /> diff --git a/core/core-frontend/src/locales/zh-CN.ts b/core/core-frontend/src/locales/zh-CN.ts index 7c29dca6a3..82fd13f4f2 100644 --- a/core/core-frontend/src/locales/zh-CN.ts +++ b/core/core-frontend/src/locales/zh-CN.ts @@ -2131,5 +2131,56 @@ export default { template_manage: { name_already_exists_type: '分类名称已存在', the_same_category: '同一分类下,该模板名称已存在' + }, + sync_manage: { + title: '同步管理', + ds_search_placeholder: '搜索名称,描述' + }, + sync_datasource: { + title: '数据连接管理', + source_ds: '源数据源', + target_ds: '目标数据源', + add_source_ds: '@:common.add@:sync_datasource.source_ds', + add_target_ds: '@:common.add@:sync_datasource.target_ds', + name: '名称', + desc: '描述', + type: '类型', + status: '状态', + create_time: '创建时间', + update_time: '更新时间', + operation: '操作', + edit: '编辑', + delete: '删除', + confirm_batch_delete_target_ds: '确定删除{0}个目标数据源吗?', + confirm_batch_delete_source_ds: '确定删除{0}个源数据源吗?' + }, + sync_task: { + title: '任务管理', + list: '任务列表', + log_list: '任务日志', + add_task: '添加任务', + name: '名称', + desc: '描述', + status: '状态', + create_time: '创建时间', + update_time: '更新时间', + operation: '操作', + edit: '编辑', + delete: '删除', + start: '启动', + stop: '停止', + trigger_last_time: '上次执行时间', + trigger_next_time: '下次执行时间', + status_success: '成功', + status_running: '执行中', + status_failed: '失败', + status_stopped: '已停止', + status_waiting: '等待执行', + status_done: '执行结束', + status_suspend: '暂停', + running_one: '执行一次', + keep_going: '继续', + log: '日志', + show_log: '查看日志' } } diff --git a/sdk/api/api-sync/pom.xml b/sdk/api/api-sync/pom.xml new file mode 100644 index 0000000000..5e36463122 --- /dev/null +++ b/sdk/api/api-sync/pom.xml @@ -0,0 +1,20 @@ + + + + api + io.dataease + 2.1.0 + + 4.0.0 + + api-sync + + + 17 + 17 + UTF-8 + + + \ No newline at end of file diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/api/SyncDatasourceApi.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/api/SyncDatasourceApi.java new file mode 100644 index 0000000000..4e5d7c6cd5 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/api/SyncDatasourceApi.java @@ -0,0 +1,80 @@ +package io.dataease.api.sync.datasource.api; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.dataease.api.sync.datasource.dto.DBTableDTO; +import io.dataease.api.sync.datasource.dto.GetDatasourceRequest; +import io.dataease.api.sync.datasource.dto.SyncDatasourceDTO; +import io.dataease.api.sync.datasource.vo.SyncDatasourceVO; +import io.dataease.auth.DeApiPath; +import io.dataease.auth.DePermit; +import io.dataease.exception.DEException; +import io.dataease.request.BaseGridRequest; +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.SYNC_DATASOURCE; + +/** + * @author fit2cloud + * @date 2023/11/20 10:14 + **/ +@DeApiPath(value = "/sync/datasource", rt = SYNC_DATASOURCE) +public interface SyncDatasourceApi { + + @DePermit("m:read") + @PostMapping("/source/pager/{goPage}/{pageSize}") + IPage sourcePager(@PathVariable("goPage") int goPage, @PathVariable("pageSize") int pageSize, @RequestBody BaseGridRequest request); + + @DePermit("m:read") + @PostMapping("/target/pager/{goPage}/{pageSize}") + IPage targetPager(@PathVariable("goPage") int goPage, @PathVariable("pageSize") int pageSize, @RequestBody BaseGridRequest request); + + @PostMapping("/save") + void save(@RequestBody SyncDatasourceDTO dataSourceDTO) throws DEException; + + @PostMapping("/update") + void update(@RequestBody SyncDatasourceDTO dataSourceDTO) throws DEException; + + @PostMapping("/delete/{datasourceId}") + void delete(@PathVariable("datasourceId") String datasourceId) throws DEException; + + @GetMapping("/types") + Object datasourceTypes() throws DEException; + + @PostMapping("/validate") + String validate(@RequestBody SyncDatasourceDTO dataSourceDTO) throws DEException; + + @PostMapping("/getSchema") + List getSchema(@RequestBody SyncDatasourceDTO dataSourceDTO) throws DEException; + + @DePermit({"#p0+':manage'"}) + @GetMapping("/validate/{datasourceId}") + SyncDatasourceDTO validate(@PathVariable("datasourceId") String datasourceId) throws DEException; + + @PostMapping("/latestUse") + List latestUse(); + + @GetMapping("/get/{datasourceId}") + SyncDatasourceDTO get(@PathVariable("datasourceId") String datasourceId) throws DEException; + + @PostMapping("/batchDel") + void batchDel(@RequestBody List ids) throws DEException; + + @PostMapping("/fields") + Map getFields(@RequestBody GetDatasourceRequest getDsRequest) throws DEException ; + + @GetMapping("/list/{type}") + List listByType(@PathVariable("type") String type) throws DEException; + + @GetMapping("/table/list/{dsId}") + List getTableList(@PathVariable("dsId") String dsId) throws DEException; + + + + +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/dto/DBTableDTO.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/dto/DBTableDTO.java new file mode 100644 index 0000000000..a8112d8e26 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/dto/DBTableDTO.java @@ -0,0 +1,18 @@ +package io.dataease.api.sync.datasource.dto; + +import lombok.Getter; +import lombok.Setter; + +/** + * @Author gin + * @Date 2021/4/30 10:57 上午 + */ +@Getter +@Setter +public class DBTableDTO { + private String datasourceId; + private String name; + private String remark; + private boolean enableCheck; + private String datasetPath; +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/dto/GetDatasourceRequest.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/dto/GetDatasourceRequest.java new file mode 100644 index 0000000000..7387082ca2 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/dto/GetDatasourceRequest.java @@ -0,0 +1,25 @@ +package io.dataease.api.sync.datasource.dto; + +import lombok.Data; + +@Data +public class GetDatasourceRequest extends SyncDatasourceDTO { + + /** + * 查询sql + */ + private String query; + /** + * 表名 + */ + private String table; + /** + * 表格的抽取数据方式 + */ + private boolean tableExtract; + /** + * 不为空时,获取源数据库表字段,将转换为doris的数据类型 + */ + private String targetDbType; + +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/dto/SyncDatasourceDTO.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/dto/SyncDatasourceDTO.java new file mode 100644 index 0000000000..8c8146f655 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/dto/SyncDatasourceDTO.java @@ -0,0 +1,61 @@ +package io.dataease.api.sync.datasource.dto; + +import lombok.Data; + +/** + * @author fit2cloud + * @date 2023/11/20 11:14 + **/ +@Data +public class SyncDatasourceDTO { + + /** + * ID + */ + private String id; + + /** + * 名称 + */ + private String name; + + /** + * 描述 + */ + private String desc; + + /** + * 类型 + */ + private String type; + + /** + * 详细信息 + */ + private String configuration; + + /** + * Create timestamp + */ + private Long createTime; + + /** + * Update timestamp + */ + private Long updateTime; + + /** + * 创建人ID + */ + private Long createBy; + private String createByUserName; + + /** + * 状态 + */ + private String status; + + private String statusRemark; + + +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/vo/SyncDatasourceVO.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/vo/SyncDatasourceVO.java new file mode 100644 index 0000000000..385b8a94ee --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/datasource/vo/SyncDatasourceVO.java @@ -0,0 +1,57 @@ +package io.dataease.api.sync.datasource.vo; + +import lombok.Data; + +/** + * @author fit2cloud + * @date 2023/11/20 11:18 + **/ +@Data +public class SyncDatasourceVO { + /** + * ID + */ + private String id; + + /** + * 名称 + */ + private String name; + + /** + * 描述 + */ + private String desc; + + /** + * 类型 + */ + private String type; + + /** + * 详细信息 + */ + private String configuration; + + /** + * Create timestamp + */ + private Long createTime; + + /** + * Update timestamp + */ + private Long updateTime; + + /** + * 创建人 + */ + private Long createBy; + private String createByName; + + /** + * 状态 + */ + private String status; + private String statusRemark; +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/summary/api/SummaryApi.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/summary/api/SummaryApi.java new file mode 100644 index 0000000000..9e83033c18 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/summary/api/SummaryApi.java @@ -0,0 +1,26 @@ +package io.dataease.api.sync.summary.api; + +import io.dataease.auth.DeApiPath; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.Map; + +import static io.dataease.constant.AuthResourceEnum.SUMMARY; + +/** + * @author fit2cloud + * @date 2023/12/4 12:43 + **/ +@DeApiPath(value = "/sync/summary", rt = SUMMARY) +public interface SummaryApi { + + @GetMapping("/resourceCount") + Map resourceCount(); + + @PostMapping("/logChartData") + Map logChartData(@RequestBody String executeTaskLogDate); + + +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/api/TaskApi.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/api/TaskApi.java new file mode 100644 index 0000000000..f272b1a919 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/api/TaskApi.java @@ -0,0 +1,52 @@ +package io.dataease.api.sync.task.api; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.dataease.api.sync.task.dto.TaskInfoDTO; +import io.dataease.api.sync.task.vo.TaskInfoVO; +import io.dataease.auth.DeApiPath; +import io.dataease.exception.DEException; +import io.dataease.request.BaseGridRequest; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static io.dataease.constant.AuthResourceEnum.TASK; + +/** + * @author fit2cloud + * @date 2023/11/20 10:14 + **/ +@DeApiPath(value = "/sync/task", rt = TASK) +public interface TaskApi { + + @PostMapping("/pager/{goPage}/{pageSize}") + IPage pager(@PathVariable("goPage") int goPage, @PathVariable("pageSize") int pageSize, @RequestBody BaseGridRequest request); + + @PostMapping("/add") + void add(@RequestBody TaskInfoDTO jobInfo) throws DEException; + + @PostMapping("/update") + void update(@RequestBody TaskInfoDTO jobInfo) throws DEException; + + @DeleteMapping("/remove/{id}") + void remove(@PathVariable(value = "id") String id) throws DEException; + + @GetMapping("start/{id}") + void startJob(@PathVariable(value = "id") String id) throws DEException; + + @GetMapping("stop/{id}") + void stopJob(@PathVariable(value = "id") String id) throws DEException; + + @GetMapping("/get/{id}") + TaskInfoVO getOneById(@PathVariable(value = "id") String id) throws DEException; + + @GetMapping("/execute/{id}") + void execute(@PathVariable(value = "id") String id) throws DEException; + + @PostMapping("/batch/del") + void batchDelete(@RequestBody List ids) throws DEException; + + @GetMapping("/count") + Long count() throws DEException; + +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/api/TaskLogApi.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/api/TaskLogApi.java new file mode 100644 index 0000000000..925eec1254 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/api/TaskLogApi.java @@ -0,0 +1,39 @@ +package io.dataease.api.sync.task.api; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.dataease.api.sync.task.vo.LogResultVO; +import io.dataease.api.sync.task.vo.TaskLogVO; +import io.dataease.auth.DeApiPath; +import io.dataease.request.BaseGridRequest; +import org.springframework.web.bind.annotation.*; + +import static io.dataease.constant.AuthResourceEnum.TASK_LOG; + +/** + * @author fit2cloud + * @date 2023/12/4 12:43 + **/ +@DeApiPath(value = "/sync/task/log", rt = TASK_LOG) +public interface TaskLogApi { + @PostMapping("/pager/{goPage}/{pageSize}") + IPage pager(@PathVariable("goPage") int goPage, @PathVariable("pageSize") int pageSize, @RequestBody BaseGridRequest request); + + @GetMapping("/detail/{logId}/{fromLineNum}") + LogResultVO logDetail(@PathVariable("logId") String logId, @PathVariable("fromLineNum") int fromLineNum); + + @PostMapping("/save") + void saveLog(@RequestBody TaskLogVO logDetail); + + @PostMapping("/update") + void updateLog(@RequestBody TaskLogVO logDetail); + + @DeleteMapping("/deleteByJobId/{jobId}") + void deleteByJobId(@PathVariable("jobId") String jobId); + + @DeleteMapping("/delete/{logId}") + void deleteById(@PathVariable("logId") String logId); + + @PostMapping("/clear") + void clearJobLog(@RequestBody TaskLogVO taskLogVO); + +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/Source.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/Source.java new file mode 100644 index 0000000000..6c7c908c17 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/Source.java @@ -0,0 +1,23 @@ +package io.dataease.api.sync.task.dto; + +import io.dataease.api.sync.datasource.dto.SyncDatasourceDTO; +import lombok.Data; + +import java.util.List; + + +/** + * @author fit2cloud + * @date 2023/8/10 16:38 + **/ +@Data +public class Source { + private String type; + private String query; + private String tables; + private SyncDatasourceDTO datasource; + private String datasourceId; + private String tableExtract; + private List fieldList; + private String incrementField; +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/TableField.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/TableField.java new file mode 100644 index 0000000000..ec6b79d07b --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/TableField.java @@ -0,0 +1,22 @@ +package io.dataease.api.sync.task.dto; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author fit2cloud + */ +@Setter +@Getter +public class TableField { + private String fieldSource; + private String fieldName; + private String remarks; + private String fieldType; + private int fieldSize; + private boolean fieldPk; + private boolean fieldIndex; + private int accuracy; + private Object defaultValue; + +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/Target.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/Target.java new file mode 100644 index 0000000000..66ab74ea5d --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/Target.java @@ -0,0 +1,21 @@ +package io.dataease.api.sync.task.dto; + +import io.dataease.api.sync.datasource.dto.SyncDatasourceDTO; +import lombok.Data; + +import java.util.List; + +/** + * @author fit2cloud + * @date 2023/8/10 16:39 + **/ +@Data +public class Target { + private String type; + private String createTable; + private List fieldList; + private String tableName; + private SyncDatasourceDTO datasource; + private String datasourceId; + private String targetProperty; +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/TaskInfoDTO.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/TaskInfoDTO.java new file mode 100644 index 0000000000..03c05a7869 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/dto/TaskInfoDTO.java @@ -0,0 +1,112 @@ +package io.dataease.api.sync.task.dto; + +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author fit2cloud + * @date 2023/11/28 17:17 + **/ +@Data +public class TaskInfoDTO { + private String id; + + private String name; + + /** + * 任务类型KEY + */ + private String jobKey; + + private String desc; + + private LocalDateTime createTime; + + private LocalDateTime modifyTime; + + /** + * 创建人 + */ + private Long createBy; + + /** + * 修改人 + */ + private Long modifyBy; + + /** + * 任务参数 + */ + private String parameter; + + /** + * 扩展参数 + */ + private String extParameter; + + /** + * 当前任务状态 + * unexecuted未执行 currentTime=currentTime>=startTime,status=1 + * suspend暂停 stopTime>=currentTime>=startTime,status=0 + * done执行结束 currentTime>stopTime + * running执行中,通过当前任务的日志状态判断,如果有日志在执行中 + */ + private String status; + + /** + * 删除标识 + */ + private Boolean deleted; + + /** + * 任务执行超时时间 + */ + private Long executorTimeout; + + /** + * 任务执行失败重试次数 + */ + private Long executorFailRetryCount; + + /** + * 上次调度时间 + */ + private Long triggerLastTime; + + /** + * 下次次调度时间 + */ + private Long triggerNextTime; + + /** + * 调度类型,NONE,CRON,FIX_RATE,FIX_DELAY + */ + private String schedulerType; + + /** + * 调度配置,取决于调度类型 + */ + private String schedulerConf; + + /** + * 开始时间 + */ + private String startTime; + + /** + * 结束时间 + */ + private String stopTime; + + + /** + * 源数据源信息 + */ + private Source source; + /** + * 目标数据源信息 + */ + private Target target; +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/vo/LogResultVO.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/vo/LogResultVO.java new file mode 100644 index 0000000000..58d62e9ee0 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/vo/LogResultVO.java @@ -0,0 +1,46 @@ +package io.dataease.api.sync.task.vo; + +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 日志返回结果 + * + * @author fit2cloud + */ +@Getter +@Setter +@NoArgsConstructor +public class LogResultVO implements Serializable{ + + /** + * 日志开始行号 + */ + private int fromLineNum; + /** + * 日志结束行号 + */ + private int toLineNum; + /** + * 日志内容 + */ + private String logContent; + /** + * 是否是最后一行 + */ + private boolean isEnd; + + public LogResultVO(int fromLineNum, int toLineNum, String logContent, boolean isEnd) { + this.fromLineNum = fromLineNum; + this.toLineNum = toLineNum; + this.logContent = logContent; + this.isEnd = isEnd; + } + + +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/vo/TaskInfoVO.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/vo/TaskInfoVO.java new file mode 100644 index 0000000000..e814ac3fd5 --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/vo/TaskInfoVO.java @@ -0,0 +1,132 @@ +package io.dataease.api.sync.task.vo; + +import io.dataease.api.sync.task.dto.Source; +import io.dataease.api.sync.task.dto.Target; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author fit2cloud + * @date 2023/11/28 17:15 + **/ +@Data +public class TaskInfoVO { + + private String id; + + private String name; + + /** + * 任务类型KEY + */ + private String jobKey; + + private String desc; + + private LocalDateTime createTime; + + private LocalDateTime modifyTime; + + /** + * 创建人 + */ + private Long createBy;; + /** + * 创建人 + */ + private String userName; + + /** + * 任务参数 + */ + private String parameter; + + /** + * 扩展参数 + */ + private String extParameter; + + /** + * 任务状态 + * unexecuted未执行 currentTime=currentTime>=startTime,status=1 + * suspend暂停 stopTime>=currentTime>=startTime,status=0 + * done执行结束 currentTime>stopTime + * running执行中,通过当前任务的日志状态判断,如果有日志在执行中 + */ + private String status; + + /** + * 删除标识 + */ + private Boolean deleted; + + /** + * 任务执行超时时间 + */ + private Long executorTimeout; + + /** + * 任务执行失败重试次数 + */ + private Long executorFailRetryCount; + + /** + * 上次调度时间 + */ + private Long triggerLastTime; + + /** + * 下次次调度时间 + */ + private Long triggerNextTime; + + /** + * 调度类型,NONE,CRON,FIX_RATE,FIX_DELAY + */ + private String schedulerType; + + /** + * 调度配置,取决于调度类型 + */ + private String schedulerConf; + + /** + * 开始时间 + */ + private Long startTime; + + /** + * 结束时间 + */ + private Long stopTime; + + private Source source; + private Target target; + + /** + * 上次执行结果,获取任务最新的日志状态 + * running执行中 + * success + * fail失败 + */ + private String lastExecuteStatus; + private Long incrementValue; + + // 以下为日志信息 + private String logId; + private Long executorStartTime; + private Long executorEndTime; + private String executorMsg; + /** + * 成功SUCCESS,失败FAIL,执行中RUNNING + */ + private String logStatus; + + /** + * 在执行周期内 + */ + private boolean withinCycle; + +} diff --git a/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/vo/TaskLogVO.java b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/vo/TaskLogVO.java new file mode 100644 index 0000000000..44289bc91a --- /dev/null +++ b/sdk/api/api-sync/src/main/java/io/dataease/api/sync/task/vo/TaskLogVO.java @@ -0,0 +1,25 @@ +package io.dataease.api.sync.task.vo; + +import lombok.Data; + +/** + * 任务日志 + * @author fit2cloud + * @date 2023/9/19 17:44 + **/ +@Data +public class TaskLogVO { + + private String id; + private String jobId; + private String jobName; + private String jobDesc; + private Long executorStartTime; + private Long executorEndTime; + private String status; + private String executorMsg; + private String executorAddress; + + private String clearType; + +} diff --git a/sdk/api/pom.xml b/sdk/api/pom.xml index 58186de6bd..d9f8c90c22 100644 --- a/sdk/api/pom.xml +++ b/sdk/api/pom.xml @@ -15,6 +15,7 @@ api-permissions api-base + api-sync 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 093f3835ad..60270644d1 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); + 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(10, 8), TASK(11, 9),TASK_LOG(12, 10), SUMMARY(13, 11); private long menuId;