diff --git a/dolphinscheduler-ui-next/src/layouts/content/use-dataList.ts b/dolphinscheduler-ui-next/src/layouts/content/use-dataList.ts index cd3b9e2d68..408e18c558 100644 --- a/dolphinscheduler-ui-next/src/layouts/content/use-dataList.ts +++ b/dolphinscheduler-ui-next/src/layouts/content/use-dataList.ts @@ -208,6 +208,10 @@ export function useDataList() { { label: t('menu.statistics'), key: `/monitor/statistics` + }, + { + label: t('menu.audit_log'), + key: `/monitor/audit-log` } ] } diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts index 80b64f8819..bf05f32133 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts @@ -65,6 +65,7 @@ const menu = { db: 'DB', statistical_manage: 'Statistical Manage', statistics: 'Statistics', + audit_log: 'Audit Log', tenant_manage: 'Tenant Manage', user_manage: 'User Manage', alarm_group_manage: 'Alarm Group Manage', @@ -149,6 +150,21 @@ const monitor = { failure_command_number: 'Failure Command Number', tasks_number_of_waiting_running: 'Tasks Number Of Waiting Running', task_number_of_ready_to_kill: 'Task Number Of Ready To Kill' + }, + audit_log: { + user_name: 'User Name', + resource_type: 'Resource Type', + project_name: 'Project Name', + operation_type: 'Operation Type', + create_time: 'Create Time', + start_time: 'Start Time', + end_time: 'End Time', + user_audit: 'User Audit', + project_audit: 'Project Audit', + create: 'Create', + update: 'Update', + delete: 'Delete', + read: 'Read' } } diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts index 31fd7cd06c..379aa85457 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts @@ -65,6 +65,7 @@ const menu = { db: 'DB', statistical_manage: '统计管理', statistics: 'Statistics', + audit_log: '审计日志', tenant_manage: '租户管理', user_manage: '用户管理', alarm_group_manage: '告警组管理', @@ -150,6 +151,21 @@ const monitor = { failure_command_number: '执行失败的命令数', tasks_number_of_waiting_running: '待运行任务数', task_number_of_ready_to_kill: '待杀死任务数' + }, + audit_log: { + user_name: '用户名称', + resource_type: '资源类型', + project_name: '项目名称', + operation_type: '操作类型', + create_time: '创建时间', + start_time: '开始时间', + end_time: '结束时间', + user_audit: '用户管理审计', + project_audit: '项目管理审计', + create: '创建', + update: '更新', + delete: '删除', + read: '读取' } } diff --git a/dolphinscheduler-ui-next/src/router/modules/monitor.ts b/dolphinscheduler-ui-next/src/router/modules/monitor.ts index 68074bf66f..3d54f10c47 100644 --- a/dolphinscheduler-ui-next/src/router/modules/monitor.ts +++ b/dolphinscheduler-ui-next/src/router/modules/monitor.ts @@ -64,6 +64,15 @@ export default { title: '统计管理-Statistics', showSide: true } + }, + { + path: '/monitor/audit-log', + name: 'statistics-audit-log', + component: components['monitor-statistics-audit-log'], + meta: { + title: '审计日志-AuditLog', + showSide: true + } } ] } diff --git a/dolphinscheduler-ui-next/src/service/modules/audit/index.ts b/dolphinscheduler-ui-next/src/service/modules/audit/index.ts new file mode 100644 index 0000000000..fd436ccbb2 --- /dev/null +++ b/dolphinscheduler-ui-next/src/service/modules/audit/index.ts @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { axios } from '@/service/service' +import type { AuditListReq } from './types' + +export function queryAuditLogListPaging(params: AuditListReq): any { + return axios({ + url: '/projects/audit/audit-log-list', + method: 'get', + params + }) +} diff --git a/dolphinscheduler-ui-next/src/service/modules/audit/types.ts b/dolphinscheduler-ui-next/src/service/modules/audit/types.ts new file mode 100644 index 0000000000..030cfc8037 --- /dev/null +++ b/dolphinscheduler-ui-next/src/service/modules/audit/types.ts @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface AuditListReq { + pageNo: number + pageSize: number + endDate?: string + moduleType?: string + operationType?: string + processName?: string + projectName?: string + resourceType?: string + startDate?: string + userName?: string +} + +interface AuditItem { + userName: string + resource: string + operation: string + time: string + resourceName: string +} + +interface AuditListRes { + totalList: AuditItem[] + total: number + totalPage: number + pageSize: number + currentPage: number + start: number +} + +export { AuditListReq, AuditListRes } diff --git a/dolphinscheduler-ui-next/src/views/monitor/statistics/audit-log/index.module.scss b/dolphinscheduler-ui-next/src/views/monitor/statistics/audit-log/index.module.scss new file mode 100644 index 0000000000..e6b0dfe014 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/monitor/statistics/audit-log/index.module.scss @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.table-card { + margin-top: 8px; + + .pagination { + margin-top: 20px; + display: flex; + justify-content: center; + } +} diff --git a/dolphinscheduler-ui-next/src/views/monitor/statistics/audit-log/index.tsx b/dolphinscheduler-ui-next/src/views/monitor/statistics/audit-log/index.tsx new file mode 100644 index 0000000000..b5d64ab077 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/monitor/statistics/audit-log/index.tsx @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineComponent, onMounted, toRefs, watch } from 'vue' +import { + NSpace, + NInput, + NSelect, + NDatePicker, + NButton, + NIcon, + NDataTable, + NPagination, + NCard +} from 'naive-ui' +import { SearchOutlined } from '@vicons/antd' +import { useTable } from './use-table' +import { useI18n } from 'vue-i18n' +import Card from '@/components/card' +import styles from './index.module.scss' + +const AuditLog = defineComponent({ + name: 'audit-log', + setup() { + const { t, variables, getTableData, createColumns } = useTable() + + const requestTableData = () => { + getTableData({ + pageSize: variables.pageSize, + pageNo: variables.page, + resourceType: variables.resourceType, + operationType: variables.operationType, + userName: variables.userName, + datePickerRange: variables.datePickerRange + }) + } + + const onUpdatePageSize = () => { + variables.page = 1 + requestTableData() + } + + const onSearch = () => { + variables.page = 1 + requestTableData() + } + + onMounted(() => { + createColumns(variables) + requestTableData() + }) + + watch(useI18n().locale, () => { + createColumns(variables) + }) + + return { + t, + ...toRefs(variables), + requestTableData, + onUpdatePageSize, + onSearch + } + }, + render() { + const { t, requestTableData, onUpdatePageSize, onSearch } = this + + return ( + <> + + + + + + + + {{ + icon: () => ( + + + + ) + }} + + + + + +
+ +
+
+ + ) + } +}) + +export default AuditLog diff --git a/dolphinscheduler-ui-next/src/views/monitor/statistics/audit-log/use-table.ts b/dolphinscheduler-ui-next/src/views/monitor/statistics/audit-log/use-table.ts new file mode 100644 index 0000000000..bff2c3f6c8 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/monitor/statistics/audit-log/use-table.ts @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useI18n } from 'vue-i18n' +import { reactive, ref } from 'vue' +import { useAsyncState } from '@vueuse/core' +import { queryAuditLogListPaging } from '@/service/modules/audit' +import { format } from 'date-fns' +import type { AuditListRes } from '@/service/modules/audit/types' + +export function useTable() { + const { t } = useI18n() + + const variables = reactive({ + columns: [], + tableData: [], + page: ref(1), + pageSize: ref(10), + resourceType: ref(null), + operationType: ref(null), + userName: ref(null), + datePickerRange: ref(null), + totalPage: ref(1) + }) + + const createColumns = (variables: any) => { + variables.columns = [ + { + title: '#', + key: 'index' + }, + { + title: t('monitor.audit_log.user_name'), + key: 'userName' + }, + { + title: t('monitor.audit_log.resource_type'), + key: 'resource' + }, + { + title: t('monitor.audit_log.project_name'), + key: 'resourceName' + }, + { + title: t('monitor.audit_log.operation_type'), + key: 'operation' + }, + { + title: t('monitor.audit_log.create_time'), + key: 'time' + } + ] + } + + const getTableData = (params: any) => { + const data = { + pageSize: params.pageSize, + pageNo: params.pageNo, + resourceType: params.resourceType, + operationType: params.operationType, + userName: params.userName, + startDate: params.datePickerRange + ? format(new Date(params.datePickerRange[0]), 'yyyy-MM-dd HH:mm:ss') + : '', + endDate: params.datePickerRange + ? format(new Date(params.datePickerRange[1]), 'yyyy-MM-dd HH:mm:ss') + : '' + } + + const { state } = useAsyncState( + queryAuditLogListPaging(data).then((res: AuditListRes) => { + variables.tableData = res.totalList.map((item, index) => { + return { + index: index + 1, + ...item + } + }) as any + }), + {} + ) + + return state + } + + return { + t, + variables, + getTableData, + createColumns + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/workflow/relation/index.tsx b/dolphinscheduler-ui-next/src/views/projects/workflow/relation/index.tsx index 1f63770af3..fc409e468c 100644 --- a/dolphinscheduler-ui-next/src/views/projects/workflow/relation/index.tsx +++ b/dolphinscheduler-ui-next/src/views/projects/workflow/relation/index.tsx @@ -25,98 +25,98 @@ import Card from '@/components/card' import Graph from './components/Graph' const workflowRelation = defineComponent({ - name: 'workflow-relation', - setup() { - const { t, locale } = useI18n() - const route = useRoute() - const { variables, getWorkflowName, getOneWorkflow, getWorkflowList } = - useRelation() + name: 'workflow-relation', + setup() { + const { t, locale } = useI18n() + const route = useRoute() + const { variables, getWorkflowName, getOneWorkflow, getWorkflowList } = + useRelation() - onMounted(() => { - getWorkflowList(Number(route.params.projectCode)) - getWorkflowName(Number(route.params.projectCode)) - }) + onMounted(() => { + getWorkflowList(Number(route.params.projectCode)) + getWorkflowName(Number(route.params.projectCode)) + }) - const handleResetDate = () => { - variables.seriesData = [] - variables.workflow && variables.workflow !== 0 - ? getOneWorkflow( - Number(variables.workflow), - Number(route.params.projectCode) - ) - : getWorkflowList(Number(route.params.projectCode)) - } + const handleResetDate = () => { + variables.seriesData = [] + variables.workflow && variables.workflow !== 0 + ? getOneWorkflow( + Number(variables.workflow), + Number(route.params.projectCode) + ) + : getWorkflowList(Number(route.params.projectCode)) + } - watch( - () => [variables.workflow, variables.labelShow, locale.value], - () => { - handleResetDate() - } - ) + watch( + () => [variables.workflow, variables.labelShow, locale.value], + () => { + handleResetDate() + } + ) - return { t, handleResetDate, ...toRefs(variables) } - }, - render() { - const { t, handleResetDate } = this + return { t, handleResetDate, ...toRefs(variables) } + }, + render() { + const { t, handleResetDate } = this - return ( - - {{ - default: () => - Object.keys(this.seriesData).length > 0 && ( - - ), - 'header-extra': () => ( - - - - {{ - default: () => t('project.workflow.refresh'), - trigger: () => ( - - - - - - ) - }} - - - {{ - default: () => t('project.workflow.show_hide_label'), - trigger: () => ( - (this.labelShow = !this.labelShow)} - > - - - - - ) - }} - - - ) - }} - - ) - } + return ( + + {{ + default: () => + Object.keys(this.seriesData).length > 0 && ( + + ), + 'header-extra': () => ( + + + + {{ + default: () => t('project.workflow.refresh'), + trigger: () => ( + + + + + + ) + }} + + + {{ + default: () => t('project.workflow.show_hide_label'), + trigger: () => ( + (this.labelShow = !this.labelShow)} + > + + + + + ) + }} + + + ) + }} + + ) + } }) export default workflowRelation