mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	feat: 日常优化
This commit is contained in:
		@@ -5,17 +5,71 @@
 | 
			
		||||
 */
 | 
			
		||||
export function formatByteSize(size: any) {
 | 
			
		||||
    const value = Number(size);
 | 
			
		||||
        if (size && !isNaN(value)) {
 | 
			
		||||
            const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'BB'];
 | 
			
		||||
            let index = 0;
 | 
			
		||||
            let k = value;
 | 
			
		||||
            if (value >= 1024) {
 | 
			
		||||
                while (k > 1024) {
 | 
			
		||||
                    k = k / 1024;
 | 
			
		||||
                    index++;
 | 
			
		||||
                }
 | 
			
		||||
    if (size && !isNaN(value)) {
 | 
			
		||||
        const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'BB'];
 | 
			
		||||
        let index = 0;
 | 
			
		||||
        let k = value;
 | 
			
		||||
        if (value >= 1024) {
 | 
			
		||||
            while (k > 1024) {
 | 
			
		||||
                k = k / 1024;
 | 
			
		||||
                index++;
 | 
			
		||||
            }
 | 
			
		||||
            return `${k.toFixed(2)}${units[index]}`;
 | 
			
		||||
        }
 | 
			
		||||
        return '-';
 | 
			
		||||
        return `${k.toFixed(2)}${units[index]}`;
 | 
			
		||||
    }
 | 
			
		||||
    return '-';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 格式化json字符串
 | 
			
		||||
 * @param txt  json字符串
 | 
			
		||||
 * @param compress 是否压缩
 | 
			
		||||
 * @returns 格式化后的字符串
 | 
			
		||||
 */
 | 
			
		||||
export function formatJsonString(txt: string, compress: boolean) {
 | 
			
		||||
    var indentChar = '    ';
 | 
			
		||||
    if (/^\s*$/.test(txt)) {
 | 
			
		||||
        console.log('数据为空,无法格式化! ');
 | 
			
		||||
        return txt;
 | 
			
		||||
    }
 | 
			
		||||
    try {
 | 
			
		||||
        var data = JSON.parse(txt);
 | 
			
		||||
    } catch (e: any) {
 | 
			
		||||
        console.log('数据源语法错误,格式化失败! 错误信息: ' + e.description, 'err');
 | 
			
		||||
        return txt;
 | 
			
		||||
    }
 | 
			
		||||
    var draw: any = [],
 | 
			
		||||
        line = compress ? '' : '\n',
 | 
			
		||||
        // eslint-disable-next-line no-unused-vars
 | 
			
		||||
        nodeCount: number = 0,
 | 
			
		||||
        // eslint-disable-next-line no-unused-vars
 | 
			
		||||
        maxDepth: number = 0;
 | 
			
		||||
 | 
			
		||||
    var notify = function (name: any, value: any, isLast: any, indent: any, formObj: any) {
 | 
			
		||||
        nodeCount++; /*节点计数*/
 | 
			
		||||
        for (var i = 0, tab = ''; i < indent; i++) tab += indentChar; /* 缩进HTML */
 | 
			
		||||
        tab = compress ? '' : tab; /*压缩模式忽略缩进*/
 | 
			
		||||
        maxDepth = ++indent; /*缩进递增并记录*/
 | 
			
		||||
        if (value && value.constructor == Array) {
 | 
			
		||||
            /*处理数组*/
 | 
			
		||||
            draw.push(tab + (formObj ? '"' + name + '": ' : '') + '[' + line); /*缩进'[' 然后换行*/
 | 
			
		||||
            for (var i = 0; i < value.length; i++) notify(i, value[i], i == value.length - 1, indent, false);
 | 
			
		||||
            draw.push(tab + ']' + (isLast ? line : ',' + line)); /*缩进']'换行,若非尾元素则添加逗号*/
 | 
			
		||||
        } else if (value && typeof value == 'object') {
 | 
			
		||||
            /*处理对象*/
 | 
			
		||||
            draw.push(tab + (formObj ? '"' + name + '": ' : '') + '{' + line); /*缩进'{' 然后换行*/
 | 
			
		||||
            var len = 0,
 | 
			
		||||
                i = 0;
 | 
			
		||||
            for (var key in value) len++;
 | 
			
		||||
            for (var key in value) notify(key, value[key], ++i == len, indent, true);
 | 
			
		||||
            draw.push(tab + '}' + (isLast ? line : ',' + line)); /*缩进'}'换行,若非尾元素则添加逗号*/
 | 
			
		||||
        } else {
 | 
			
		||||
            if (typeof value == 'string') value = '"' + value + '"';
 | 
			
		||||
            draw.push(tab + (formObj ? '"' + name + '": ' : '') + value + (isLast ? '' : ',') + line);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    var isLast = true,
 | 
			
		||||
        indent = 0;
 | 
			
		||||
    notify('', data, isLast, indent, false);
 | 
			
		||||
    return draw.join('');
 | 
			
		||||
}
 | 
			
		||||
@@ -46,7 +46,7 @@ import { ElOption, ElSelect } from 'element-plus';
 | 
			
		||||
const CodeMirror = (window as any).CodeMirror || _CodeMirror;
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
    name: 'codemirror',
 | 
			
		||||
    name: 'CodeMirror',
 | 
			
		||||
     components: {
 | 
			
		||||
        ElOption,
 | 
			
		||||
        ElSelect,
 | 
			
		||||
@@ -173,7 +173,7 @@ export default defineComponent({
 | 
			
		||||
 | 
			
		||||
        watch(
 | 
			
		||||
            () => props.modelValue,
 | 
			
		||||
            (newValue, oldValue) => {
 | 
			
		||||
            (newValue) => {
 | 
			
		||||
                handerCodeChange(newValue);
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
 
 | 
			
		||||
@@ -22,9 +22,7 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { ref, toRefs, reactive, watch, defineComponent, onMounted } from 'vue';
 | 
			
		||||
import { ElMessage } from 'element-plus';
 | 
			
		||||
import { notEmpty } from '@/common/assert';
 | 
			
		||||
import { toRefs, reactive, watch, defineComponent, onMounted } from 'vue';
 | 
			
		||||
import { projectApi } from '../project/api';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
 
 | 
			
		||||
@@ -26,45 +26,26 @@
 | 
			
		||||
                    <el-tab-pane label="字段" name="1">
 | 
			
		||||
                        <el-table :data="tableData.fields.res">
 | 
			
		||||
                            <el-table-column :prop="item.prop" :label="item.label" v-for="item in tableData.fields.colNames" :key="item.prop">
 | 
			
		||||
                                <template v-if="item.prop === 'name'" #default="scope">
 | 
			
		||||
                                    <el-input size="small" v-model="scope.row.name"></el-input>
 | 
			
		||||
                                </template>
 | 
			
		||||
                                <!--eslint-disable-next-line-->
 | 
			
		||||
                                <template v-if="item.prop === 'type'" #default="scope">
 | 
			
		||||
                                    <el-select filterable size="small" v-model="scope.row.type">
 | 
			
		||||
                                <template #default="scope">
 | 
			
		||||
                                    <el-input v-if="item.prop === 'name'" size="small" v-model="scope.row.name"></el-input>
 | 
			
		||||
 | 
			
		||||
                                    <el-select v-if="item.prop === 'type'" filterable size="small" v-model="scope.row.type">
 | 
			
		||||
                                        <el-option v-for="typeValue in typeList" :key="typeValue" :value="typeValue">{{ typeValue }}</el-option>
 | 
			
		||||
                                    </el-select>
 | 
			
		||||
                                </template>
 | 
			
		||||
                                <!--eslint-disable-next-line-->
 | 
			
		||||
                                <template v-if="item.prop === 'value'" #default="scope">
 | 
			
		||||
                                    <el-input size="small" v-model="scope.row.value"> </el-input>
 | 
			
		||||
                                </template>
 | 
			
		||||
                                <!--eslint-disable-next-line-->
 | 
			
		||||
                                <template v-if="item.prop === 'length'" #default="scope">
 | 
			
		||||
                                    <el-input size="small" v-model="scope.row.length"> </el-input>
 | 
			
		||||
                                </template>
 | 
			
		||||
                                <!--eslint-disable-next-line-->
 | 
			
		||||
                                <template v-if="item.prop === 'notNull'" #default="scope">
 | 
			
		||||
                                    <el-checkbox size="small" v-model="scope.row.notNull"> </el-checkbox>
 | 
			
		||||
                                </template>
 | 
			
		||||
                                <!--eslint-disable-next-line-->
 | 
			
		||||
                                <template v-if="item.prop === 'pri'" #default="scope">
 | 
			
		||||
                                    <el-checkbox size="small" v-model="scope.row.pri"> </el-checkbox>
 | 
			
		||||
                                </template>
 | 
			
		||||
                                <!--eslint-disable-next-line-->
 | 
			
		||||
                                <template v-if="item.prop === 'auto_increment'" #default="scope">
 | 
			
		||||
                                    <el-checkbox size="small" v-model="scope.row.auto_increment"> </el-checkbox>
 | 
			
		||||
                                </template>
 | 
			
		||||
                                <!-- <template v-if="item.prop === 'un_signed'" #default="scope">
 | 
			
		||||
                                    <el-checkbox :disabled="scope.row.type === 'int'" size="small" v-model="scope.row.un_signed"> </el-checkbox>
 | 
			
		||||
                                </template> -->
 | 
			
		||||
                                <!--eslint-disable-next-line-->
 | 
			
		||||
                                <template v-if="item.prop === 'remark'" #default="scope">
 | 
			
		||||
                                    <el-input size="small" v-model="scope.row.remark"> </el-input>
 | 
			
		||||
                                </template>
 | 
			
		||||
                                <!--eslint-disable-next-line-->
 | 
			
		||||
                                <template v-if="item.prop === 'action'" #default="scope">
 | 
			
		||||
                                    <el-button type="text" size="small" @click.prevent="deleteRow(scope.$index)">删除</el-button>
 | 
			
		||||
 | 
			
		||||
                                    <el-input v-if="item.prop === 'value'" size="small" v-model="scope.row.value"> </el-input>
 | 
			
		||||
 | 
			
		||||
                                    <el-input v-if="item.prop === 'length'" size="small" v-model="scope.row.length"> </el-input>
 | 
			
		||||
 | 
			
		||||
                                    <el-checkbox v-if="item.prop === 'notNull'" size="small" v-model="scope.row.notNull"> </el-checkbox>
 | 
			
		||||
 | 
			
		||||
                                    <el-checkbox v-if="item.prop === 'pri'" size="small" v-model="scope.row.pri"> </el-checkbox>
 | 
			
		||||
 | 
			
		||||
                                     <el-checkbox v-if="item.prop === 'auto_increment'" size="small" v-model="scope.row.auto_increment"> </el-checkbox>
 | 
			
		||||
 | 
			
		||||
                                     <el-input v-if="item.prop === 'remark'" size="small" v-model="scope.row.remark"> </el-input>
 | 
			
		||||
 | 
			
		||||
                                     <el-button v-if="item.prop === 'action'" type="text" size="small" @click.prevent="deleteRow(scope.$index)">删除</el-button>
 | 
			
		||||
                                </template>
 | 
			
		||||
                            </el-table-column>
 | 
			
		||||
                        </el-table>
 | 
			
		||||
@@ -85,8 +66,8 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { watch, toRefs, reactive, defineComponent, ref, getCurrentInstance } from 'vue';
 | 
			
		||||
import { TYPE_LIST, CHARACTER_SET_NAME_LIST } from './service.ts';
 | 
			
		||||
import { dbApi } from '../../db/api';
 | 
			
		||||
import { ElMessage } from 'element-plus';
 | 
			
		||||
import SqlExecBox from './component/SqlExecBox.ts';
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
    name: 'createTable',
 | 
			
		||||
    props: {
 | 
			
		||||
@@ -178,6 +159,7 @@ export default defineComponent({
 | 
			
		||||
        });
 | 
			
		||||
        const cancel = () => {
 | 
			
		||||
            emit('update:visible', false);
 | 
			
		||||
            reset();
 | 
			
		||||
        };
 | 
			
		||||
        const addRow = () => {
 | 
			
		||||
            state.tableData.fields.res.push({
 | 
			
		||||
@@ -196,39 +178,36 @@ export default defineComponent({
 | 
			
		||||
        };
 | 
			
		||||
        const submit = async () => {
 | 
			
		||||
            let data = state.tableData;
 | 
			
		||||
            let str = '';
 | 
			
		||||
            let primary_key = '';
 | 
			
		||||
            let fields: string[] = [];
 | 
			
		||||
            data.fields.res.forEach((item) => {
 | 
			
		||||
                str += `\`${item.name}\` ${item.type}${+item.length > 0 ? `(${item.length})` : ''} ${item.notNull ? 'NOT NULL' : ''} ${
 | 
			
		||||
                    item.auto_increment ? 'AUTO_INCREMENT' : ''
 | 
			
		||||
                } ${item.value ? 'DEFAULT ' + item.value : item.notNull ? '' : 'DEFAULT NULL'} ${item.remark ? `COMMENT '${item.remark}'` : ''},\n`;
 | 
			
		||||
                fields.push(
 | 
			
		||||
                    `${item.name} ${item.type}${+item.length > 0 ? `(${item.length})` : ''} ${item.notNull ? 'NOT NULL' : ''} ${
 | 
			
		||||
                        item.auto_increment ? 'AUTO_INCREMENT' : ''
 | 
			
		||||
                    } ${item.value ? 'DEFAULT ' + item.value : item.notNull ? '' : 'DEFAULT NULL'} ${
 | 
			
		||||
                        item.remark ? `COMMENT '${item.remark}'` : ''
 | 
			
		||||
                    } \n`
 | 
			
		||||
                );
 | 
			
		||||
                if (item.pri) {
 | 
			
		||||
                    primary_key += `\`${item.name}\`,`;
 | 
			
		||||
                    primary_key += `${item.name},`;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            let sql = `
 | 
			
		||||
                CREATE TABLE \`${data.tableName}\` (
 | 
			
		||||
                ${str}
 | 
			
		||||
                PRIMARY KEY (${primary_key.slice(0, -1)})
 | 
			
		||||
                CREATE TABLE ${data.tableName} (
 | 
			
		||||
                ${fields.join(',')}
 | 
			
		||||
                ${primary_key ? `, PRIMARY KEY (${primary_key.slice(0, -1)})` : ''}
 | 
			
		||||
                ) ENGINE=InnoDB DEFAULT CHARSET=${data.characterSet} COLLATE=utf8mb4_bin COMMENT='${data.tableComment}';`;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                state.btnloading = true;
 | 
			
		||||
                const res = await dbApi.sqlExec.request({
 | 
			
		||||
                    id: props.dbId,
 | 
			
		||||
                    sql: sql,
 | 
			
		||||
                });
 | 
			
		||||
                state.btnloading = false;
 | 
			
		||||
                ElMessage.success('创建成功');
 | 
			
		||||
                proxy.$parent.tableInfo({ id: props.dbId });
 | 
			
		||||
                reset();
 | 
			
		||||
                cancel();
 | 
			
		||||
            } catch (err) {
 | 
			
		||||
                console.error(err);
 | 
			
		||||
                state.btnloading = false;
 | 
			
		||||
                ElMessage.error('创建失败');
 | 
			
		||||
            }
 | 
			
		||||
            SqlExecBox({
 | 
			
		||||
                sql: sql,
 | 
			
		||||
                dbId: props.dbId as any,
 | 
			
		||||
                runSuccessCallback: () => {
 | 
			
		||||
                    ElMessage.success('创建成功');
 | 
			
		||||
                    proxy.$parent.tableInfo({ id: props.dbId });
 | 
			
		||||
                    cancel();
 | 
			
		||||
                },
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
        const reset = () => {
 | 
			
		||||
            formRef.value.resetFields();
 | 
			
		||||
@@ -114,6 +114,11 @@
 | 
			
		||||
                        <el-link class="ml5" @click.prevent="showCreateDdl(scope.row)" type="info">SQL</el-link>
 | 
			
		||||
                    </template>
 | 
			
		||||
                </el-table-column>
 | 
			
		||||
                <el-table-column label="操作" min-width="80">
 | 
			
		||||
                    <template #default="scope">
 | 
			
		||||
                        <el-link @click.prevent="dropTable(scope.row)" type="danger">删除</el-link>
 | 
			
		||||
                    </template>
 | 
			
		||||
                </el-table-column>
 | 
			
		||||
            </el-table>
 | 
			
		||||
        </el-dialog>
 | 
			
		||||
 | 
			
		||||
@@ -155,9 +160,10 @@ import { toRefs, reactive, onMounted, defineComponent } from 'vue';
 | 
			
		||||
import { ElMessage, ElMessageBox } from 'element-plus';
 | 
			
		||||
import { formatByteSize } from '@/common/utils/format';
 | 
			
		||||
import DbEdit from './DbEdit.vue';
 | 
			
		||||
import CreateTable from '../component/Table/CreateTable.vue';
 | 
			
		||||
import CreateTable from './CreateTable.vue';
 | 
			
		||||
import { dbApi } from './api';
 | 
			
		||||
import { projectApi } from '../project/api.ts';
 | 
			
		||||
import SqlExecBox from './component/SqlExecBox.ts';
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
    name: 'DbList',
 | 
			
		||||
    components: {
 | 
			
		||||
@@ -306,10 +312,30 @@ export default defineComponent({
 | 
			
		||||
                tableName: row.tableName,
 | 
			
		||||
            });
 | 
			
		||||
            state.ddlDialog.ddl = res[0]['Create Table'];
 | 
			
		||||
            console.log(state.ddlDialog);
 | 
			
		||||
            state.ddlDialog.visible = true;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 删除表
 | 
			
		||||
         */
 | 
			
		||||
        const dropTable = async (row: any) => {
 | 
			
		||||
            try {
 | 
			
		||||
                const tableName = row.tableName;
 | 
			
		||||
                await ElMessageBox.confirm(`确定删除'${tableName}'表?`, '提示', {
 | 
			
		||||
                    confirmButtonText: '确定',
 | 
			
		||||
                    cancelButtonText: '取消',
 | 
			
		||||
                    type: 'warning',
 | 
			
		||||
                });
 | 
			
		||||
                SqlExecBox({
 | 
			
		||||
                    sql: `DROP TABLE ${tableName}`,
 | 
			
		||||
                    dbId: state.chooseId,
 | 
			
		||||
                    runSuccessCallback: async () => {
 | 
			
		||||
                        state.tableInfoDialog.infos = await dbApi.tableInfos.request({ id: state.chooseId });
 | 
			
		||||
                    },
 | 
			
		||||
                });
 | 
			
		||||
            } catch (err) {}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            ...toRefs(state),
 | 
			
		||||
            // enums,
 | 
			
		||||
@@ -324,6 +350,7 @@ export default defineComponent({
 | 
			
		||||
            showColumns,
 | 
			
		||||
            showTableIndex,
 | 
			
		||||
            showCreateDdl,
 | 
			
		||||
            dropTable,
 | 
			
		||||
            formatByteSize,
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -196,7 +196,7 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { h, toRefs, reactive, computed, defineComponent, ref } from 'vue';
 | 
			
		||||
import { toRefs, reactive, computed, defineComponent, ref } from 'vue';
 | 
			
		||||
import { dbApi } from './api';
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
@@ -218,7 +218,7 @@ import { ElMessage, ElMessageBox } from 'element-plus';
 | 
			
		||||
import ProjectEnvSelect from '../component/ProjectEnvSelect.vue';
 | 
			
		||||
import config from '@/common/config';
 | 
			
		||||
import { getSession } from '@/common/utils/storage';
 | 
			
		||||
import SqlExecBox from './SqlExecBox';
 | 
			
		||||
import SqlExecBox from './component/SqlExecBox';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
    name: 'SqlExec',
 | 
			
		||||
@@ -828,8 +828,8 @@ export default defineComponent({
 | 
			
		||||
 | 
			
		||||
        // 添加新数据行
 | 
			
		||||
        const addRow = async () => {
 | 
			
		||||
            const tableNmae = state.nowTableName;
 | 
			
		||||
            const columns = await getColumns(tableNmae);
 | 
			
		||||
            const tableName = state.nowTableName;
 | 
			
		||||
            const columns = await getColumns(tableName);
 | 
			
		||||
 | 
			
		||||
            // key: 字段名,value: 字段名提示
 | 
			
		||||
            let obj: any = {};
 | 
			
		||||
@@ -840,7 +840,7 @@ export default defineComponent({
 | 
			
		||||
            let values = Object.values(obj).join(',');
 | 
			
		||||
            let sql = `INSERT INTO ${state.nowTableName} (${columnNames}) VALUES (${values});`;
 | 
			
		||||
            promptExeSql(sql, null, () => {
 | 
			
		||||
                onRefresh(tableNmae);
 | 
			
		||||
                onRefresh(tableName);
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ export type SqlExecProps = {
 | 
			
		||||
    cancelCallback?: Function
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const boxId = 'Sql-Exec-ID'
 | 
			
		||||
const boxId = 'sql-exec-id'
 | 
			
		||||
 | 
			
		||||
const renderBox = (): VNode => {
 | 
			
		||||
    const props: SqlExecProps = {
 | 
			
		||||
@@ -32,7 +32,7 @@ let boxInstance: any
 | 
			
		||||
const SqlExecBox = (props: SqlExecProps): void => {
 | 
			
		||||
    if (boxInstance) {
 | 
			
		||||
        const boxVue = boxInstance.component
 | 
			
		||||
        // 调用open方法显示弹框
 | 
			
		||||
        // 调用open方法显示弹框,注意不能使用boxVue.ctx来调用组件函数(build打包后ctx会获取不到)
 | 
			
		||||
        boxVue.proxy.open(props);
 | 
			
		||||
    } else {
 | 
			
		||||
        boxInstance = renderBox()
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { toRefs, reactive, defineComponent } from 'vue';
 | 
			
		||||
import { dbApi } from './api';
 | 
			
		||||
import { dbApi } from '../api';
 | 
			
		||||
import { ElDialog, ElButton } from 'element-plus';
 | 
			
		||||
// import base style
 | 
			
		||||
import 'codemirror/lib/codemirror.css';
 | 
			
		||||
@@ -71,6 +71,7 @@ export default defineComponent({
 | 
			
		||||
         */
 | 
			
		||||
        const runSql = async () => {
 | 
			
		||||
            try {
 | 
			
		||||
                state.btnLoading = true;
 | 
			
		||||
                await dbApi.sqlExec.request({
 | 
			
		||||
                    id: state.dbId,
 | 
			
		||||
                    sql: state.sql.trim(),
 | 
			
		||||
@@ -79,9 +80,10 @@ export default defineComponent({
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
                runSuccess = false;
 | 
			
		||||
            }
 | 
			
		||||
            if (runSuccessCallback) {
 | 
			
		||||
            if (runSuccess && runSuccessCallback) {
 | 
			
		||||
                runSuccessCallback();
 | 
			
		||||
            }
 | 
			
		||||
            state.btnLoading = false;
 | 
			
		||||
            cancel();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import SshTerminal from './SshTerminal.vue';
 | 
			
		||||
import { reactive, toRefs, onBeforeMount, defineComponent, onMounted } from 'vue';
 | 
			
		||||
import { reactive, toRefs, defineComponent, onMounted } from 'vue';
 | 
			
		||||
import { useRoute } from 'vue-router';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
                    icon="edit"
 | 
			
		||||
                    >编辑</el-button
 | 
			
		||||
                >
 | 
			
		||||
                <el-button @click="showMembers(chooseData)" :disabled="chooseId == null" type="success" icon="setting">成员管理</el-button>
 | 
			
		||||
                <el-button @click="showMembers(chooseData)" :disabled="chooseId == null" type="success" icon="user">成员管理</el-button>
 | 
			
		||||
 | 
			
		||||
                <el-button @click="showEnv(chooseData)" :disabled="chooseId == null" type="info" icon="setting">环境管理</el-button>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,13 +2,13 @@
 | 
			
		||||
    <el-dialog :title="title" v-model="dialogVisible" :before-close="cancel" :show-close="false" width="750px" :destroy-on-close="true">
 | 
			
		||||
        <el-form label-width="85px">
 | 
			
		||||
            <el-form-item prop="key" label="key:">
 | 
			
		||||
                <el-input :disabled="operationType == 2" v-model="keyInfo.key"></el-input>
 | 
			
		||||
                <el-input :disabled="operationType == 2" v-model="key.key"></el-input>
 | 
			
		||||
            </el-form-item>
 | 
			
		||||
            <el-form-item prop="timed" label="过期时间:">
 | 
			
		||||
                <el-input v-model.number="keyInfo.timed" type="number"></el-input>
 | 
			
		||||
                <el-input v-model.number="key.timed" type="number"></el-input>
 | 
			
		||||
            </el-form-item>
 | 
			
		||||
            <el-form-item prop="dataType" label="数据类型:">
 | 
			
		||||
                <el-select :disabled="operationType == 2" style="width: 100%" v-model="keyInfo.type" placeholder="请选择数据类型">
 | 
			
		||||
                <el-select :disabled="operationType == 2" style="width: 100%" v-model="key.type" placeholder="请选择数据类型">
 | 
			
		||||
                    <el-option key="string" label="string" value="string"> </el-option>
 | 
			
		||||
                    <el-option key="hash" label="hash" value="hash"> </el-option>
 | 
			
		||||
                    <el-option key="set" label="set" value="set"> </el-option>
 | 
			
		||||
@@ -16,7 +16,13 @@
 | 
			
		||||
            </el-form-item>
 | 
			
		||||
 | 
			
		||||
            <el-form-item v-if="keyInfo.type == 'string'" prop="value" label="内容:">
 | 
			
		||||
                <el-input class="json-text" v-model="stringValue" type="textarea" :autosize="{ minRows: 10, maxRows: 20 }"></el-input>
 | 
			
		||||
                <div id="string-value-text" style="width: 100%">
 | 
			
		||||
                    <el-input class="json-text" v-model="string.value" type="textarea" :autosize="{ minRows: 10, maxRows: 20 }"></el-input>
 | 
			
		||||
                    <el-select class="text-type-select" @change="onChangeTextType" v-model="string.type">
 | 
			
		||||
                        <el-option key="text" label="text" value="text"> </el-option>
 | 
			
		||||
                        <el-option key="json" label="json" value="json"> </el-option>
 | 
			
		||||
                    </el-select>
 | 
			
		||||
                </div>
 | 
			
		||||
            </el-form-item>
 | 
			
		||||
 | 
			
		||||
            <span v-if="keyInfo.type == 'hash'">
 | 
			
		||||
@@ -40,7 +46,7 @@
 | 
			
		||||
                    </el-table-column>
 | 
			
		||||
                    <el-table-column label="操作" width="90">
 | 
			
		||||
                        <template #default="scope">
 | 
			
		||||
                            <el-button type="danger" @click="hashValue.splice(scope.$index, 1)" icon="delete" size="small" plain>删除</el-button>
 | 
			
		||||
                            <el-button type="danger" @click="hash.value.splice(scope.$index, 1)" icon="delete" size="small" plain>删除</el-button>
 | 
			
		||||
                        </template>
 | 
			
		||||
                    </el-table-column>
 | 
			
		||||
                </el-table>
 | 
			
		||||
@@ -49,8 +55,8 @@
 | 
			
		||||
            <span v-if="keyInfo.type == 'set'">
 | 
			
		||||
                <el-button @click="onAddSetValue" icon="plus" size="small" plain class="mt10">添加</el-button>
 | 
			
		||||
                <el-table :data="setValue" stripe style="width: 100%">
 | 
			
		||||
                    <el-table-column prop="value" label="value" width>
 | 
			
		||||
                        <template #default="scope" min-width="200">
 | 
			
		||||
                    <el-table-column prop="value" label="value" min-width="200">
 | 
			
		||||
                        <template #default="scope">
 | 
			
		||||
                            <el-input
 | 
			
		||||
                                v-model="scope.row.value"
 | 
			
		||||
                                clearable
 | 
			
		||||
@@ -62,7 +68,7 @@
 | 
			
		||||
                    </el-table-column>
 | 
			
		||||
                    <el-table-column label="操作" width="90">
 | 
			
		||||
                        <template #default="scope">
 | 
			
		||||
                            <el-button type="danger" @click="setValue.splice(scope.$index, 1)" icon="delete" size="small" plain>删除</el-button>
 | 
			
		||||
                            <el-button type="danger" @click="set.value.splice(scope.$index, 1)" icon="delete" size="small" plain>删除</el-button>
 | 
			
		||||
                        </template>
 | 
			
		||||
                    </el-table-column>
 | 
			
		||||
                </el-table>
 | 
			
		||||
@@ -81,6 +87,7 @@ import { defineComponent, reactive, watch, toRefs } from 'vue';
 | 
			
		||||
import { redisApi } from './api';
 | 
			
		||||
import { ElMessage } from 'element-plus';
 | 
			
		||||
import { isTrue, notEmpty } from '@/common/assert';
 | 
			
		||||
import { formatJsonString } from '@/common/utils/format';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
    name: 'DateEdit',
 | 
			
		||||
@@ -119,32 +126,40 @@ export default defineComponent({
 | 
			
		||||
            dialogVisible: false,
 | 
			
		||||
            operationType: 1,
 | 
			
		||||
            redisId: '',
 | 
			
		||||
            keyInfo: {
 | 
			
		||||
            key: {
 | 
			
		||||
                key: '',
 | 
			
		||||
                type: 'string',
 | 
			
		||||
                timed: -1,
 | 
			
		||||
            },
 | 
			
		||||
            stringValue: '',
 | 
			
		||||
            hashValue: [
 | 
			
		||||
                {
 | 
			
		||||
                    key: '',
 | 
			
		||||
                    value: '',
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
            setValue: [{ value: '' }],
 | 
			
		||||
            string: {
 | 
			
		||||
                type: 'text',
 | 
			
		||||
                value: '',
 | 
			
		||||
            },
 | 
			
		||||
            hash: {
 | 
			
		||||
                value: [
 | 
			
		||||
                    {
 | 
			
		||||
                        key: '',
 | 
			
		||||
                        value: '',
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
            },
 | 
			
		||||
            set: {
 | 
			
		||||
                value: [{ value: '' }],
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        const cancel = () => {
 | 
			
		||||
            emit('update:visible', false);
 | 
			
		||||
            emit('cancel');
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
                state.keyInfo = {
 | 
			
		||||
                state.key = {
 | 
			
		||||
                    key: '',
 | 
			
		||||
                    type: 'string',
 | 
			
		||||
                    timed: -1,
 | 
			
		||||
                };
 | 
			
		||||
                state.stringValue = '';
 | 
			
		||||
                state.hashValue = [
 | 
			
		||||
                state.string.value = '';
 | 
			
		||||
                state.string.type = 'text';
 | 
			
		||||
                state.hash.value = [
 | 
			
		||||
                    {
 | 
			
		||||
                        key: '',
 | 
			
		||||
                        value: '',
 | 
			
		||||
@@ -178,7 +193,7 @@ export default defineComponent({
 | 
			
		||||
            () => props.keyInfo,
 | 
			
		||||
            (val) => {
 | 
			
		||||
                if (val) {
 | 
			
		||||
                    state.keyInfo = { ...val };
 | 
			
		||||
                    state.key = { ...val };
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
@@ -190,7 +205,7 @@ export default defineComponent({
 | 
			
		||||
            () => props.stringValue,
 | 
			
		||||
            (val) => {
 | 
			
		||||
                if (val) {
 | 
			
		||||
                    state.stringValue = val;
 | 
			
		||||
                    state.string.value = val;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
@@ -202,7 +217,7 @@ export default defineComponent({
 | 
			
		||||
            () => props.setValue,
 | 
			
		||||
            (val) => {
 | 
			
		||||
                if (val) {
 | 
			
		||||
                    state.setValue = val;
 | 
			
		||||
                    state.set.value = val;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
@@ -214,7 +229,7 @@ export default defineComponent({
 | 
			
		||||
            () => props.hashValue,
 | 
			
		||||
            (val) => {
 | 
			
		||||
                if (val) {
 | 
			
		||||
                    state.hashValue = val;
 | 
			
		||||
                    state.hash.value = val;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
@@ -223,26 +238,26 @@ export default defineComponent({
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const saveValue = async () => {
 | 
			
		||||
            notEmpty(state.keyInfo.key, 'key不能为空');
 | 
			
		||||
            notEmpty(state.key.key, 'key不能为空');
 | 
			
		||||
 | 
			
		||||
            if (state.keyInfo.type == 'string') {
 | 
			
		||||
                notEmpty(state.stringValue, 'value不能为空');
 | 
			
		||||
                const sv = { value: state.stringValue, id: state.redisId };
 | 
			
		||||
                Object.assign(sv, state.keyInfo);
 | 
			
		||||
            if (state.key.type == 'string') {
 | 
			
		||||
                notEmpty(state.string.value, 'value不能为空');
 | 
			
		||||
                const sv = { value: formatJsonString(state.string.value, true), id: state.redisId };
 | 
			
		||||
                Object.assign(sv, state.key);
 | 
			
		||||
                await redisApi.saveStringValue.request(sv);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (state.keyInfo.type == 'hash') {
 | 
			
		||||
                isTrue(state.hashValue.length > 0, 'hash内容不能为空');
 | 
			
		||||
                const sv = { value: state.hashValue, id: state.redisId };
 | 
			
		||||
                Object.assign(sv, state.keyInfo);
 | 
			
		||||
            if (state.key.type == 'hash') {
 | 
			
		||||
                isTrue(state.hash.value.length > 0, 'hash内容不能为空');
 | 
			
		||||
                const sv = { value: state.hash.value, id: state.redisId };
 | 
			
		||||
                Object.assign(sv, state.key);
 | 
			
		||||
                await redisApi.saveHashValue.request(sv);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (state.keyInfo.type == 'set') {
 | 
			
		||||
                isTrue(state.setValue.length > 0, 'set内容不能为空');
 | 
			
		||||
                const sv = { value: state.setValue.map((x) => x.value), id: state.redisId };
 | 
			
		||||
                Object.assign(sv, state.keyInfo);
 | 
			
		||||
            if (state.key.type == 'set') {
 | 
			
		||||
                isTrue(state.set.value.length > 0, 'set内容不能为空');
 | 
			
		||||
                const sv = { value: state.set.value.map((x) => x.value), id: state.redisId };
 | 
			
		||||
                Object.assign(sv, state.key);
 | 
			
		||||
                await redisApi.saveSetValue.request(sv);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -252,11 +267,22 @@ export default defineComponent({
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const onAddHashValue = () => {
 | 
			
		||||
            state.hashValue.push({ key: '', value: '' });
 | 
			
		||||
            state.hash.value.push({ key: '', value: '' });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const onAddSetValue = () => {
 | 
			
		||||
            state.setValue.push({ value: '' });
 | 
			
		||||
            state.set.value.push({ value: '' });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // 更改文本类型
 | 
			
		||||
        const onChangeTextType = (val: string) => {
 | 
			
		||||
            if (val == 'json') {
 | 
			
		||||
                state.string.value = formatJsonString(state.string.value, false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (val == 'text') {
 | 
			
		||||
                state.string.value = formatJsonString(state.string.value, true);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
@@ -265,7 +291,23 @@ export default defineComponent({
 | 
			
		||||
            cancel,
 | 
			
		||||
            onAddHashValue,
 | 
			
		||||
            onAddSetValue,
 | 
			
		||||
            onChangeTextType,
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
#string-value-text {
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    position: relative;
 | 
			
		||||
 | 
			
		||||
    .text-type-select {
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        z-index: 2;
 | 
			
		||||
        right: 10px;
 | 
			
		||||
        top: 10px;
 | 
			
		||||
        max-width: 70px;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
                            <el-form-item label="key" label-width="40px">
 | 
			
		||||
                                <el-input
 | 
			
		||||
                                    placeholder="支持*模糊key"
 | 
			
		||||
                                    style="width: 180px"
 | 
			
		||||
                                    style="width: 240px"
 | 
			
		||||
                                    v-model="scanParam.match"
 | 
			
		||||
                                    @clear="clear()"
 | 
			
		||||
                                    clearable
 | 
			
		||||
@@ -83,7 +83,6 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import ValueDialog from './ValueDialog.vue';
 | 
			
		||||
import { redisApi } from './api';
 | 
			
		||||
import { toRefs, reactive, defineComponent } from 'vue';
 | 
			
		||||
import { ElMessage, ElMessageBox } from 'element-plus';
 | 
			
		||||
@@ -94,7 +93,6 @@ import { isTrue, notNull } from '@/common/assert';
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
    name: 'DataOperation',
 | 
			
		||||
    components: {
 | 
			
		||||
        ValueDialog,
 | 
			
		||||
        DataEdit,
 | 
			
		||||
        ProjectEnvSelect,
 | 
			
		||||
    },
 | 
			
		||||
@@ -106,11 +104,6 @@ export default defineComponent({
 | 
			
		||||
            query: {
 | 
			
		||||
                envId: 0,
 | 
			
		||||
            },
 | 
			
		||||
            // redis: {
 | 
			
		||||
            //     id: 0,
 | 
			
		||||
            //     info: '',
 | 
			
		||||
            //     conf: '',
 | 
			
		||||
            // },
 | 
			
		||||
            scanParam: {
 | 
			
		||||
                id: null,
 | 
			
		||||
                cluster: 0,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user