mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 16:30:25 +08:00 
			
		
		
		
	refactor: tooltip延迟显示等
This commit is contained in:
		@@ -59,15 +59,20 @@ export async function useLoginCaptcha(): Promise<boolean> {
 | 
			
		||||
 */
 | 
			
		||||
export async function useWatermark(): Promise<any> {
 | 
			
		||||
    const value = await getConfigValue(UseWatermarkConfigKey);
 | 
			
		||||
    const defaultValue = {
 | 
			
		||||
        isUse: true,
 | 
			
		||||
    };
 | 
			
		||||
    if (!value) {
 | 
			
		||||
        return {
 | 
			
		||||
            isUse: true,
 | 
			
		||||
        };
 | 
			
		||||
        return defaultValue;
 | 
			
		||||
    }
 | 
			
		||||
    try {
 | 
			
		||||
        const jsonValue = JSON.parse(value);
 | 
			
		||||
        // 将字符串转为bool
 | 
			
		||||
        jsonValue.isUse = convertBool(jsonValue.isUse, true);
 | 
			
		||||
        return jsonValue;
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        return defaultValue;
 | 
			
		||||
    }
 | 
			
		||||
    const jsonValue = JSON.parse(value);
 | 
			
		||||
    // 将字符串转为bool
 | 
			
		||||
    jsonValue.isUse = convertBool(jsonValue.isUse, true);
 | 
			
		||||
    return jsonValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function convertBool(value: string, defaultValue: boolean) {
 | 
			
		||||
 
 | 
			
		||||
@@ -132,7 +132,7 @@ const languageArr = [
 | 
			
		||||
    },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
const options = {
 | 
			
		||||
const defaultOptions = {
 | 
			
		||||
    language: 'shell',
 | 
			
		||||
    theme: 'SolarizedLight',
 | 
			
		||||
    automaticLayout: true, //自适应宽高布局
 | 
			
		||||
@@ -223,9 +223,9 @@ const initMonacoEditorIns = () => {
 | 
			
		||||
    // options参数参考 https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneEditorConstructionOptions.html#language
 | 
			
		||||
    // 初始化一些主题
 | 
			
		||||
    monaco.editor.defineTheme('SolarizedLight', SolarizedLight);
 | 
			
		||||
    options.language = state.languageMode;
 | 
			
		||||
    options.theme = themeConfig.value.editorTheme;
 | 
			
		||||
    monacoEditorIns = monaco.editor.create(monacoTextarea.value, Object.assign(options, props.options as any));
 | 
			
		||||
    defaultOptions.language = state.languageMode;
 | 
			
		||||
    defaultOptions.theme = themeConfig.value.editorTheme;
 | 
			
		||||
    monacoEditorIns = monaco.editor.create(monacoTextarea.value, Object.assign(defaultOptions, props.options as any));
 | 
			
		||||
 | 
			
		||||
    // 监听内容改变,双向绑定
 | 
			
		||||
    monacoEditorIns.onDidChangeModelContent(() => {
 | 
			
		||||
 
 | 
			
		||||
@@ -151,7 +151,7 @@ export const useThemeConfig = defineStore('themeConfig', {
 | 
			
		||||
                this.themeConfig.editorTheme = 'vs-dark';
 | 
			
		||||
            } else {
 | 
			
		||||
                body.setAttribute('class', '');
 | 
			
		||||
                this.themeConfig.editorTheme = 'SolarizedLight';
 | 
			
		||||
                this.themeConfig.editorTheme = 'vs';
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        // 设置水印配置信息
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div style="display: inline-flex; justify-content: center; align-items: center; cursor: pointer; vertical-align: middle">
 | 
			
		||||
        <el-popover @show="showTagInfo" placement="top-start" title="标签信息" :width="300" trigger="hover">
 | 
			
		||||
        <el-popover :show-after="500" @show="showTagInfo" placement="top-start" title="标签信息" :width="300" trigger="hover">
 | 
			
		||||
            <template #reference>
 | 
			
		||||
                <el-icon>
 | 
			
		||||
                    <InfoFilled />
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,10 @@
 | 
			
		||||
                </span>
 | 
			
		||||
            </template>
 | 
			
		||||
 | 
			
		||||
            <template #host="{ data }">
 | 
			
		||||
                {{ `${data.host}:${data.port}` }}
 | 
			
		||||
            </template>
 | 
			
		||||
 | 
			
		||||
            <template #database="{ data }">
 | 
			
		||||
                <el-popover placement="right" trigger="click" :width="300">
 | 
			
		||||
                    <template #reference>
 | 
			
		||||
@@ -195,6 +199,10 @@ const queryConfig = [TableQuery.slot('tagPath', '标签', 'tagPathSelect'), Tabl
 | 
			
		||||
 | 
			
		||||
const columns = ref([
 | 
			
		||||
    TableColumn.new('tagPath', '标签路径').isSlot().setAddWidth(20),
 | 
			
		||||
    TableColumn.new('instanceName', '实例名'),
 | 
			
		||||
    TableColumn.new('type', '类型'),
 | 
			
		||||
    TableColumn.new('host', 'ip:port').isSlot().setAddWidth(20),
 | 
			
		||||
    TableColumn.new('username', 'username'),
 | 
			
		||||
    TableColumn.new('name', '名称'),
 | 
			
		||||
    TableColumn.new('database', '数据库').isSlot().setMinWidth(70),
 | 
			
		||||
    TableColumn.new('remark', '备注'),
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@
 | 
			
		||||
                >
 | 
			
		||||
                    <template #prefix="{ data }">
 | 
			
		||||
                        <span v-if="data.type == NodeType.DbInst">
 | 
			
		||||
                            <el-popover placement="right-start" title="数据库实例信息" trigger="hover" :width="210">
 | 
			
		||||
                            <el-popover :show-after="500" placement="right-start" title="数据库实例信息" trigger="hover" :width="210">
 | 
			
		||||
                                <template #reference>
 | 
			
		||||
                                    <SvgIcon v-if="data.params.type === 'mysql'" name="iconfont icon-op-mysql" :size="18" />
 | 
			
		||||
                                    <SvgIcon v-if="data.params.type === 'postgres'" name="iconfont icon-op-postgres" :size="18" />
 | 
			
		||||
@@ -47,8 +47,10 @@
 | 
			
		||||
                                    <SvgIcon name="InfoFilled" v-else />
 | 
			
		||||
                                </template>
 | 
			
		||||
                                <template #default>
 | 
			
		||||
                                    <el-form class="instances-pop-form" label-width="55px" :size="'small'">
 | 
			
		||||
                                    <el-form class="instances-pop-form" label-width="auto" :size="'small'">
 | 
			
		||||
                                        <el-form-item label="类型:">{{ data.params.type }}</el-form-item>
 | 
			
		||||
                                        <el-form-item label="host:">{{ `${data.params.host}:${data.params.port}` }}</el-form-item>
 | 
			
		||||
                                        <el-form-item label="user:">{{ data.params.username }}</el-form-item>
 | 
			
		||||
                                        <el-form-item label="名称:">{{ data.params.name }}</el-form-item>
 | 
			
		||||
                                        <el-form-item v-if="data.params.remark" label="备注:">{{ data.params.remark }}</el-form-item>
 | 
			
		||||
                                    </el-form>
 | 
			
		||||
@@ -60,7 +62,13 @@
 | 
			
		||||
 | 
			
		||||
                        <SvgIcon name="Calendar" v-if="data.type == NodeType.TableMenu" color="#409eff" />
 | 
			
		||||
 | 
			
		||||
                        <el-tooltip v-if="data.type == NodeType.Table" effect="customized" :content="data.params.tableComment" placement="top-end">
 | 
			
		||||
                        <el-tooltip
 | 
			
		||||
                            :show-after="500"
 | 
			
		||||
                            v-if="data.type == NodeType.Table"
 | 
			
		||||
                            effect="customized"
 | 
			
		||||
                            :content="data.params.tableComment"
 | 
			
		||||
                            placement="top-end"
 | 
			
		||||
                        >
 | 
			
		||||
                            <SvgIcon name="Calendar" color="#409eff" />
 | 
			
		||||
                        </el-tooltip>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@
 | 
			
		||||
                    :sortable="sortable"
 | 
			
		||||
                >
 | 
			
		||||
                    <template #header v-if="showColumnTip">
 | 
			
		||||
                        <el-tooltip raw-content placement="top" effect="customized">
 | 
			
		||||
                        <el-tooltip :show-after="500" raw-content placement="top" effect="customized">
 | 
			
		||||
                            <template #content> {{ getColumnTip(item) }} </template>
 | 
			
		||||
                            {{ item.columnName }}
 | 
			
		||||
                        </el-tooltip>
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
import { onMounted, watch, reactive, toRefs } from 'vue';
 | 
			
		||||
import { DbInst, UpdateFieldsMeta, FieldsMeta } from '../db';
 | 
			
		||||
 | 
			
		||||
const emits = defineEmits(['sortChange', 'deleteData', 'selectionChange', 'changeUpdatedField'])
 | 
			
		||||
const emits = defineEmits(['sortChange', 'deleteData', 'selectionChange', 'changeUpdatedField']);
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    dbId: {
 | 
			
		||||
@@ -54,7 +54,7 @@ const props = defineProps({
 | 
			
		||||
    },
 | 
			
		||||
    dbType: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: ''
 | 
			
		||||
        default: '',
 | 
			
		||||
    },
 | 
			
		||||
    db: {
 | 
			
		||||
        type: String,
 | 
			
		||||
@@ -88,14 +88,14 @@ const props = defineProps({
 | 
			
		||||
    },
 | 
			
		||||
    height: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: '600'
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
        default: '600',
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const state = reactive({
 | 
			
		||||
    dbId: 0, // 当前选中操作的数据库实例
 | 
			
		||||
    dbType: '',
 | 
			
		||||
    db: '',  // 数据库名
 | 
			
		||||
    db: '', // 数据库名
 | 
			
		||||
    table: '', // 当前的表名
 | 
			
		||||
    datas: [],
 | 
			
		||||
    columns: [],
 | 
			
		||||
@@ -105,16 +105,10 @@ const state = reactive({
 | 
			
		||||
    showColumnTip: false,
 | 
			
		||||
    tableHeight: '600',
 | 
			
		||||
    emptyText: '',
 | 
			
		||||
    updatedFields: [] as UpdateFieldsMeta[],// 各个tab表被修改的字段信息
 | 
			
		||||
    updatedFields: [] as UpdateFieldsMeta[], // 各个tab表被修改的字段信息
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const {
 | 
			
		||||
    tableHeight,
 | 
			
		||||
    datas,
 | 
			
		||||
    sortable,
 | 
			
		||||
    loading,
 | 
			
		||||
    showColumnTip,
 | 
			
		||||
} = toRefs(state);
 | 
			
		||||
const { tableHeight, datas } = toRefs(state);
 | 
			
		||||
 | 
			
		||||
watch(props, (newValue: any) => {
 | 
			
		||||
    setState(newValue);
 | 
			
		||||
@@ -123,7 +117,7 @@ watch(props, (newValue: any) => {
 | 
			
		||||
onMounted(async () => {
 | 
			
		||||
    console.log('in DbTable mounted');
 | 
			
		||||
    setState(props);
 | 
			
		||||
})
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const setState = (props: any) => {
 | 
			
		||||
    state.dbId = props.dbId;
 | 
			
		||||
@@ -137,7 +131,7 @@ const setState = (props: any) => {
 | 
			
		||||
    state.columns = props.columns;
 | 
			
		||||
    state.showColumnTip = props.showColumnTip;
 | 
			
		||||
    state.emptyText = props.emptyText;
 | 
			
		||||
}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getColumnTip = (column: any) => {
 | 
			
		||||
    const comment = column.columnComment;
 | 
			
		||||
@@ -181,7 +175,7 @@ const cellClick = (row: any, column: any, cell: any) => {
 | 
			
		||||
            row[property] = input.value;
 | 
			
		||||
            cell.replaceChildren(div);
 | 
			
		||||
            if (input.value !== text) {
 | 
			
		||||
                let currentUpdatedFields = state.updatedFields
 | 
			
		||||
                let currentUpdatedFields = state.updatedFields;
 | 
			
		||||
                const dbInst = getNowDbInst();
 | 
			
		||||
                // 主键
 | 
			
		||||
                const primaryKey = await dbInst.loadTableColumn(state.db, state.table);
 | 
			
		||||
@@ -189,73 +183,75 @@ const cellClick = (row: any, column: any, cell: any) => {
 | 
			
		||||
                // 更新字段列信息
 | 
			
		||||
                const updateColumn = await dbInst.loadTableColumn(state.db, state.table, property);
 | 
			
		||||
                const newField = {
 | 
			
		||||
                    div, row,
 | 
			
		||||
                    div,
 | 
			
		||||
                    row,
 | 
			
		||||
                    fieldName: property,
 | 
			
		||||
                    fieldType: updateColumn.columnType,
 | 
			
		||||
                    oldValue: text,
 | 
			
		||||
                    newValue: input.value
 | 
			
		||||
                    newValue: input.value,
 | 
			
		||||
                } as FieldsMeta;
 | 
			
		||||
 | 
			
		||||
                // 被修改的字段
 | 
			
		||||
                const primaryKeyFields = currentUpdatedFields.filter((meta) => meta.primaryKey === primaryKeyValue)
 | 
			
		||||
                const primaryKeyFields = currentUpdatedFields.filter((meta) => meta.primaryKey === primaryKeyValue);
 | 
			
		||||
                let hasKey = false;
 | 
			
		||||
                if (primaryKeyFields.length <= 0) {
 | 
			
		||||
                    primaryKeyFields[0] = {
 | 
			
		||||
                        primaryKey: primaryKeyValue,
 | 
			
		||||
                        primaryKeyName: primaryKey.columnName,
 | 
			
		||||
                        primaryKeyType: primaryKey.columnType,
 | 
			
		||||
                        fields: [newField]
 | 
			
		||||
                    }
 | 
			
		||||
                        fields: [newField],
 | 
			
		||||
                    };
 | 
			
		||||
                } else {
 | 
			
		||||
                    hasKey = true
 | 
			
		||||
                    let hasField = primaryKeyFields[0].fields.some(a => {
 | 
			
		||||
                    hasKey = true;
 | 
			
		||||
                    let hasField = primaryKeyFields[0].fields.some((a) => {
 | 
			
		||||
                        if (a.fieldName === newField.fieldName) {
 | 
			
		||||
                            a.newValue = newField.newValue
 | 
			
		||||
                            a.newValue = newField.newValue;
 | 
			
		||||
                        }
 | 
			
		||||
                        return a.fieldName === newField.fieldName
 | 
			
		||||
                    })
 | 
			
		||||
                        return a.fieldName === newField.fieldName;
 | 
			
		||||
                    });
 | 
			
		||||
                    if (!hasField) {
 | 
			
		||||
                        primaryKeyFields[0].fields.push(newField)
 | 
			
		||||
                        primaryKeyFields[0].fields.push(newField);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                let fields = primaryKeyFields[0].fields
 | 
			
		||||
                let fields = primaryKeyFields[0].fields;
 | 
			
		||||
 | 
			
		||||
                const fieldsParam = fields.filter((a) => {
 | 
			
		||||
                    if (a.fieldName === column.property) {
 | 
			
		||||
                        a.newValue = input.value
 | 
			
		||||
                        a.newValue = input.value;
 | 
			
		||||
                    }
 | 
			
		||||
                    return a.fieldName === column.property
 | 
			
		||||
                })
 | 
			
		||||
                    return a.fieldName === column.property;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                const field = fieldsParam.length > 0 && fieldsParam[0] || {} as FieldsMeta
 | 
			
		||||
                if (field.oldValue === input.value) { // 新值=旧值
 | 
			
		||||
                const field = (fieldsParam.length > 0 && fieldsParam[0]) || ({} as FieldsMeta);
 | 
			
		||||
                if (field.oldValue === input.value) {
 | 
			
		||||
                    // 新值=旧值
 | 
			
		||||
                    // 删除数据
 | 
			
		||||
                    div.classList.remove('update_field_active')
 | 
			
		||||
                    div.classList.remove('update_field_active');
 | 
			
		||||
                    let delIndex: number[] = [];
 | 
			
		||||
                    currentUpdatedFields.forEach((a, i) => {
 | 
			
		||||
                        if (a.primaryKey === primaryKeyValue) {
 | 
			
		||||
                            a.fields = a.fields && a.fields.length > 0 ? a.fields.filter(f => f.fieldName !== column.property) : [];
 | 
			
		||||
                            a.fields.length <= 0 && delIndex.push(i)
 | 
			
		||||
                            a.fields = a.fields && a.fields.length > 0 ? a.fields.filter((f) => f.fieldName !== column.property) : [];
 | 
			
		||||
                            a.fields.length <= 0 && delIndex.push(i);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                    delIndex.forEach(i => delete currentUpdatedFields[i])
 | 
			
		||||
                    currentUpdatedFields = currentUpdatedFields.filter(a => a)
 | 
			
		||||
                    delIndex.forEach((i) => delete currentUpdatedFields[i]);
 | 
			
		||||
                    currentUpdatedFields = currentUpdatedFields.filter((a) => a);
 | 
			
		||||
                } else {
 | 
			
		||||
                    // 新增数据
 | 
			
		||||
                    div.classList.add('update_field_active')
 | 
			
		||||
                    div.classList.add('update_field_active');
 | 
			
		||||
                    if (hasKey) {
 | 
			
		||||
                        currentUpdatedFields.forEach((value, index, array) => {
 | 
			
		||||
                            if (value.primaryKey === primaryKeyValue) {
 | 
			
		||||
                                array[index].fields = fields
 | 
			
		||||
                                array[index].fields = fields;
 | 
			
		||||
                            }
 | 
			
		||||
                        })
 | 
			
		||||
                        });
 | 
			
		||||
                    } else {
 | 
			
		||||
                        currentUpdatedFields.push({
 | 
			
		||||
                            primaryKey: primaryKeyValue,
 | 
			
		||||
                            primaryKeyName: primaryKey.columnName,
 | 
			
		||||
                            primaryKeyType: primaryKey.columnType,
 | 
			
		||||
                            fields
 | 
			
		||||
                        })
 | 
			
		||||
                            fields,
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                state.updatedFields = currentUpdatedFields;
 | 
			
		||||
@@ -266,7 +262,7 @@ const cellClick = (row: any, column: any, cell: any) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const submitUpdateFields = () => {
 | 
			
		||||
    const dbInst = DbInst.getInst(state.dbId)
 | 
			
		||||
    const dbInst = DbInst.getInst(state.dbId);
 | 
			
		||||
    let currentUpdatedFields = state.updatedFields;
 | 
			
		||||
    if (currentUpdatedFields.length <= 0) {
 | 
			
		||||
        return;
 | 
			
		||||
@@ -274,58 +270,62 @@ const submitUpdateFields = () => {
 | 
			
		||||
    const db = state.db;
 | 
			
		||||
    let res = '';
 | 
			
		||||
    let divs: HTMLElement[] = [];
 | 
			
		||||
    currentUpdatedFields.forEach(a => {
 | 
			
		||||
    currentUpdatedFields.forEach((a) => {
 | 
			
		||||
        let sql = `UPDATE ${dbInst.wrapName(state.table)} SET `;
 | 
			
		||||
        let primaryKey = a.primaryKey;
 | 
			
		||||
        let primaryKeyType = a.primaryKeyType;
 | 
			
		||||
        let primaryKeyName = a.primaryKeyName;
 | 
			
		||||
        a.fields.forEach(f => {
 | 
			
		||||
            sql += ` ${dbInst.wrapName(f.fieldName)} = ${DbInst.wrapColumnValue(f.fieldType, f.newValue)},`
 | 
			
		||||
        a.fields.forEach((f) => {
 | 
			
		||||
            sql += ` ${dbInst.wrapName(f.fieldName)} = ${DbInst.wrapColumnValue(f.fieldType, f.newValue)},`;
 | 
			
		||||
            // 如果修改的字段是主键
 | 
			
		||||
            if (f.fieldName === primaryKeyName) {
 | 
			
		||||
                primaryKey = f.oldValue
 | 
			
		||||
                primaryKey = f.oldValue;
 | 
			
		||||
            }
 | 
			
		||||
            divs.push(f.div)
 | 
			
		||||
        })
 | 
			
		||||
        sql = sql.substring(0, sql.length - 1)
 | 
			
		||||
        sql += ` WHERE ${dbInst.wrapName(primaryKeyName)} = ${DbInst.wrapColumnValue(primaryKeyType, primaryKey)} ;`
 | 
			
		||||
            divs.push(f.div);
 | 
			
		||||
        });
 | 
			
		||||
        sql = sql.substring(0, sql.length - 1);
 | 
			
		||||
        sql += ` WHERE ${dbInst.wrapName(primaryKeyName)} = ${DbInst.wrapColumnValue(primaryKeyType, primaryKey)} ;`;
 | 
			
		||||
        res += sql;
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    dbInst.promptExeSql(db, res, () => { }, () => {
 | 
			
		||||
        currentUpdatedFields = [];
 | 
			
		||||
        divs.forEach(a => {
 | 
			
		||||
            a.classList.remove('update_field_active');
 | 
			
		||||
        })
 | 
			
		||||
        state.updatedFields = [];
 | 
			
		||||
        changeUpdatedField();
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    dbInst.promptExeSql(
 | 
			
		||||
        db,
 | 
			
		||||
        res,
 | 
			
		||||
        () => {},
 | 
			
		||||
        () => {
 | 
			
		||||
            currentUpdatedFields = [];
 | 
			
		||||
            divs.forEach((a) => {
 | 
			
		||||
                a.classList.remove('update_field_active');
 | 
			
		||||
            });
 | 
			
		||||
            state.updatedFields = [];
 | 
			
		||||
            changeUpdatedField();
 | 
			
		||||
        }
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const cancelUpdateFields = () => {
 | 
			
		||||
    state.updatedFields.forEach((a: any) => {
 | 
			
		||||
        a.fields.forEach((b: any) => {
 | 
			
		||||
            b.div.classList.remove('update_field_active')
 | 
			
		||||
            b.row[b.fieldName] = b.oldValue
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
            b.div.classList.remove('update_field_active');
 | 
			
		||||
            b.row[b.fieldName] = b.oldValue;
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    state.updatedFields = [];
 | 
			
		||||
    changeUpdatedField();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const changeUpdatedField = () => {
 | 
			
		||||
    emits('changeUpdatedField', state.updatedFields);
 | 
			
		||||
}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getNowDbInst = () => {
 | 
			
		||||
    return DbInst.getInst(state.dbId);
 | 
			
		||||
}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
defineExpose({
 | 
			
		||||
    submitUpdateFields,
 | 
			
		||||
    cancelUpdateFields
 | 
			
		||||
})
 | 
			
		||||
    cancelUpdateFields,
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
 
 | 
			
		||||
@@ -6,12 +6,12 @@
 | 
			
		||||
                    <el-link @click="onRunSql()" :underline="false" class="ml15" icon="VideoPlay"> </el-link>
 | 
			
		||||
                    <el-divider direction="vertical" border-style="dashed" />
 | 
			
		||||
 | 
			
		||||
                    <el-tooltip class="box-item" effect="dark" content="format sql" placement="top">
 | 
			
		||||
                    <el-tooltip :show-after="1000" class="box-item" effect="dark" content="format sql" placement="top">
 | 
			
		||||
                        <el-link @click="formatSql()" type="primary" :underline="false" icon="MagicStick"> </el-link>
 | 
			
		||||
                    </el-tooltip>
 | 
			
		||||
                    <el-divider direction="vertical" border-style="dashed" />
 | 
			
		||||
 | 
			
		||||
                    <el-tooltip class="box-item" effect="dark" content="commit" placement="top">
 | 
			
		||||
                    <el-tooltip :show-after="1000" class="box-item" effect="dark" content="commit" placement="top">
 | 
			
		||||
                        <el-link @click="onCommit()" type="success" :underline="false" icon="CircleCheck"> </el-link>
 | 
			
		||||
                    </el-tooltip>
 | 
			
		||||
                    <el-divider direction="vertical" border-style="dashed" />
 | 
			
		||||
@@ -27,12 +27,12 @@
 | 
			
		||||
                        multiple
 | 
			
		||||
                        :limit="100"
 | 
			
		||||
                    >
 | 
			
		||||
                        <el-tooltip class="box-item" effect="dark" content="SQL脚本执行" placement="top">
 | 
			
		||||
                        <el-tooltip :show-after="1000" class="box-item" effect="dark" content="SQL脚本执行" placement="top">
 | 
			
		||||
                            <el-link type="success" :underline="false" icon="Document"></el-link>
 | 
			
		||||
                        </el-tooltip>
 | 
			
		||||
                    </el-upload>
 | 
			
		||||
                    <el-divider direction="vertical" border-style="dashed" />
 | 
			
		||||
                    <el-tooltip class="box-item" effect="dark" content="limit" placement="top">
 | 
			
		||||
                    <el-tooltip :show-after="1000" class="box-item" effect="dark" content="limit" placement="top">
 | 
			
		||||
                        <el-link @click="onLimit()" type="success" :underline="false" icon="Operation"> </el-link>
 | 
			
		||||
                    </el-tooltip>
 | 
			
		||||
                </div>
 | 
			
		||||
@@ -153,7 +153,7 @@ const state = reactive({
 | 
			
		||||
    hasUpdatedFileds: false,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const { tableDataHeight, editorHeight, ti, execRes, table, sqlName, loading, hasUpdatedFileds } = toRefs(state);
 | 
			
		||||
const { tableDataHeight, ti, execRes, table, loading, hasUpdatedFileds } = toRefs(state);
 | 
			
		||||
 | 
			
		||||
watch(
 | 
			
		||||
    () => props.editorHeight,
 | 
			
		||||
 
 | 
			
		||||
@@ -74,9 +74,10 @@
 | 
			
		||||
                                :data="columns"
 | 
			
		||||
                                max-height="500"
 | 
			
		||||
                                size="small"
 | 
			
		||||
                                @row-click="(...event: any) => {
 | 
			
		||||
                                onConditionRowClick(event);
 | 
			
		||||
                            }
 | 
			
		||||
                                @row-click="
 | 
			
		||||
                                    (...event: any) => {
 | 
			
		||||
                                        onConditionRowClick(event);
 | 
			
		||||
                                    }
 | 
			
		||||
                                "
 | 
			
		||||
                                style="cursor: pointer"
 | 
			
		||||
                            >
 | 
			
		||||
@@ -153,6 +154,7 @@
 | 
			
		||||
            <el-form ref="dataForm" :model="addDataDialog.data" label-width="auto" size="small">
 | 
			
		||||
                <el-form-item
 | 
			
		||||
                    v-for="column in columns"
 | 
			
		||||
                    :key="column.columnName"
 | 
			
		||||
                    class="w100"
 | 
			
		||||
                    :prop="column.columnName"
 | 
			
		||||
                    :label="column.columnName"
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@
 | 
			
		||||
 | 
			
		||||
            <template #action="{ data }">
 | 
			
		||||
                <span v-auth="'machine:terminal'">
 | 
			
		||||
                    <el-tooltip effect="customized" content="按住ctrl则为新标签打开" placement="top">
 | 
			
		||||
                    <el-tooltip :show-after="500" effect="customized" content="按住ctrl则为新标签打开" placement="top">
 | 
			
		||||
                        <el-button :disabled="data.status == -1" type="primary" @click="showTerminal(data, $event)" link>终端</el-button>
 | 
			
		||||
                    </el-tooltip>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
                <tag-tree @node-click="nodeClick" :load="loadNode">
 | 
			
		||||
                    <template #prefix="{ data }">
 | 
			
		||||
                        <span v-if="data.type == NodeType.Mongo">
 | 
			
		||||
                            <el-popover placement="right-start" title="mongo实例信息" trigger="hover" :width="210">
 | 
			
		||||
                            <el-popover :show-after="500" placement="right-start" title="mongo实例信息" trigger="hover" :width="210">
 | 
			
		||||
                                <template #reference>
 | 
			
		||||
                                    <SvgIcon name="iconfont icon-op-mongo" :size="18" />
 | 
			
		||||
                                </template>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
                        <tag-tree @node-click="nodeClick" :load="loadNode">
 | 
			
		||||
                            <template #prefix="{ data }">
 | 
			
		||||
                                <span v-if="data.type == NodeType.Redis">
 | 
			
		||||
                                    <el-popover placement="right-start" title="redis实例信息" trigger="hover" :width="210">
 | 
			
		||||
                                    <el-popover :show-after="500" placement="right-start" title="redis实例信息" trigger="hover" :width="210">
 | 
			
		||||
                                        <template #reference>
 | 
			
		||||
                                            <SvgIcon name="iconfont icon-op-redis" :size="18" />
 | 
			
		||||
                                        </template>
 | 
			
		||||
@@ -471,7 +471,7 @@ const removeDataTab = (targetName: string) => {
 | 
			
		||||
    delete state.dataTabs[targetName];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const keyTreeNodeExpand = (data: any, node: any, component: any) => {
 | 
			
		||||
const keyTreeNodeExpand = (data: any, node: any) => {
 | 
			
		||||
    state.keyTreeExpanded.add(data.key);
 | 
			
		||||
    // async sort nodes
 | 
			
		||||
    if (!node.customSorted) {
 | 
			
		||||
@@ -480,7 +480,7 @@ const keyTreeNodeExpand = (data: any, node: any, component: any) => {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const keyTreeNodeCollapse = (data: any, node: any, component: any) => {
 | 
			
		||||
const keyTreeNodeCollapse = (data: any) => {
 | 
			
		||||
    state.keyTreeExpanded.delete(data.key);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ func (d *Db) Dbs(rc *req.Ctx) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	queryCond.TagIds = tagIds
 | 
			
		||||
	res, err := d.DbApp.GetPageList(queryCond, page, new([]vo.SelectDataDbVO))
 | 
			
		||||
	res, err := d.DbApp.GetPageList(queryCond, page, new([]vo.DbListVO))
 | 
			
		||||
	biz.ErrIsNil(err)
 | 
			
		||||
	rc.ResData = res
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ type Instance struct {
 | 
			
		||||
// @router /api/instances [get]
 | 
			
		||||
func (d *Instance) Instances(rc *req.Ctx) {
 | 
			
		||||
	queryCond, page := ginx.BindQueryAndPage[*entity.InstanceQuery](rc.GinCtx, new(entity.InstanceQuery))
 | 
			
		||||
	res, err := d.InstanceApp.GetPageList(queryCond, page, new([]vo.SelectDataInstanceVO))
 | 
			
		||||
	res, err := d.InstanceApp.GetPageList(queryCond, page, new([]vo.InstanceListVO))
 | 
			
		||||
	biz.ErrIsNil(err)
 | 
			
		||||
	rc.ResData = res
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,7 @@ package vo
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
type SelectDataDbVO struct {
 | 
			
		||||
	//models.BaseModel
 | 
			
		||||
type DbListVO struct {
 | 
			
		||||
	Id       *int64  `json:"id"`
 | 
			
		||||
	Name     *string `json:"name"`
 | 
			
		||||
	Database *string `json:"database"`
 | 
			
		||||
@@ -14,6 +13,9 @@ type SelectDataDbVO struct {
 | 
			
		||||
	InstanceId   *int64  `json:"instanceId"`
 | 
			
		||||
	InstanceName *string `json:"instanceName"`
 | 
			
		||||
	InstanceType *string `json:"type"`
 | 
			
		||||
	Host         string  `json:"host"`
 | 
			
		||||
	Port         int     `json:"port"`
 | 
			
		||||
	Username     string  `json:"username"`
 | 
			
		||||
 | 
			
		||||
	CreateTime *time.Time `json:"createTime"`
 | 
			
		||||
	Creator    *string    `json:"creator"`
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,7 @@ package vo
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
type SelectDataInstanceVO struct {
 | 
			
		||||
	//models.BaseModel
 | 
			
		||||
type InstanceListVO struct {
 | 
			
		||||
	Id         *int64     `json:"id"`
 | 
			
		||||
	Name       *string    `json:"name"`
 | 
			
		||||
	Host       *string    `json:"host"`
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ func newDbRepo() repository.Db {
 | 
			
		||||
// 分页获取数据库信息列表
 | 
			
		||||
func (d *dbRepoImpl) GetDbList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
 | 
			
		||||
	qd := gormx.NewQueryWithTableName("t_db db").
 | 
			
		||||
		Select("db.*, inst.name instance_name, inst.type instance_type").
 | 
			
		||||
		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).
 | 
			
		||||
		Like("db.database", condition.Database).
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user