diff --git a/dinky-admin/src/main/java/org/dinky/context/ConsoleContextHolder.java b/dinky-admin/src/main/java/org/dinky/context/ConsoleContextHolder.java index cc95550928..b38aae76ca 100644 --- a/dinky-admin/src/main/java/org/dinky/context/ConsoleContextHolder.java +++ b/dinky-admin/src/main/java/org/dinky/context/ConsoleContextHolder.java @@ -88,6 +88,15 @@ public ProcessEntity getProcess(String processName) { } } + public boolean clearProcessLog(String processName) { + // find process and delete + String filePath = String.format("%s/tmp/log/%s.json", System.getProperty("user.dir"), processName); + if (FileUtil.exist(filePath)) { + return FileUtil.del(filePath); + } + return false; + } + /** * Add log messages to specific processes and process steps. * diff --git a/dinky-admin/src/main/java/org/dinky/controller/ProcessController.java b/dinky-admin/src/main/java/org/dinky/controller/ProcessController.java index b5c6d06081..455db993d7 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/ProcessController.java +++ b/dinky-admin/src/main/java/org/dinky/controller/ProcessController.java @@ -20,10 +20,12 @@ package org.dinky.controller; import org.dinky.context.ConsoleContextHolder; +import org.dinky.data.enums.Status; import org.dinky.data.model.ProcessEntity; import org.dinky.data.result.ProTableResult; import org.dinky.data.result.Result; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -67,7 +69,18 @@ public ProTableResult listAllProcess(@RequestParam boolean active @GetMapping("/getProcess") @ApiOperation("get process") @ApiImplicitParam(name = "processName", value = "process name", dataType = "ProcessEntity") - public Result listAllProcess(@RequestParam String processName) { + public Result getProcessByProcessName(@RequestParam String processName) { return Result.succeed(ConsoleContextHolder.getInstances().getProcess(processName)); } + + @DeleteMapping("/clearProcessLog") + @ApiOperation("Clear Process") + @ApiImplicitParam(name = "processName", value = "process name", dataType = "ProcessEntity") + public Result clearProcessLog(@RequestParam String processName) { + boolean clearProcessLog = ConsoleContextHolder.getInstances().clearProcessLog(processName); + if (!clearProcessLog) { + return Result.failed(Status.PROCESS_CLEAR_LOG_FAILED); + } + return Result.succeed(Status.PROCESS_CLEAR_LOG_SUCCESS); + } } diff --git a/dinky-common/src/main/java/org/dinky/data/enums/Status.java b/dinky-common/src/main/java/org/dinky/data/enums/Status.java index 8616a5c292..36c56b192d 100644 --- a/dinky-common/src/main/java/org/dinky/data/enums/Status.java +++ b/dinky-common/src/main/java/org/dinky/data/enums/Status.java @@ -441,6 +441,8 @@ public enum Status { PROCESS_SUBMIT_EXECUTECOMMSQL(194, "process.submit.execute.commSql"), PROCESS_SUBMIT_EXECUTEFLINKSQL(195, "process.submit.execute.flinkSql"), PROCESS_REGISTER_EXITS(196, "process.register.exits"), + PROCESS_CLEAR_LOG_SUCCESS(198, "process.clear.log.success"), + PROCESS_CLEAR_LOG_FAILED(199, "process.clear.log.failed"), ; private final int code; private final String key; diff --git a/dinky-common/src/main/resources/i18n/messages_en_US.properties b/dinky-common/src/main/resources/i18n/messages_en_US.properties index b4aa96a520..1c1a5fc192 100644 --- a/dinky-common/src/main/resources/i18n/messages_en_US.properties +++ b/dinky-common/src/main/resources/i18n/messages_en_US.properties @@ -288,6 +288,8 @@ process.submit.buildConfig=Build configuration information process.submit.execute.commSql=excute commonSql process.submit.execute.flinkSql=excute flinkSql process.register.exits=The current task is executing, do not submit it repeatedly, if you have any questions, please go to the configuration center to view +process.clear.log.success=Clear process log successfully +process.clear.log.failed=Clear process log failed # resource resource.root.dir.not.allow.delete=The root directory is not allowed to be deleted resource.dir.or.file.not.exist=The directory or file does not exist diff --git a/dinky-common/src/main/resources/i18n/messages_zh_CN.properties b/dinky-common/src/main/resources/i18n/messages_zh_CN.properties index 625d284ed9..9a1ef5a1f5 100644 --- a/dinky-common/src/main/resources/i18n/messages_zh_CN.properties +++ b/dinky-common/src/main/resources/i18n/messages_zh_CN.properties @@ -288,6 +288,8 @@ process.submit.buildConfig=构建配置信息 process.submit.execute.commSql=执行普通sql process.submit.execute.flinkSql=执行FlinkSql process.register.exits=当前任务正在执行,请勿重复提交,如有问题请前往配置中心查看 +process.clear.log.success=清除日志成功 +process.clear.log.failed=清除日志失败 # resource resource.root.dir.not.allow.delete=根目录不允许删除 diff --git a/dinky-web/src/components/CustomEditor/CodeShow/index.tsx b/dinky-web/src/components/CustomEditor/CodeShow/index.tsx index 89fd5d919b..4b3357332c 100644 --- a/dinky-web/src/components/CustomEditor/CodeShow/index.tsx +++ b/dinky-web/src/components/CustomEditor/CodeShow/index.tsx @@ -48,6 +48,7 @@ export type CodeShowFormProps = { fullScreenBtn?: boolean; enableAutoScroll?: boolean; style?: CSSProperties; + clearContent?: () => void; }; const CodeShow = (props: CodeShowFormProps) => { @@ -76,7 +77,8 @@ const CodeShow = (props: CodeShowFormProps) => { refreshLogCallback, fullScreenBtn = false, enableMiniMap = false, - enableAutoScroll = false + enableAutoScroll = false, + clearContent } = props; const { ScrollType } = editor; @@ -205,7 +207,8 @@ const CodeShow = (props: CodeShowFormProps) => { handleUpScroll, handleDownScroll, handleDownloadLog, - handleWrap + handleWrap, + clearContent }; /** diff --git a/dinky-web/src/components/CustomEditor/EditorFloatBtn/index.tsx b/dinky-web/src/components/CustomEditor/EditorFloatBtn/index.tsx index 5c84230c8b..9896e0bb8f 100644 --- a/dinky-web/src/components/CustomEditor/EditorFloatBtn/index.tsx +++ b/dinky-web/src/components/CustomEditor/EditorFloatBtn/index.tsx @@ -20,6 +20,7 @@ import { CircleBtn } from '@/components/CallBackButton/CircleBtn'; import { l } from '@/utils/intl'; import { + ClearOutlined, CloudDownloadOutlined, DownCircleFilled, EnterOutlined, @@ -50,6 +51,7 @@ type EditFloatBtnProps = { handleDownScroll?: () => void; // down scroll callback handleDownloadLog?: () => string; // download log callback handleWrap?: () => void; // wrap callback + clearContent?: () => void; // clear content callback }; const EditorFloatBtn: React.FC = (props) => { /** @@ -68,7 +70,8 @@ const EditorFloatBtn: React.FC = (props) => { handleUpScroll, handleDownScroll, handleDownloadLog, - handleWrap + handleWrap, + clearContent } = props; /** @@ -99,6 +102,13 @@ const EditorFloatBtn: React.FC = (props) => { )} )} + {clearContent && ( + } + onClick={clearContent} + title={l('button.clear')} + /> + )} } onClick={handleBackTop} diff --git a/dinky-web/src/locales/en-US/pages.ts b/dinky-web/src/locales/en-US/pages.ts index 0a30cd86a0..0971de6e77 100644 --- a/dinky-web/src/locales/en-US/pages.ts +++ b/dinky-web/src/locales/en-US/pages.ts @@ -860,6 +860,7 @@ export default { 'rc.ds.search': 'Search Name/Note', 'rc.ds.console.exec': 'Execute', 'rc.ds.console.running': 'Running...', + 'rc.ds.detail.tag.console.clear.log': 'Clear Log...', 'rc.ds.create': 'Create DataSource', 'rc.ds.decimalDigits': 'Decimal Range', 'rc.ds.default': 'Default Value', diff --git a/dinky-web/src/locales/zh-CN/pages.ts b/dinky-web/src/locales/zh-CN/pages.ts index 3200eaa19b..52f1c2d712 100644 --- a/dinky-web/src/locales/zh-CN/pages.ts +++ b/dinky-web/src/locales/zh-CN/pages.ts @@ -831,6 +831,7 @@ export default { 'rc.ds.delete': '删除数据源', 'rc.ds.deleteConfirm': '确定删除该数据源吗?', 'rc.ds.detail.tag.console': '控制台', + 'rc.ds.detail.tag.console.clear.log': '清除日志...', 'rc.ds.detail.tag.desc': '描述', 'rc.ds.detail.tag.gensql': '生成 SQL', 'rc.ds.detail.tag.query': '查询', diff --git a/dinky-web/src/pages/DataStudio/BottomContainer/Console/ConsoleContent.tsx b/dinky-web/src/pages/DataStudio/BottomContainer/Console/ConsoleContent.tsx index 24096a1a43..b690465bd7 100644 --- a/dinky-web/src/pages/DataStudio/BottomContainer/Console/ConsoleContent.tsx +++ b/dinky-web/src/pages/DataStudio/BottomContainer/Console/ConsoleContent.tsx @@ -21,9 +21,11 @@ import CodeShow from '@/components/CustomEditor/CodeShow'; import { SseData } from '@/models/Sse'; import { DataStudioTabsItemType, StateType, VIEW } from '@/pages/DataStudio/model'; import { SSE_TOPIC } from '@/pages/DevOps/constants'; +import { handleDeleteOperation } from '@/services/BusinessCrud'; import { API_CONSTANTS } from '@/services/endpoints'; import { JobStatus } from '@/types/Studio/data.d'; import { parseMilliSecondStr } from '@/utils/function'; +import { l } from '@/utils/intl'; import { SplitPane } from '@andrewray/react-multi-split-pane'; import { Pane } from '@andrewray/react-multi-split-pane/dist/lib/Pane'; import { CheckOutlined, CloseCircleFilled, LoadingOutlined } from '@ant-design/icons'; @@ -79,16 +81,16 @@ const ConsoleContent = (props: ConsoleProps) => { const onUpdate = (data: ProcessStep) => { setProcessNode((prevState: any) => { //如果key不一致代表重新提交了任务,清空旧状态 - if (prevState && prevState.key != data.key) { + if (prevState && prevState?.key != data?.key) { setSelectNode(undefined); } return data; }); setSelectNode((prevState: any) => { - if (prevState && data?.lastUpdateStep && prevState.key === data.lastUpdateStep.key) { + if (prevState && data?.lastUpdateStep && prevState?.key === data?.lastUpdateStep?.key) { //更新当前节点 - return data.lastUpdateStep; - } else if (!prevState || prevState.key === data.key) { + return data?.lastUpdateStep; + } else if (!prevState || prevState?.key === data?.key) { //未选择节点状态下选择根节点 return data; } @@ -96,11 +98,11 @@ const ConsoleContent = (props: ConsoleProps) => { }); }; - useRequest( + const { run } = useRequest( { url: API_CONSTANTS.PROCESS_LOG, params: { processName: process } }, { onSuccess: async (res) => onUpdate(res) } ); - useEffect(() => subscribeTopic([topic], (data: SseData) => onUpdate(data.data)), []); + useEffect(() => subscribeTopic([topic], (data: SseData) => onUpdate(data?.data)), []); const onSelect = ( _selectedKeys: Key[], info: { @@ -185,6 +187,14 @@ const ConsoleContent = (props: ConsoleProps) => { enableMiniMap enableAutoScroll showFloatButton + clearContent={async () => { + const boolean = await handleDeleteOperation( + API_CONSTANTS.PROCESS_LOG_CLEAR, + { processName: process }, + l('rc.ds.detail.tag.console.clear.log') + ); + if (boolean) run(); + }} /> diff --git a/dinky-web/src/services/BusinessCrud.ts b/dinky-web/src/services/BusinessCrud.ts index 0c7873773b..c2c3002230 100644 --- a/dinky-web/src/services/BusinessCrud.ts +++ b/dinky-web/src/services/BusinessCrud.ts @@ -26,6 +26,7 @@ import { putData, putDataJson, removeById, + removeData, updateDataByParams } from '@/services/api'; import { METHOD_CONSTANTS, RESPONSE_CODE } from '@/services/constants'; @@ -130,6 +131,35 @@ export const handleRemoveById = async (url: string, id: number, afterCallBack?: } }; +/** + * delete by params + * @param url + * @param params + * @param title + * @param afterCallBack + */ +export const handleDeleteOperation = async ( + url: string, + params: any, + title: string, + afterCallBack?: () => void +) => { + await LoadingMessageAsync(l('app.request.running') + title); + try { + const { code, msg } = await removeData(url, { ...params }); + if (code === RESPONSE_CODE.SUCCESS) { + await SuccessMessage(msg); + afterCallBack?.(); + return true; + } else { + await WarningMessage(msg); + } + return true; + } catch (error) { + return false; + } +}; + /** * update enabled status * @param url diff --git a/dinky-web/src/services/api.ts b/dinky-web/src/services/api.ts index 41127bf416..fb6e38aee9 100644 --- a/dinky-web/src/services/api.ts +++ b/dinky-web/src/services/api.ts @@ -78,7 +78,7 @@ export async function getData(url: string, params?: any) { export async function removeData(url: string, params: [any]) { return request(url, { method: METHOD_CONSTANTS.DELETE, - data: { + params: { ...params } }); diff --git a/dinky-web/src/services/endpoints.tsx b/dinky-web/src/services/endpoints.tsx index b597be5dfe..6da038dcd8 100644 --- a/dinky-web/src/services/endpoints.tsx +++ b/dinky-web/src/services/endpoints.tsx @@ -186,6 +186,7 @@ export enum API_CONSTANTS { // ------------------------------------ system process ------------------------------------ PROCESS_LIST = '/api/process/listAllProcess', PROCESS_LOG = '/api/process/getProcess', + PROCESS_LOG_CLEAR = '/api/process/clearProcessLog', /** ------------------------------------------------ Devops center ------------------------------------ */ // ------------------------------------ devops job ------------------------------------