mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 00:10:25 +08:00 
			
		
		
		
	refactor: 数据同步编辑页调整、echarts组件重构
This commit is contained in:
		@@ -17,7 +17,7 @@
 | 
			
		||||
    "countup.js": "^2.7.0",
 | 
			
		||||
    "cropperjs": "^1.5.11",
 | 
			
		||||
    "echarts": "^5.4.3",
 | 
			
		||||
    "element-plus": "^2.4.4",
 | 
			
		||||
    "element-plus": "^2.5.0",
 | 
			
		||||
    "js-base64": "^3.7.5",
 | 
			
		||||
    "jsencrypt": "^3.3.2",
 | 
			
		||||
    "lodash": "^4.17.21",
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
    "splitpanes": "^3.1.5",
 | 
			
		||||
    "sql-formatter": "^14.0.0",
 | 
			
		||||
    "uuid": "^9.0.1",
 | 
			
		||||
    "vue": "^3.4.6",
 | 
			
		||||
    "vue": "^3.4.7",
 | 
			
		||||
    "vue-router": "^4.2.5",
 | 
			
		||||
    "xterm": "^5.3.0",
 | 
			
		||||
    "xterm-addon-fit": "^0.8.0",
 | 
			
		||||
@@ -48,7 +48,7 @@
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^6.7.4",
 | 
			
		||||
    "@typescript-eslint/parser": "^6.7.4",
 | 
			
		||||
    "@vitejs/plugin-vue": "^5.0.2",
 | 
			
		||||
    "@vue/compiler-sfc": "^3.4.6",
 | 
			
		||||
    "@vue/compiler-sfc": "^3.4.7",
 | 
			
		||||
    "dotenv": "^16.3.1",
 | 
			
		||||
    "eslint": "^8.35.0",
 | 
			
		||||
    "eslint-plugin-vue": "^9.19.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,176 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
    "seriesCnt": "4",
 | 
			
		||||
    "backgroundColor": "rgba(0,0,0,0)",
 | 
			
		||||
    "titleColor": "#008acd",
 | 
			
		||||
    "subtitleColor": "#aaaaaa",
 | 
			
		||||
    "textColorShow": false,
 | 
			
		||||
    "textColor": "#333",
 | 
			
		||||
    "markTextColor": "#eeeeee",
 | 
			
		||||
    "color": [
 | 
			
		||||
        "#2ec7c9",
 | 
			
		||||
        "#b6a2de",
 | 
			
		||||
        "#5ab1ef",
 | 
			
		||||
        "#ffb980",
 | 
			
		||||
        "#d87a80",
 | 
			
		||||
        "#8d98b3",
 | 
			
		||||
        "#e5cf0d",
 | 
			
		||||
        "#97b552",
 | 
			
		||||
        "#95706d",
 | 
			
		||||
        "#dc69aa",
 | 
			
		||||
        "#07a2a4",
 | 
			
		||||
        "#9a7fd1",
 | 
			
		||||
        "#588dd5",
 | 
			
		||||
        "#f5994e",
 | 
			
		||||
        "#c05050",
 | 
			
		||||
        "#59678c",
 | 
			
		||||
        "#c9ab00",
 | 
			
		||||
        "#7eb00a",
 | 
			
		||||
        "#6f5553",
 | 
			
		||||
        "#c14089"
 | 
			
		||||
    ],
 | 
			
		||||
    "borderColor": "#ccc",
 | 
			
		||||
    "borderWidth": 0,
 | 
			
		||||
    "visualMapColor": [
 | 
			
		||||
        "#5ab1ef",
 | 
			
		||||
        "#e0ffff"
 | 
			
		||||
    ],
 | 
			
		||||
    "legendTextColor": "#333333",
 | 
			
		||||
    "kColor": "#d87a80",
 | 
			
		||||
    "kColor0": "#2ec7c9",
 | 
			
		||||
    "kBorderColor": "#d87a80",
 | 
			
		||||
    "kBorderColor0": "#2ec7c9",
 | 
			
		||||
    "kBorderWidth": 1,
 | 
			
		||||
    "lineWidth": 2,
 | 
			
		||||
    "symbolSize": 3,
 | 
			
		||||
    "symbol": "emptyCircle",
 | 
			
		||||
    "symbolBorderWidth": 1,
 | 
			
		||||
    "lineSmooth": true,
 | 
			
		||||
    "graphLineWidth": 1,
 | 
			
		||||
    "graphLineColor": "#aaaaaa",
 | 
			
		||||
    "mapLabelColor": "#d87a80",
 | 
			
		||||
    "mapLabelColorE": "rgb(100,0,0)",
 | 
			
		||||
    "mapBorderColor": "#eeeeee",
 | 
			
		||||
    "mapBorderColorE": "#444",
 | 
			
		||||
    "mapBorderWidth": 0.5,
 | 
			
		||||
    "mapBorderWidthE": 1,
 | 
			
		||||
    "mapAreaColor": "#dddddd",
 | 
			
		||||
    "mapAreaColorE": "rgba(254,153,78,1)",
 | 
			
		||||
    "axes": [
 | 
			
		||||
        {
 | 
			
		||||
            "type": "all",
 | 
			
		||||
            "name": "通用坐标轴",
 | 
			
		||||
            "axisLineShow": true,
 | 
			
		||||
            "axisLineColor": "#eeeeee",
 | 
			
		||||
            "axisTickShow": true,
 | 
			
		||||
            "axisTickColor": "#eeeeee",
 | 
			
		||||
            "axisLabelShow": true,
 | 
			
		||||
            "axisLabelColor": "#eeeeee",
 | 
			
		||||
            "splitLineShow": true,
 | 
			
		||||
            "splitLineColor": [
 | 
			
		||||
                "#aaaaaa"
 | 
			
		||||
            ],
 | 
			
		||||
            "splitAreaShow": false,
 | 
			
		||||
            "splitAreaColor": [
 | 
			
		||||
                "#eeeeee"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "type": "category",
 | 
			
		||||
            "name": "类目坐标轴",
 | 
			
		||||
            "axisLineShow": true,
 | 
			
		||||
            "axisLineColor": "#008acd",
 | 
			
		||||
            "axisTickShow": true,
 | 
			
		||||
            "axisTickColor": "#333",
 | 
			
		||||
            "axisLabelShow": true,
 | 
			
		||||
            "axisLabelColor": "#333",
 | 
			
		||||
            "splitLineShow": false,
 | 
			
		||||
            "splitLineColor": [
 | 
			
		||||
                "#eee"
 | 
			
		||||
            ],
 | 
			
		||||
            "splitAreaShow": false,
 | 
			
		||||
            "splitAreaColor": [
 | 
			
		||||
                "rgba(250,250,250,0.3)",
 | 
			
		||||
                "rgba(200,200,200,0.3)"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "type": "value",
 | 
			
		||||
            "name": "数值坐标轴",
 | 
			
		||||
            "axisLineShow": true,
 | 
			
		||||
            "axisLineColor": "#008acd",
 | 
			
		||||
            "axisTickShow": true,
 | 
			
		||||
            "axisTickColor": "#333",
 | 
			
		||||
            "axisLabelShow": true,
 | 
			
		||||
            "axisLabelColor": "#333",
 | 
			
		||||
            "splitLineShow": true,
 | 
			
		||||
            "splitLineColor": [
 | 
			
		||||
                "#eee"
 | 
			
		||||
            ],
 | 
			
		||||
            "splitAreaShow": true,
 | 
			
		||||
            "splitAreaColor": [
 | 
			
		||||
                "rgba(250,250,250,0.3)",
 | 
			
		||||
                "rgba(200,200,200,0.3)"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "type": "log",
 | 
			
		||||
            "name": "对数坐标轴",
 | 
			
		||||
            "axisLineShow": true,
 | 
			
		||||
            "axisLineColor": "#008acd",
 | 
			
		||||
            "axisTickShow": true,
 | 
			
		||||
            "axisTickColor": "#333",
 | 
			
		||||
            "axisLabelShow": true,
 | 
			
		||||
            "axisLabelColor": "#333",
 | 
			
		||||
            "splitLineShow": true,
 | 
			
		||||
            "splitLineColor": [
 | 
			
		||||
                "#eee"
 | 
			
		||||
            ],
 | 
			
		||||
            "splitAreaShow": true,
 | 
			
		||||
            "splitAreaColor": [
 | 
			
		||||
                "rgba(250,250,250,0.3)",
 | 
			
		||||
                "rgba(200,200,200,0.3)"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "type": "time",
 | 
			
		||||
            "name": "时间坐标轴",
 | 
			
		||||
            "axisLineShow": true,
 | 
			
		||||
            "axisLineColor": "#008acd",
 | 
			
		||||
            "axisTickShow": true,
 | 
			
		||||
            "axisTickColor": "#333",
 | 
			
		||||
            "axisLabelShow": true,
 | 
			
		||||
            "axisLabelColor": "#333",
 | 
			
		||||
            "splitLineShow": true,
 | 
			
		||||
            "splitLineColor": [
 | 
			
		||||
                "#eee"
 | 
			
		||||
            ],
 | 
			
		||||
            "splitAreaShow": false,
 | 
			
		||||
            "splitAreaColor": [
 | 
			
		||||
                "rgba(250,250,250,0.3)",
 | 
			
		||||
                "rgba(200,200,200,0.3)"
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "axisSeperateSetting": true,
 | 
			
		||||
    "toolboxColor": "#2ec7c9",
 | 
			
		||||
    "toolboxEmphasisColor": "#18a4a6",
 | 
			
		||||
    "tooltipAxisColor": "#008acd",
 | 
			
		||||
    "tooltipAxisWidth": "1",
 | 
			
		||||
    "timelineLineColor": "#008acd",
 | 
			
		||||
    "timelineLineWidth": 1,
 | 
			
		||||
    "timelineItemColor": "#008acd",
 | 
			
		||||
    "timelineItemColorE": "#a9334c",
 | 
			
		||||
    "timelineCheckColor": "#2ec7c9",
 | 
			
		||||
    "timelineCheckBorderColor": "#2ec7c9",
 | 
			
		||||
    "timelineItemBorderWidth": 1,
 | 
			
		||||
    "timelineControlColor": "#008acd",
 | 
			
		||||
    "timelineControlBorderColor": "#008acd",
 | 
			
		||||
    "timelineControlBorderWidth": 0.5,
 | 
			
		||||
    "timelineLabelColor": "#008acd",
 | 
			
		||||
    "datazoomBackgroundColor": "rgba(47,69,84,0)",
 | 
			
		||||
    "datazoomDataColor": "#efefff",
 | 
			
		||||
    "datazoomFillColor": "rgba(182,162,222,0.2)",
 | 
			
		||||
    "datazoomHandleColor": "#008acd",
 | 
			
		||||
    "datazoomHandleWidth": "100",
 | 
			
		||||
    "datazoomLabelColor": "#333333"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
// import * as echarts from 'echarts'
 | 
			
		||||
 | 
			
		||||
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
 | 
			
		||||
import * as echarts from 'echarts/core';
 | 
			
		||||
 | 
			
		||||
/** 图表后缀都为 Chart  */
 | 
			
		||||
import { PieChart } from 'echarts/charts';
 | 
			
		||||
 | 
			
		||||
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
 | 
			
		||||
import { TitleComponent, TooltipComponent, GridComponent, DatasetComponent, TransformComponent, LegendComponent } from 'echarts/components';
 | 
			
		||||
 | 
			
		||||
// 标签自动布局,全局过渡动画等特性
 | 
			
		||||
import { LabelLayout, UniversalTransition } from 'echarts/features';
 | 
			
		||||
 | 
			
		||||
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
 | 
			
		||||
import { CanvasRenderer } from 'echarts/renderers';
 | 
			
		||||
 | 
			
		||||
// 注册必须的组件
 | 
			
		||||
echarts.use([
 | 
			
		||||
    TitleComponent,
 | 
			
		||||
    TooltipComponent,
 | 
			
		||||
    GridComponent,
 | 
			
		||||
    DatasetComponent,
 | 
			
		||||
    TransformComponent,
 | 
			
		||||
    LegendComponent,
 | 
			
		||||
    //   BarChart,
 | 
			
		||||
    LabelLayout,
 | 
			
		||||
    UniversalTransition,
 | 
			
		||||
    CanvasRenderer,
 | 
			
		||||
    //   LineChart,
 | 
			
		||||
    PieChart,
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
export default function (dom: any, theme: any = null, option: any) {
 | 
			
		||||
    let chart = echarts.init(dom, theme);
 | 
			
		||||
    chart.setOption(option);
 | 
			
		||||
    return chart;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								mayfly_go_web/src/components/echarts/ECharts.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								mayfly_go_web/src/components/echarts/ECharts.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div id="echarts" ref="chartRef" :style="echartsStyle" />
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts" name="ECharts">
 | 
			
		||||
import { ref, onMounted, onBeforeUnmount, watch, computed, markRaw, nextTick } from 'vue';
 | 
			
		||||
import { EChartsType, ECElementEvent } from 'echarts/core';
 | 
			
		||||
import echarts, { ECOption } from './config';
 | 
			
		||||
import { useDebounceFn, useEventListener } from '@vueuse/core';
 | 
			
		||||
import { light } from './config/theme';
 | 
			
		||||
// import { useThemeConfig } from '@/store/themeConfig';
 | 
			
		||||
// import { storeToRefs } from 'pinia';
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
    option: ECOption;
 | 
			
		||||
    renderer?: 'canvas' | 'svg';
 | 
			
		||||
    resize?: boolean;
 | 
			
		||||
    theme?: Object | string;
 | 
			
		||||
    width?: number | string;
 | 
			
		||||
    height?: number | string;
 | 
			
		||||
    onClick?: (event: ECElementEvent) => any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(defineProps<Props>(), {
 | 
			
		||||
    renderer: 'canvas',
 | 
			
		||||
    theme: light as any,
 | 
			
		||||
    resize: true,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const echartsStyle = computed(() => {
 | 
			
		||||
    return props.width || props.height ? { height: props.height + 'px', width: props.width + 'px' } : { height: '100%', width: '100%' };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const chartRef = ref<HTMLDivElement | HTMLCanvasElement>();
 | 
			
		||||
const chartInstance = ref<EChartsType>();
 | 
			
		||||
 | 
			
		||||
const draw = () => {
 | 
			
		||||
    if (chartInstance.value) {
 | 
			
		||||
        chartInstance.value.setOption(props.option, { notMerge: true });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
watch(props, () => {
 | 
			
		||||
    draw();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const handleClick = (event: ECElementEvent) => props.onClick && props.onClick(event);
 | 
			
		||||
 | 
			
		||||
const init = () => {
 | 
			
		||||
    if (!chartRef.value) return;
 | 
			
		||||
    chartInstance.value = echarts.getInstanceByDom(chartRef.value);
 | 
			
		||||
 | 
			
		||||
    if (!chartInstance.value) {
 | 
			
		||||
        chartInstance.value = markRaw(
 | 
			
		||||
            echarts.init(chartRef.value, props.theme, {
 | 
			
		||||
                renderer: props.renderer,
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
        chartInstance.value.on('click', handleClick);
 | 
			
		||||
        draw();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const resize = () => {
 | 
			
		||||
    if (chartInstance.value && props.resize) {
 | 
			
		||||
        chartInstance.value.resize({ animation: { duration: 300 } });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const debouncedResize = useDebounceFn(resize, 300, { maxWait: 800 });
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
    nextTick(() => init());
 | 
			
		||||
    useEventListener('resize', debouncedResize);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onBeforeUnmount(() => {
 | 
			
		||||
    chartInstance.value?.dispose();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
defineExpose({
 | 
			
		||||
    getInstance: () => chartInstance.value,
 | 
			
		||||
    resize,
 | 
			
		||||
    draw,
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										67
									
								
								mayfly_go_web/src/components/echarts/config/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								mayfly_go_web/src/components/echarts/config/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
import * as echarts from 'echarts/core';
 | 
			
		||||
import { BarChart, LineChart, LinesChart, PieChart, ScatterChart, RadarChart, GaugeChart } from 'echarts/charts';
 | 
			
		||||
import {
 | 
			
		||||
    TitleComponent,
 | 
			
		||||
    TooltipComponent,
 | 
			
		||||
    GridComponent,
 | 
			
		||||
    DatasetComponent,
 | 
			
		||||
    TransformComponent,
 | 
			
		||||
    LegendComponent,
 | 
			
		||||
    PolarComponent,
 | 
			
		||||
    GeoComponent,
 | 
			
		||||
    ToolboxComponent,
 | 
			
		||||
    DataZoomComponent,
 | 
			
		||||
} from 'echarts/components';
 | 
			
		||||
import { LabelLayout, UniversalTransition } from 'echarts/features';
 | 
			
		||||
import { CanvasRenderer } from 'echarts/renderers';
 | 
			
		||||
import type {
 | 
			
		||||
    BarSeriesOption,
 | 
			
		||||
    LineSeriesOption,
 | 
			
		||||
    LinesSeriesOption,
 | 
			
		||||
    PieSeriesOption,
 | 
			
		||||
    ScatterSeriesOption,
 | 
			
		||||
    RadarSeriesOption,
 | 
			
		||||
    GaugeSeriesOption,
 | 
			
		||||
} from 'echarts/charts';
 | 
			
		||||
import type { TitleComponentOption, TooltipComponentOption, GridComponentOption, DatasetComponentOption } from 'echarts/components';
 | 
			
		||||
import type { ComposeOption } from 'echarts/core';
 | 
			
		||||
// import 'echarts-liquidfill';
 | 
			
		||||
 | 
			
		||||
export type ECOption = ComposeOption<
 | 
			
		||||
    | BarSeriesOption
 | 
			
		||||
    | LineSeriesOption
 | 
			
		||||
    | LinesSeriesOption
 | 
			
		||||
    | PieSeriesOption
 | 
			
		||||
    | RadarSeriesOption
 | 
			
		||||
    | GaugeSeriesOption
 | 
			
		||||
    | TitleComponentOption
 | 
			
		||||
    | TooltipComponentOption
 | 
			
		||||
    | GridComponentOption
 | 
			
		||||
    | DatasetComponentOption
 | 
			
		||||
    | ScatterSeriesOption
 | 
			
		||||
>;
 | 
			
		||||
 | 
			
		||||
echarts.use([
 | 
			
		||||
    TitleComponent,
 | 
			
		||||
    TooltipComponent,
 | 
			
		||||
    GridComponent,
 | 
			
		||||
    DatasetComponent,
 | 
			
		||||
    TransformComponent,
 | 
			
		||||
    LegendComponent,
 | 
			
		||||
    PolarComponent,
 | 
			
		||||
    GeoComponent,
 | 
			
		||||
    ToolboxComponent,
 | 
			
		||||
    DataZoomComponent,
 | 
			
		||||
    BarChart,
 | 
			
		||||
    LineChart,
 | 
			
		||||
    LinesChart,
 | 
			
		||||
    PieChart,
 | 
			
		||||
    ScatterChart,
 | 
			
		||||
    RadarChart,
 | 
			
		||||
    GaugeChart,
 | 
			
		||||
    LabelLayout,
 | 
			
		||||
    UniversalTransition,
 | 
			
		||||
    CanvasRenderer,
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
export default echarts;
 | 
			
		||||
							
								
								
									
										151
									
								
								mayfly_go_web/src/components/echarts/config/theme.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								mayfly_go_web/src/components/echarts/config/theme.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
const light = {
 | 
			
		||||
    seriesCnt: '4',
 | 
			
		||||
    backgroundColor: 'rgba(0,0,0,0)',
 | 
			
		||||
    titleColor: '#008acd',
 | 
			
		||||
    subtitleColor: '#aaaaaa',
 | 
			
		||||
    textColorShow: false,
 | 
			
		||||
    textColor: '#333',
 | 
			
		||||
    markTextColor: '#eeeeee',
 | 
			
		||||
    color: [
 | 
			
		||||
        '#2ec7c9',
 | 
			
		||||
        '#b6a2de',
 | 
			
		||||
        '#5ab1ef',
 | 
			
		||||
        '#ffb980',
 | 
			
		||||
        '#d87a80',
 | 
			
		||||
        '#8d98b3',
 | 
			
		||||
        '#e5cf0d',
 | 
			
		||||
        '#97b552',
 | 
			
		||||
        '#95706d',
 | 
			
		||||
        '#dc69aa',
 | 
			
		||||
        '#07a2a4',
 | 
			
		||||
        '#9a7fd1',
 | 
			
		||||
        '#588dd5',
 | 
			
		||||
        '#f5994e',
 | 
			
		||||
        '#c05050',
 | 
			
		||||
        '#59678c',
 | 
			
		||||
        '#c9ab00',
 | 
			
		||||
        '#7eb00a',
 | 
			
		||||
        '#6f5553',
 | 
			
		||||
        '#c14089',
 | 
			
		||||
    ],
 | 
			
		||||
    borderColor: '#ccc',
 | 
			
		||||
    borderWidth: 0,
 | 
			
		||||
    visualMapColor: ['#5ab1ef', '#e0ffff'],
 | 
			
		||||
    legendTextColor: '#333333',
 | 
			
		||||
    kColor: '#d87a80',
 | 
			
		||||
    kColor0: '#2ec7c9',
 | 
			
		||||
    kBorderColor: '#d87a80',
 | 
			
		||||
    kBorderColor0: '#2ec7c9',
 | 
			
		||||
    kBorderWidth: 1,
 | 
			
		||||
    lineWidth: 2,
 | 
			
		||||
    symbolSize: 3,
 | 
			
		||||
    symbol: 'emptyCircle',
 | 
			
		||||
    symbolBorderWidth: 1,
 | 
			
		||||
    lineSmooth: true,
 | 
			
		||||
    graphLineWidth: 1,
 | 
			
		||||
    graphLineColor: '#aaaaaa',
 | 
			
		||||
    mapLabelColor: '#d87a80',
 | 
			
		||||
    mapLabelColorE: 'rgb(100,0,0)',
 | 
			
		||||
    mapBorderColor: '#eeeeee',
 | 
			
		||||
    mapBorderColorE: '#444',
 | 
			
		||||
    mapBorderWidth: 0.5,
 | 
			
		||||
    mapBorderWidthE: 1,
 | 
			
		||||
    mapAreaColor: '#dddddd',
 | 
			
		||||
    mapAreaColorE: 'rgba(254,153,78,1)',
 | 
			
		||||
    axes: [
 | 
			
		||||
        {
 | 
			
		||||
            type: 'all',
 | 
			
		||||
            name: '通用坐标轴',
 | 
			
		||||
            axisLineShow: true,
 | 
			
		||||
            axisLineColor: '#eeeeee',
 | 
			
		||||
            axisTickShow: true,
 | 
			
		||||
            axisTickColor: '#eeeeee',
 | 
			
		||||
            axisLabelShow: true,
 | 
			
		||||
            axisLabelColor: '#eeeeee',
 | 
			
		||||
            splitLineShow: true,
 | 
			
		||||
            splitLineColor: ['#aaaaaa'],
 | 
			
		||||
            splitAreaShow: false,
 | 
			
		||||
            splitAreaColor: ['#eeeeee'],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            type: 'category',
 | 
			
		||||
            name: '类目坐标轴',
 | 
			
		||||
            axisLineShow: true,
 | 
			
		||||
            axisLineColor: '#008acd',
 | 
			
		||||
            axisTickShow: true,
 | 
			
		||||
            axisTickColor: '#333',
 | 
			
		||||
            axisLabelShow: true,
 | 
			
		||||
            axisLabelColor: '#333',
 | 
			
		||||
            splitLineShow: false,
 | 
			
		||||
            splitLineColor: ['#eee'],
 | 
			
		||||
            splitAreaShow: false,
 | 
			
		||||
            splitAreaColor: ['rgba(250,250,250,0.3)', 'rgba(200,200,200,0.3)'],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            type: 'value',
 | 
			
		||||
            name: '数值坐标轴',
 | 
			
		||||
            axisLineShow: true,
 | 
			
		||||
            axisLineColor: '#008acd',
 | 
			
		||||
            axisTickShow: true,
 | 
			
		||||
            axisTickColor: '#333',
 | 
			
		||||
            axisLabelShow: true,
 | 
			
		||||
            axisLabelColor: '#333',
 | 
			
		||||
            splitLineShow: true,
 | 
			
		||||
            splitLineColor: ['#eee'],
 | 
			
		||||
            splitAreaShow: true,
 | 
			
		||||
            splitAreaColor: ['rgba(250,250,250,0.3)', 'rgba(200,200,200,0.3)'],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            type: 'log',
 | 
			
		||||
            name: '对数坐标轴',
 | 
			
		||||
            axisLineShow: true,
 | 
			
		||||
            axisLineColor: '#008acd',
 | 
			
		||||
            axisTickShow: true,
 | 
			
		||||
            axisTickColor: '#333',
 | 
			
		||||
            axisLabelShow: true,
 | 
			
		||||
            axisLabelColor: '#333',
 | 
			
		||||
            splitLineShow: true,
 | 
			
		||||
            splitLineColor: ['#eee'],
 | 
			
		||||
            splitAreaShow: true,
 | 
			
		||||
            splitAreaColor: ['rgba(250,250,250,0.3)', 'rgba(200,200,200,0.3)'],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            type: 'time',
 | 
			
		||||
            name: '时间坐标轴',
 | 
			
		||||
            axisLineShow: true,
 | 
			
		||||
            axisLineColor: '#008acd',
 | 
			
		||||
            axisTickShow: true,
 | 
			
		||||
            axisTickColor: '#333',
 | 
			
		||||
            axisLabelShow: true,
 | 
			
		||||
            axisLabelColor: '#333',
 | 
			
		||||
            splitLineShow: true,
 | 
			
		||||
            splitLineColor: ['#eee'],
 | 
			
		||||
            splitAreaShow: false,
 | 
			
		||||
            splitAreaColor: ['rgba(250,250,250,0.3)', 'rgba(200,200,200,0.3)'],
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    axisSeperateSetting: true,
 | 
			
		||||
    toolboxColor: '#2ec7c9',
 | 
			
		||||
    toolboxEmphasisColor: '#18a4a6',
 | 
			
		||||
    tooltipAxisColor: '#008acd',
 | 
			
		||||
    tooltipAxisWidth: '1',
 | 
			
		||||
    timelineLineColor: '#008acd',
 | 
			
		||||
    timelineLineWidth: 1,
 | 
			
		||||
    timelineItemColor: '#008acd',
 | 
			
		||||
    timelineItemColorE: '#a9334c',
 | 
			
		||||
    timelineCheckColor: '#2ec7c9',
 | 
			
		||||
    timelineCheckBorderColor: '#2ec7c9',
 | 
			
		||||
    timelineItemBorderWidth: 1,
 | 
			
		||||
    timelineControlColor: '#008acd',
 | 
			
		||||
    timelineControlBorderColor: '#008acd',
 | 
			
		||||
    timelineControlBorderWidth: 0.5,
 | 
			
		||||
    timelineLabelColor: '#008acd',
 | 
			
		||||
    datazoomBackgroundColor: 'rgba(47,69,84,0)',
 | 
			
		||||
    datazoomDataColor: '#efefff',
 | 
			
		||||
    datazoomFillColor: 'rgba(182,162,222,0.2)',
 | 
			
		||||
    datazoomHandleColor: '#008acd',
 | 
			
		||||
    datazoomHandleWidth: '100',
 | 
			
		||||
    datazoomLabelColor: '#333333',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { light };
 | 
			
		||||
							
								
								
									
										135
									
								
								mayfly_go_web/src/views/ops/component/TagTreeResourceSelect.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								mayfly_go_web/src/views/ops/component/TagTreeResourceSelect.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <el-tree-select
 | 
			
		||||
        v-bind="$attrs"
 | 
			
		||||
        ref="treeRef"
 | 
			
		||||
        :highlight-current="true"
 | 
			
		||||
        :indent="10"
 | 
			
		||||
        :load="loadNode"
 | 
			
		||||
        :props="treeProps"
 | 
			
		||||
        lazy
 | 
			
		||||
        node-key="key"
 | 
			
		||||
        :expand-on-click-node="true"
 | 
			
		||||
        filterable
 | 
			
		||||
        :filter-node-method="filterNode"
 | 
			
		||||
        v-model="modelValue"
 | 
			
		||||
        @change="changeNode"
 | 
			
		||||
    >
 | 
			
		||||
        <template #default="{ node, data }">
 | 
			
		||||
            <span>
 | 
			
		||||
                <span v-if="data.type.value == TagTreeNode.TagPath">
 | 
			
		||||
                    <tag-info :tag-path="data.label" />
 | 
			
		||||
                </span>
 | 
			
		||||
 | 
			
		||||
                <slot v-else :node="node" :data="data" name="prefix"></slot>
 | 
			
		||||
 | 
			
		||||
                <span class="ml3" :title="data.labelRemark">
 | 
			
		||||
                    <slot name="label" :data="data"> {{ data.label }}</slot>
 | 
			
		||||
                </span>
 | 
			
		||||
 | 
			
		||||
                <slot :node="node" :data="data" name="suffix"></slot>
 | 
			
		||||
            </span>
 | 
			
		||||
        </template>
 | 
			
		||||
    </el-tree-select>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { onMounted, reactive, ref, watch, toRefs } from 'vue';
 | 
			
		||||
import { NodeType, TagTreeNode } from './tag';
 | 
			
		||||
import TagInfo from './TagInfo.vue';
 | 
			
		||||
import { tagApi } from '../tag/api';
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    resourceType: {
 | 
			
		||||
        type: [Number],
 | 
			
		||||
        required: true,
 | 
			
		||||
    },
 | 
			
		||||
    tagPathNodeType: {
 | 
			
		||||
        type: [NodeType],
 | 
			
		||||
        required: true,
 | 
			
		||||
    },
 | 
			
		||||
    load: {
 | 
			
		||||
        type: Function,
 | 
			
		||||
        required: false,
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const treeProps = {
 | 
			
		||||
    label: 'name',
 | 
			
		||||
    children: 'zones',
 | 
			
		||||
    isLeaf: 'isLeaf',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const treeRef: any = ref(null);
 | 
			
		||||
 | 
			
		||||
const modelValue = defineModel('modelValue');
 | 
			
		||||
 | 
			
		||||
const state = reactive({
 | 
			
		||||
    height: 600 as any,
 | 
			
		||||
    filterText: '',
 | 
			
		||||
    opend: {},
 | 
			
		||||
});
 | 
			
		||||
const { filterText } = toRefs(state);
 | 
			
		||||
 | 
			
		||||
onMounted(async () => {});
 | 
			
		||||
 | 
			
		||||
watch(filterText, (val) => {
 | 
			
		||||
    treeRef.value?.filter(val);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const filterNode = (value: string, data: any) => {
 | 
			
		||||
    if (!value) return true;
 | 
			
		||||
    return data.label.includes(value);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 加载标签树节点
 | 
			
		||||
 */
 | 
			
		||||
const loadTags = async () => {
 | 
			
		||||
    const tags = await tagApi.getResourceTagPaths.request({ resourceType: props.resourceType });
 | 
			
		||||
    const tagNodes = [];
 | 
			
		||||
    for (let tagPath of tags) {
 | 
			
		||||
        tagNodes.push(new TagTreeNode(tagPath, tagPath, props.tagPathNodeType));
 | 
			
		||||
    }
 | 
			
		||||
    return tagNodes;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 加载树节点
 | 
			
		||||
 * @param { Object } node
 | 
			
		||||
 * @param { Object } resolve
 | 
			
		||||
 */
 | 
			
		||||
const loadNode = async (node: any, resolve: any) => {
 | 
			
		||||
    if (typeof resolve !== 'function') {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    let nodes = [];
 | 
			
		||||
    try {
 | 
			
		||||
        if (node.level == 0) {
 | 
			
		||||
            nodes = await loadTags();
 | 
			
		||||
        } else if (props.load) {
 | 
			
		||||
            nodes = await props.load(node);
 | 
			
		||||
        } else {
 | 
			
		||||
            nodes = await node.data.loadChildren();
 | 
			
		||||
        }
 | 
			
		||||
    } catch (e: any) {
 | 
			
		||||
        console.error(e);
 | 
			
		||||
    }
 | 
			
		||||
    return resolve(nodes);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getNode = (nodeKey: any) => {
 | 
			
		||||
    let node = treeRef.value.getNode(nodeKey);
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        throw new Error('未找到节点: ' + nodeKey);
 | 
			
		||||
    }
 | 
			
		||||
    return node;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const changeNode = (val: any) => {
 | 
			
		||||
    // 触发改变时间,并传递节点数据
 | 
			
		||||
    emit('change', getNode(val)?.data);
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped></style>
 | 
			
		||||
@@ -7,47 +7,62 @@
 | 
			
		||||
            :close-on-click-modal="false"
 | 
			
		||||
            :close-on-press-escape="false"
 | 
			
		||||
            :destroy-on-close="true"
 | 
			
		||||
            width="700px"
 | 
			
		||||
            width="850px"
 | 
			
		||||
        >
 | 
			
		||||
            <el-form :model="form" ref="dbForm" :rules="rules" label-width="auto">
 | 
			
		||||
                <el-tabs v-model="tabActiveName" style="height: 450px">
 | 
			
		||||
                    <el-tab-pane label="基本信息" name="basic">
 | 
			
		||||
                        <el-form-item prop="taskName" label="任务名" required>
 | 
			
		||||
                            <el-input v-model.trim="form.taskName" placeholder="请输入数据库别名" auto-complete="off" />
 | 
			
		||||
                        <el-form-item>
 | 
			
		||||
                            <el-row>
 | 
			
		||||
                                <el-col :span="11">
 | 
			
		||||
                                    <el-form-item prop="taskName" label="任务名" required>
 | 
			
		||||
                                        <el-input v-model.trim="form.taskName" placeholder="请输入数据库别名" auto-complete="off" />
 | 
			
		||||
                                    </el-form-item>
 | 
			
		||||
                                </el-col>
 | 
			
		||||
 | 
			
		||||
                                <el-col :span="11">
 | 
			
		||||
                                    <el-form-item prop="taskCron" label="cron" required>
 | 
			
		||||
                                        <template #label>
 | 
			
		||||
                                            cron
 | 
			
		||||
                                            <el-tooltip effect="dark" content="只支持5位表达式,不支持秒级.如 0/2 * * * * 表示每两分钟执行" placement="top">
 | 
			
		||||
                                                <el-icon>
 | 
			
		||||
                                                    <question-filled />
 | 
			
		||||
                                                </el-icon>
 | 
			
		||||
                                            </el-tooltip>
 | 
			
		||||
                                        </template>
 | 
			
		||||
 | 
			
		||||
                                        <el-input v-model="form.taskCron" placeholder="支持5位表达式,不支持秒级" auto-complete="off" />
 | 
			
		||||
                                    </el-form-item>
 | 
			
		||||
                                </el-col>
 | 
			
		||||
 | 
			
		||||
                                <el-col :span="2">
 | 
			
		||||
                                    <el-form-item prop="status" label="状态" label-width="60" required>
 | 
			
		||||
                                        <el-switch
 | 
			
		||||
                                            v-model="form.status"
 | 
			
		||||
                                            inline-prompt
 | 
			
		||||
                                            active-text="启用"
 | 
			
		||||
                                            inactive-text="禁用"
 | 
			
		||||
                                            :active-value="1"
 | 
			
		||||
                                            :inactive-value="-1"
 | 
			
		||||
                                        />
 | 
			
		||||
                                    </el-form-item>
 | 
			
		||||
                                </el-col>
 | 
			
		||||
                            </el-row>
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                        <el-form-item prop="taskCron" label="cron" required>
 | 
			
		||||
                            <el-input v-model="form.taskCron" placeholder="只支持5位表达式,不支持秒级.如 0/2 * * * * 表示每两分钟执行" auto-complete="off" />
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                        <el-form-item prop="pageSize" label="分页大小" required>
 | 
			
		||||
                            <el-input-number v-model.trim="form.pageSize" placeholder="同步数据时查询的每页数据大小" auto-complete="off" size="small" />
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                        <el-form-item prop="updField" label="更新字段" required>
 | 
			
		||||
                            <el-input v-model.trim="form.updField" placeholder="查询数据源的时候会带上这个字段当前最大值" auto-complete="off" />
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                        <el-form-item prop="updFieldVal" label="更新值">
 | 
			
		||||
                            <el-input v-model.trim="form.updFieldVal" placeholder="更新字段当前最大值" auto-complete="off" />
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                        <el-form-item prop="status" label="状态" required>
 | 
			
		||||
                            <el-switch v-model="form.status" inline-prompt active-text="启用" inactive-text="禁用" :active-value="1" :inactive-value="-1" />
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                    </el-tab-pane>
 | 
			
		||||
                    <el-tab-pane label="源数据库配置" name="srcDb">
 | 
			
		||||
                        <el-form-item prop="srcDbId" label="数据源" required>
 | 
			
		||||
 | 
			
		||||
                        <el-form-item prop="srcDbId" label="源数据库" required>
 | 
			
		||||
                            <db-select-tree
 | 
			
		||||
                                placeholder="请选择源数据库"
 | 
			
		||||
                                v-model:db-id="form.srcDbId"
 | 
			
		||||
                                v-model:db-name="form.srcDbName"
 | 
			
		||||
                                v-model:tag-path="form.srcTagPath"
 | 
			
		||||
                                @select-db="onSelectSrcDb"
 | 
			
		||||
                            />
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                        <el-form-item prop="dataSql" label="数据sql" required>
 | 
			
		||||
                            <monaco-editor height="200px" class="task-sql" language="sql" v-model="form.dataSql" />
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                    </el-tab-pane>
 | 
			
		||||
 | 
			
		||||
                    <el-tab-pane label="目标数据库配置" name="targetDb">
 | 
			
		||||
                        <el-form-item prop="targetDbId" label="数据源" required>
 | 
			
		||||
                        <el-form-item prop="targetDbId" label="目标数据库" required>
 | 
			
		||||
                            <db-select-tree
 | 
			
		||||
                                placeholder="请选择目标数据库"
 | 
			
		||||
                                v-model:db-id="form.targetDbId"
 | 
			
		||||
                                v-model:db-name="form.targetDbName"
 | 
			
		||||
                                v-model:tag-path="form.targetTagPath"
 | 
			
		||||
@@ -55,7 +70,11 @@
 | 
			
		||||
                            />
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
 | 
			
		||||
                        <el-form-item prop="targetTableName" label="目标表" required>
 | 
			
		||||
                        <el-form-item prop="dataSql" label="源数据sql" required>
 | 
			
		||||
                            <monaco-editor height="150px" class="task-sql" language="sql" v-model="form.dataSql" />
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
 | 
			
		||||
                        <el-form-item prop="targetTableName" label="目标库表" required>
 | 
			
		||||
                            <el-select v-model="form.targetTableName" filterable placeholder="请选择目标数据库表">
 | 
			
		||||
                                <el-option
 | 
			
		||||
                                    v-for="item in state.targetTableList"
 | 
			
		||||
@@ -65,7 +84,30 @@
 | 
			
		||||
                                />
 | 
			
		||||
                            </el-select>
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
 | 
			
		||||
                        <el-form-item>
 | 
			
		||||
                            <el-row>
 | 
			
		||||
                                <el-col :span="8">
 | 
			
		||||
                                    <el-form-item prop="pageSize" label="分页大小" required>
 | 
			
		||||
                                        <el-input type="number" v-model.trim="form.pageSize" placeholder="同步数据时查询的每页数据大小" auto-complete="off" />
 | 
			
		||||
                                    </el-form-item>
 | 
			
		||||
                                </el-col>
 | 
			
		||||
 | 
			
		||||
                                <el-col :span="8">
 | 
			
		||||
                                    <el-form-item prop="updField" label="更新字段" required>
 | 
			
		||||
                                        <el-input v-model.trim="form.updField" placeholder="查询数据源的时候会带上这个字段当前最大值" auto-complete="off" />
 | 
			
		||||
                                    </el-form-item>
 | 
			
		||||
                                </el-col>
 | 
			
		||||
 | 
			
		||||
                                <el-col :span="8">
 | 
			
		||||
                                    <el-form-item prop="updFieldVal" label="更新值">
 | 
			
		||||
                                        <el-input v-model.trim="form.updFieldVal" placeholder="更新字段当前最大值" auto-complete="off" />
 | 
			
		||||
                                    </el-form-item>
 | 
			
		||||
                                </el-col>
 | 
			
		||||
                            </el-row>
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                    </el-tab-pane>
 | 
			
		||||
 | 
			
		||||
                    <el-tab-pane label="字段映射" name="field">
 | 
			
		||||
                        <el-form-item prop="fieldMap" label="字段映射" required>
 | 
			
		||||
                            <el-table :data="form.fieldMap" :max-height="400" size="small">
 | 
			
		||||
@@ -85,6 +127,7 @@
 | 
			
		||||
                            </el-table>
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
                    </el-tab-pane>
 | 
			
		||||
 | 
			
		||||
                    <el-tab-pane label="sql预览" name="sqlPreview">
 | 
			
		||||
                        <el-form-item prop="fieldMap" label="查询sql">
 | 
			
		||||
                            <el-input type="textarea" v-model="state.previewDataSql" readonly :input-style="{ height: '190px' }" />
 | 
			
		||||
@@ -226,48 +269,43 @@ watch(dialogVisible, async (newValue: boolean) => {
 | 
			
		||||
    }
 | 
			
		||||
    state.tabActiveName = 'basic';
 | 
			
		||||
    const propsData = props.data as any;
 | 
			
		||||
    if (propsData?.id) {
 | 
			
		||||
        let data = await dbApi.getDatasyncTask.request({ taskId: propsData?.id });
 | 
			
		||||
        state.form = data;
 | 
			
		||||
        try {
 | 
			
		||||
            state.form.fieldMap = JSON.parse(data.fieldMap);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            state.form.fieldMap = [];
 | 
			
		||||
        }
 | 
			
		||||
        let { srcDbId, srcTagPath, srcDbName, targetTagPath, targetDbId } = state.form;
 | 
			
		||||
 | 
			
		||||
        //  初始化src数据源
 | 
			
		||||
        if (srcTagPath && srcDbId) {
 | 
			
		||||
            // 通过tagPath查询实例列表
 | 
			
		||||
            const dbInfoRes = await dbApi.dbs.request({ tagPath: srcTagPath });
 | 
			
		||||
            dbInfoRes.list.forEach((a: any) => {
 | 
			
		||||
                if (a.id === srcDbId) {
 | 
			
		||||
                    // 初始化实例
 | 
			
		||||
                    a.databases = a.database?.split(' ').sort() || [];
 | 
			
		||||
                    state.srcDbInst = DbInst.getOrNewInst(a);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //  初始化target数据源
 | 
			
		||||
        if (targetTagPath && targetDbId) {
 | 
			
		||||
            // 通过tagPath查询实例列表
 | 
			
		||||
            const dbInfoRes = await dbApi.dbs.request({ tagPath: targetTagPath });
 | 
			
		||||
            dbInfoRes.list.forEach((a: any) => {
 | 
			
		||||
                if (a.id === targetDbId) {
 | 
			
		||||
                    // 初始化实例
 | 
			
		||||
                    a.databases = a.database?.split(' ').sort() || [];
 | 
			
		||||
                    state.targetDbInst = DbInst.getOrNewInst(a);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 注册sql代码提示
 | 
			
		||||
        if (srcDbId && srcDbName) {
 | 
			
		||||
            registerDbCompletionItemProvider(srcDbId, srcDbName, state.srcDbInst.databases, state.srcDbInst.type);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
    if (!propsData?.id) {
 | 
			
		||||
        state.form = basicFormData;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let data = await dbApi.getDatasyncTask.request({ taskId: propsData?.id });
 | 
			
		||||
    state.form = data;
 | 
			
		||||
    try {
 | 
			
		||||
        state.form.fieldMap = JSON.parse(data.fieldMap);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        state.form.fieldMap = [];
 | 
			
		||||
    }
 | 
			
		||||
    let { srcDbId, srcDbName, targetDbId } = state.form;
 | 
			
		||||
 | 
			
		||||
    //  初始化src数据源
 | 
			
		||||
    if (srcDbId) {
 | 
			
		||||
        // 通过tagPath查询实例列表
 | 
			
		||||
        const dbInfoRes = await dbApi.dbs.request({ id: srcDbId });
 | 
			
		||||
        const db = dbInfoRes.list[0];
 | 
			
		||||
        // 初始化实例
 | 
			
		||||
        db.databases = db.database?.split(' ').sort() || [];
 | 
			
		||||
        state.srcDbInst = DbInst.getOrNewInst(db);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //  初始化target数据源
 | 
			
		||||
    if (targetDbId) {
 | 
			
		||||
        // 通过tagPath查询实例列表
 | 
			
		||||
        const dbInfoRes = await dbApi.dbs.request({ id: targetDbId });
 | 
			
		||||
        const db = dbInfoRes.list[0];
 | 
			
		||||
        // 初始化实例
 | 
			
		||||
        db.databases = db.database?.split(' ').sort() || [];
 | 
			
		||||
        state.targetDbInst = DbInst.getOrNewInst(db);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 注册sql代码提示
 | 
			
		||||
    if (srcDbId && srcDbName) {
 | 
			
		||||
        registerDbCompletionItemProvider(srcDbId, srcDbName, state.srcDbInst.databases, state.srcDbInst.type);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@@ -277,7 +315,7 @@ watch(tabActiveName, async (newValue: string) => {
 | 
			
		||||
            await handleGetSrcFields();
 | 
			
		||||
            await handleGetTargetFields();
 | 
			
		||||
            break;
 | 
			
		||||
        case 'targetDb':
 | 
			
		||||
        case 'dbConf':
 | 
			
		||||
            await handleGetTargetFields();
 | 
			
		||||
            if (state.form.targetDbId && state.form.targetDbName) {
 | 
			
		||||
                await loadDbTables(state.form.targetDbId, state.form.targetDbName);
 | 
			
		||||
@@ -418,8 +456,12 @@ const cancel = () => {
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
.sync-task-edit {
 | 
			
		||||
    .el-select {
 | 
			
		||||
        width: 360px;
 | 
			
		||||
        // width: 360px;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
    // .el-input__inner {
 | 
			
		||||
    //     width: 100%; /* 将el-select内部输入框的宽度设置为100% */
 | 
			
		||||
    // }
 | 
			
		||||
    .task-sql {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,29 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="db-select-tree">
 | 
			
		||||
        <div style="color: gray">{{ (tagPath || '') + ' - ' + (dbName || '请选择数据源schema') }}</div>
 | 
			
		||||
        <tag-tree :resource-type="TagResourceTypeEnum.Db.value" :tag-path-node-type="NodeTypeTagPath" ref="tagTreeRef">
 | 
			
		||||
            <template #prefix="{ data }">
 | 
			
		||||
                <SvgIcon v-if="data.type.value == SqlExecNodeType.DbInst" :name="getDbDialect(data.params.type).getInfo().icon" :size="18" />
 | 
			
		||||
                <SvgIcon v-if="data.icon" :name="data.icon.name" :color="data.icon.color" />
 | 
			
		||||
            </template>
 | 
			
		||||
        </tag-tree>
 | 
			
		||||
    </div>
 | 
			
		||||
    <TagTreeResourceSelect
 | 
			
		||||
        v-bind="$attrs"
 | 
			
		||||
        v-model="selectNode"
 | 
			
		||||
        @change="changeNode"
 | 
			
		||||
        :resource-type="TagResourceTypeEnum.Db.value"
 | 
			
		||||
        :tag-path-node-type="NodeTypeTagPath"
 | 
			
		||||
    >
 | 
			
		||||
        <template #prefix="{ data }">
 | 
			
		||||
            <SvgIcon v-if="data.type.value == SqlExecNodeType.DbInst" :name="getDbDialect(data.params.type).getInfo().icon" :size="18" />
 | 
			
		||||
            <SvgIcon v-if="data.icon" :name="data.icon.name" :color="data.icon.color" />
 | 
			
		||||
        </template>
 | 
			
		||||
    </TagTreeResourceSelect>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { TagResourceTypeEnum } from '@/common/commonEnum';
 | 
			
		||||
import TagTree from '@/views/ops/component/TagTree.vue';
 | 
			
		||||
import { NodeType, TagTreeNode } from '@/views/ops/component/tag';
 | 
			
		||||
import { dbApi } from '@/views/ops/db/api';
 | 
			
		||||
import { sleep } from '@/common/utils/loading';
 | 
			
		||||
import SvgIcon from '@/components/svgIcon/index.vue';
 | 
			
		||||
import { DbType, getDbDialect } from '@/views/ops/db/dialect';
 | 
			
		||||
import TagTreeResourceSelect from '../../component/TagTreeResourceSelect.vue';
 | 
			
		||||
import { computed } from 'vue';
 | 
			
		||||
 | 
			
		||||
defineProps({
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    dbId: {
 | 
			
		||||
        type: Number,
 | 
			
		||||
    },
 | 
			
		||||
@@ -47,6 +51,15 @@ class SqlExecNodeType {
 | 
			
		||||
    static PgSchema = 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const selectNode = computed({
 | 
			
		||||
    get: () => {
 | 
			
		||||
        return props.dbName ? `${props.tagPath} - ${props.dbId} - ${props.dbName}` : '';
 | 
			
		||||
    },
 | 
			
		||||
    set: () => {
 | 
			
		||||
        //
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const DbIcon = {
 | 
			
		||||
    name: 'Coin',
 | 
			
		||||
    color: '#67c23a',
 | 
			
		||||
@@ -89,7 +102,7 @@ const NodeTypeDbInst = new NodeType(SqlExecNodeType.DbInst).withLoadNodesFunc((p
 | 
			
		||||
        fn = PgNodeTypes;
 | 
			
		||||
    }
 | 
			
		||||
    return dbs.map((x: any) => {
 | 
			
		||||
        let tagTreeNode = new TagTreeNode(`${parentNode.key}.${x}`, x, fn)
 | 
			
		||||
        let tagTreeNode = new TagTreeNode(`${parentNode.key}.${x}`, `${x}`, fn)
 | 
			
		||||
            .withParams({
 | 
			
		||||
                tagPath: params.tagPath,
 | 
			
		||||
                id: params.id,
 | 
			
		||||
@@ -108,17 +121,6 @@ const NodeTypeDbInst = new NodeType(SqlExecNodeType.DbInst).withLoadNodesFunc((p
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const nodeClickChangeDb = (nodeData: TagTreeNode) => {
 | 
			
		||||
    const params = nodeData.params;
 | 
			
		||||
    // postgres
 | 
			
		||||
    emits('update:dbName', params.db);
 | 
			
		||||
    emits('update:dbId', params.id);
 | 
			
		||||
    emits('update:tagPath', params.tagPath);
 | 
			
		||||
    emits('selectDb', params);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 数据库节点
 | 
			
		||||
const PgNodeTypes = new NodeType(SqlExecNodeType.Db).withLoadNodesFunc(async (parentNode: TagTreeNode) => {
 | 
			
		||||
    // pg类数据库会多一层schema
 | 
			
		||||
@@ -137,23 +139,19 @@ const PgNodeTypes = new NodeType(SqlExecNodeType.Db).withLoadNodesFunc(async (pa
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const MysqlNodeTypes = new NodeType(SqlExecNodeType.Db).withNodeClickFunc(nodeClickChangeDb);
 | 
			
		||||
const MysqlNodeTypes = new NodeType(SqlExecNodeType.Db);
 | 
			
		||||
 | 
			
		||||
// postgres schema模式
 | 
			
		||||
const NodeTypePostgresSchema = new NodeType(SqlExecNodeType.PgSchema).withNodeClickFunc(nodeClickChangeDb);
 | 
			
		||||
const NodeTypePostgresSchema = new NodeType(SqlExecNodeType.PgSchema);
 | 
			
		||||
 | 
			
		||||
const changeNode = (nodeData: TagTreeNode) => {
 | 
			
		||||
    const params = nodeData.params;
 | 
			
		||||
    // postgres
 | 
			
		||||
    emits('update:dbName', params.db);
 | 
			
		||||
    emits('update:dbId', params.id);
 | 
			
		||||
    emits('update:tagPath', params.tagPath);
 | 
			
		||||
    emits('selectDb', params);
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
.db-select-tree {
 | 
			
		||||
    .tag-tree {
 | 
			
		||||
        height: auto !important;
 | 
			
		||||
        overflow-x: hidden;
 | 
			
		||||
        width: 560px;
 | 
			
		||||
        .el-tree {
 | 
			
		||||
            height: 150px;
 | 
			
		||||
            overflow-y: auto;
 | 
			
		||||
            overflow-x: hidden;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
<style lang="scss"></style>
 | 
			
		||||
 
 | 
			
		||||
@@ -24,11 +24,11 @@
 | 
			
		||||
                </el-col>
 | 
			
		||||
 | 
			
		||||
                <el-col :lg="6" :md="6">
 | 
			
		||||
                    <div class="card-item-chart" ref="memRef"></div>
 | 
			
		||||
                    <ECharts height="200" :option="state.memOption" />
 | 
			
		||||
                </el-col>
 | 
			
		||||
 | 
			
		||||
                <el-col :lg="6" :md="6">
 | 
			
		||||
                    <div class="card-item-chart" ref="cpuRef"></div>
 | 
			
		||||
                    <ECharts height="200" :option="state.cpuOption" />
 | 
			
		||||
                </el-col>
 | 
			
		||||
            </el-row>
 | 
			
		||||
 | 
			
		||||
@@ -74,11 +74,11 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { toRefs, reactive, watch, ref, nextTick } from 'vue';
 | 
			
		||||
import useEcharts from '@/common/echarts/useEcharts';
 | 
			
		||||
import tdTheme from '@/common/echarts/theme.json';
 | 
			
		||||
import { toRefs, reactive, watch, nextTick } from 'vue';
 | 
			
		||||
import { formatByteSize } from '@/common/utils/format';
 | 
			
		||||
import { machineApi } from './api';
 | 
			
		||||
import ECharts from '@/components/echarts/ECharts.vue';
 | 
			
		||||
import { ECOption } from '@/components/echarts/config';
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    visible: {
 | 
			
		||||
@@ -94,22 +94,16 @@ const props = defineProps({
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['update:visible', 'cancel', 'update:machineId']);
 | 
			
		||||
 | 
			
		||||
const cpuRef: any = ref();
 | 
			
		||||
const memRef: any = ref();
 | 
			
		||||
 | 
			
		||||
let cpuChart: any = null;
 | 
			
		||||
let memChart: any = null;
 | 
			
		||||
 | 
			
		||||
const state = reactive({
 | 
			
		||||
    dialogVisible: false,
 | 
			
		||||
    stats: {} as any,
 | 
			
		||||
    netInter: [] as any,
 | 
			
		||||
    memOption: {},
 | 
			
		||||
    cpuOption: {},
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const { dialogVisible, stats, netInter } = toRefs(state);
 | 
			
		||||
 | 
			
		||||
let charts = [] as any;
 | 
			
		||||
 | 
			
		||||
watch(props, async (newValue: any) => {
 | 
			
		||||
    const visible = newValue.visible;
 | 
			
		||||
    if (visible) {
 | 
			
		||||
@@ -139,15 +133,15 @@ const initMemStats = () => {
 | 
			
		||||
            value: mem.total - mem.available,
 | 
			
		||||
        },
 | 
			
		||||
    ];
 | 
			
		||||
    const option = {
 | 
			
		||||
 | 
			
		||||
    const option: ECOption = {
 | 
			
		||||
        title: {
 | 
			
		||||
            text: '内存',
 | 
			
		||||
            x: 'left',
 | 
			
		||||
            textStyle: { fontSize: 15 },
 | 
			
		||||
        },
 | 
			
		||||
        tooltip: {
 | 
			
		||||
            trigger: 'item',
 | 
			
		||||
            valueFormatter: formatByteSize,
 | 
			
		||||
            valueFormatter: (val: any) => formatByteSize(val),
 | 
			
		||||
        },
 | 
			
		||||
        legend: {
 | 
			
		||||
            top: '15%',
 | 
			
		||||
@@ -180,13 +174,7 @@ const initMemStats = () => {
 | 
			
		||||
            },
 | 
			
		||||
        ],
 | 
			
		||||
    };
 | 
			
		||||
    if (memChart) {
 | 
			
		||||
        memChart.setOption(option, true);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    const chart: any = useEcharts(memRef.value, tdTheme, option);
 | 
			
		||||
    memChart = chart;
 | 
			
		||||
    charts.push(chart);
 | 
			
		||||
    state.memOption = option;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const initCpuStats = () => {
 | 
			
		||||
@@ -206,10 +194,10 @@ const initCpuStats = () => {
 | 
			
		||||
            value: cpu.user,
 | 
			
		||||
        },
 | 
			
		||||
    ];
 | 
			
		||||
    const option = {
 | 
			
		||||
 | 
			
		||||
    const option: ECOption = {
 | 
			
		||||
        title: {
 | 
			
		||||
            text: 'CPU使用率',
 | 
			
		||||
            x: 'left',
 | 
			
		||||
            textStyle: { fontSize: 15 },
 | 
			
		||||
        },
 | 
			
		||||
        tooltip: {
 | 
			
		||||
@@ -247,13 +235,7 @@ const initCpuStats = () => {
 | 
			
		||||
            },
 | 
			
		||||
        ],
 | 
			
		||||
    };
 | 
			
		||||
    if (cpuChart) {
 | 
			
		||||
        cpuChart.setOption(option, true);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    const chart: any = useEcharts(cpuRef.value, tdTheme, option);
 | 
			
		||||
    cpuChart = chart;
 | 
			
		||||
    charts.push(chart);
 | 
			
		||||
    state.cpuOption = option;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const initCharts = () => {
 | 
			
		||||
@@ -262,21 +244,6 @@ const initCharts = () => {
 | 
			
		||||
        initCpuStats();
 | 
			
		||||
    });
 | 
			
		||||
    parseNetInter();
 | 
			
		||||
    initEchartsResize();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const initEchartResizeFun = () => {
 | 
			
		||||
    nextTick(() => {
 | 
			
		||||
        for (let i = 0; i < charts.length; i++) {
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
                charts[i].resize();
 | 
			
		||||
            }, i * 1000);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const initEchartsResize = () => {
 | 
			
		||||
    window.addEventListener('resize', initEchartResizeFun);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const parseNetInter = () => {
 | 
			
		||||
@@ -295,16 +262,6 @@ const parseNetInter = () => {
 | 
			
		||||
const cancel = () => {
 | 
			
		||||
    emit('update:visible', false);
 | 
			
		||||
    emit('cancel');
 | 
			
		||||
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
        cpuChart = null;
 | 
			
		||||
        memChart = null;
 | 
			
		||||
    }, 200);
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
.card-item-chart {
 | 
			
		||||
    height: 200px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
<style lang="scss"></style>
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
                    </el-descriptions>
 | 
			
		||||
                </el-col>
 | 
			
		||||
                <el-col :lg="8" :md="8" class="redis-info">
 | 
			
		||||
                    <div class="info-memory-chart" ref="memRef"></div>
 | 
			
		||||
                    <ECharts height="150" width="360" :option="state.memOption" />
 | 
			
		||||
                </el-col>
 | 
			
		||||
            </el-row>
 | 
			
		||||
 | 
			
		||||
@@ -72,10 +72,10 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { reactive, watch, toRefs, ref, nextTick } from 'vue';
 | 
			
		||||
import { reactive, watch, toRefs, nextTick } from 'vue';
 | 
			
		||||
import { formatByteSize } from '@/common/utils/format';
 | 
			
		||||
import useEcharts from '@/common/echarts/useEcharts';
 | 
			
		||||
import tdTheme from '@/common/echarts/theme.json';
 | 
			
		||||
import ECharts from '@/components/echarts/ECharts.vue';
 | 
			
		||||
import { ECOption } from '@/components/echarts/config';
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    visible: {
 | 
			
		||||
@@ -86,6 +86,7 @@ const props = defineProps({
 | 
			
		||||
    },
 | 
			
		||||
    info: {
 | 
			
		||||
        type: [Boolean, Object],
 | 
			
		||||
        default: () => {},
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@@ -95,11 +96,9 @@ const state = reactive({
 | 
			
		||||
    dialogVisible: false,
 | 
			
		||||
    memInfo: {} as any,
 | 
			
		||||
    Keyspace: [] as any[],
 | 
			
		||||
    memOption: {},
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
let memChart: any = null;
 | 
			
		||||
let memRef = ref(null);
 | 
			
		||||
 | 
			
		||||
const { dialogVisible, Keyspace } = toRefs(state);
 | 
			
		||||
 | 
			
		||||
watch(
 | 
			
		||||
@@ -146,15 +145,14 @@ const initMemStats = () => {
 | 
			
		||||
            value: state.memInfo.used_memory,
 | 
			
		||||
        },
 | 
			
		||||
    ];
 | 
			
		||||
    const option = {
 | 
			
		||||
    const option: ECOption = {
 | 
			
		||||
        title: {
 | 
			
		||||
            text: '内存',
 | 
			
		||||
            x: 'left',
 | 
			
		||||
            textStyle: { fontSize: 14 },
 | 
			
		||||
        },
 | 
			
		||||
        tooltip: {
 | 
			
		||||
            trigger: 'item',
 | 
			
		||||
            valueFormatter: formatByteSize,
 | 
			
		||||
            valueFormatter: (val: any) => formatByteSize(val),
 | 
			
		||||
        },
 | 
			
		||||
        legend: {
 | 
			
		||||
            top: '15%',
 | 
			
		||||
@@ -186,11 +184,8 @@ const initMemStats = () => {
 | 
			
		||||
            },
 | 
			
		||||
        ],
 | 
			
		||||
    };
 | 
			
		||||
    if (memChart) {
 | 
			
		||||
        memChart.setOption(option, true);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    memChart = useEcharts(memRef.value, tdTheme, option);
 | 
			
		||||
 | 
			
		||||
    state.memOption = option;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const close = () => {
 | 
			
		||||
@@ -202,11 +197,6 @@ const close = () => {
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
.redis-info {
 | 
			
		||||
    margin-top: 12px;
 | 
			
		||||
 | 
			
		||||
    .info-memory-chart {
 | 
			
		||||
        width: 360px;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.row .title {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
package entity
 | 
			
		||||
 | 
			
		||||
import "mayfly-go/pkg/model"
 | 
			
		||||
 | 
			
		||||
// InstanceQuery 数据库实例查询
 | 
			
		||||
type InstanceQuery struct {
 | 
			
		||||
	Id   uint64 `json:"id" form:"id"`
 | 
			
		||||
@@ -19,7 +17,7 @@ type DataSyncLogQuery struct {
 | 
			
		||||
 | 
			
		||||
// 数据库查询实体,不与数据库表字段一一对应
 | 
			
		||||
type DbQuery struct {
 | 
			
		||||
	model.Model
 | 
			
		||||
	Id uint64 `form:"id"`
 | 
			
		||||
 | 
			
		||||
	Name     string `orm:"column(name)" json:"name"`
 | 
			
		||||
	Database string `orm:"column(database)" json:"database"`
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ func (d *dbRepoImpl) GetDbList(condition *entity.DbQuery, pageParam *model.PageP
 | 
			
		||||
		Select("db.*, inst.name instance_name, inst.type instance_type, inst.host, inst.port, inst.username ").
 | 
			
		||||
		Joins("JOIN t_db_instance inst ON db.instance_id = inst.id").
 | 
			
		||||
		Eq("db.instance_id", condition.InstanceId).
 | 
			
		||||
		Eq("db.id", condition.Id).
 | 
			
		||||
		Like("db.database", condition.Database).
 | 
			
		||||
		In("db.code", condition.Codes).
 | 
			
		||||
		Eq0("db."+model.DeletedColumn, model.ModelUndeleted).
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user