fix: 移除隧道连接时检测是否正在使用

This commit is contained in:
meilin.huang
2025-05-26 22:33:51 +08:00
parent d6280ea280
commit e0c01d4561
19 changed files with 314 additions and 161 deletions

View File

@@ -153,7 +153,7 @@
:close-on-click-modal="false"
v-model="sqlExecLogDialog.visible"
:destroy-on-close="true"
body-class="h-250"
body-class="h-[65vh]"
>
<db-sql-exec-log :db-id="sqlExecLogDialog.dbId" :dbs="sqlExecLogDialog.dbs" />
</el-dialog>

View File

@@ -1,28 +1,25 @@
<template>
<div class="db-transfer-file">
<el-dialog :title="title" v-model="dialogVisible" :close-on-click-modal="false" :destroy-on-close="true" width="1000px">
<el-dialog
@open="search()"
:title="title"
v-model="dialogVisible"
:close-on-click-modal="false"
:destroy-on-close="true"
body-class="h-[65vh]"
width="1000px"
>
<page-table
ref="pageTableRef"
:data="state.tableData"
v-model:query-form="state.query"
:page-api="dbApi.dbTransferFileList"
:lazy="true"
:show-selection="true"
v-model:selection-data="state.selectionData"
:columns="columns"
@page-num-change="
(args: any) => {
state.query.pageNum = args.pageNum;
search();
}
"
@page-size-change="
(args: any) => {
state.query.pageSize = args.pageNum;
search();
}
"
>
<template #tableHeader>
<el-button v-auth="perms.del" :disabled="state.selectionData.length < 1" @click="del()" type="danger" icon="delete">
<el-button v-auth="perms.del" :disabled="state.selectionData.length < 1" @click="onDel()" type="danger" icon="delete">
{{ $t('common.delete') }}
</el-button>
</template>
@@ -41,17 +38,20 @@
<template #action="{ data }">
<el-button
v-if="actionBtns[perms.run] && data.status === DbTransferFileStatusEnum.Success.value"
@click="openRun(data)"
@click="onOpenRun(data)"
type="primary"
link
>{{ $t('db.run') }}</el-button
>
<el-button v-if="data.logId" @click="openLog(data)" type="success" link>{{ $t('db.log') }}</el-button>
{{ $t('db.run') }}
</el-button>
<el-button v-if="data.logId" @click="onOpenLog(data)" type="success" link>{{ $t('db.log') }}</el-button>
</template>
</page-table>
<TerminalLog v-model:log-id="state.logsDialog.logId" v-model:visible="state.logsDialog.visible" :title="state.logsDialog.title" />
</el-dialog>
<TerminalLog v-model:log-id="state.logsDialog.logId" v-model:visible="state.logsDialog.visible" :title="state.logsDialog.title" />
<el-dialog :title="state.runDialog.title" v-model="state.runDialog.visible" :destroy-on-close="true" width="600px">
<el-form :model="state.runDialog.runForm" ref="runFormRef" label-width="auto" :rules="state.runDialog.formRules">
<el-form-item :label="$t('db.dbFileType')" prop="dbType">
@@ -70,17 +70,15 @@
</el-form>
<template #footer>
<div>
<el-button @click="state.runDialog.cancel()">{{ $t('common.cancel') }}</el-button>
<el-button type="primary" :loading="state.runDialog.loading" @click="state.runDialog.btnOk">{{ $t('common.confirm') }}</el-button>
</div>
<el-button @click="state.runDialog.onCancel()">{{ $t('common.cancel') }}</el-button>
<el-button type="primary" :loading="state.runDialog.loading" @click="state.runDialog.onConfirm">{{ $t('common.confirm') }}</el-button>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { onMounted, reactive, Ref, ref, watch } from 'vue';
import { onMounted, reactive, Ref, ref, useTemplateRef, watch } from 'vue';
import { dbApi } from '@/views/ops/db/api';
import { getDbDialect } from '@/views/ops/db/dialect';
import PageTable from '@/components/pagetable/PageTable.vue';
@@ -109,6 +107,8 @@ const props = defineProps({
const dialogVisible = defineModel<boolean>('visible', { default: false });
const pageTableRef: Ref<any> = useTemplateRef('pageTableRef');
const columns = ref([
TableColumn.new('fileKey', 'db.file').setMinWidth(280).isSlot(),
TableColumn.new('createTime', 'db.execTime').setMinWidth(180).isTime(),
@@ -168,11 +168,11 @@ const state = reactive({
targetDbType: '',
},
loading: false,
cancel: function () {
onCancel: function () {
state.runDialog.visible = false;
state.runDialog.runForm = {} as any;
},
btnOk: async function () {
onConfirm: async function () {
await useI18nFormValidate(runFormRef);
if (state.runDialog.runForm.targetDbType !== state.runDialog.runForm.dbType) {
ElMessage.warning(t('db.targetDbTypeSelectError', { dbType: state.runDialog.runForm.dbType }));
@@ -181,7 +181,7 @@ const state = reactive({
state.runDialog.runForm.clientId = getClientId();
await dbApi.dbTransferFileRun.request(state.runDialog.runForm);
useI18nOperateSuccessMsg();
state.runDialog.cancel();
state.runDialog.onCancel();
await search();
},
onSelectRunTargetDb: function (param: any) {
@@ -195,14 +195,13 @@ const state = reactive({
});
const search = async () => {
const { total, list } = await dbApi.dbTransferFileList.request(state.query);
state.tableData = list;
pageTableRef.value.total = total;
pageTableRef.value?.search();
// const { total, list } = await dbApi.dbTransferFileList.request(state.query);
// state.tableData = list;
// pageTableRef.value.total = total;
};
const pageTableRef: Ref<any> = ref(null);
const del = async function () {
const onDel = async function () {
try {
await useI18nDeleteConfirm(state.selectionData.map((x: any) => x.fileKey).join('、'));
await dbApi.dbTransferFileDel.request({ fileId: state.selectionData.map((x: any) => x.id).join(',') });
@@ -213,7 +212,7 @@ const del = async function () {
}
};
const openLog = function (data: any) {
const onOpenLog = function (data: any) {
state.logsDialog.logId = data.logId;
state.logsDialog.visible = true;
state.logsDialog.title = t('db.log');
@@ -221,7 +220,7 @@ const openLog = function (data: any) {
};
// 运行sql弹出选择需要运行的库默认运行当前数据库需要保证数据库类型与sql文件一致
const openRun = function (data: any) {
const onOpenRun = function (data: any) {
state.runDialog.runForm = { id: data.id, dbType: data.fileDbType } as any;
state.runDialog.visible = true;
};

View File

@@ -1,10 +1,9 @@
<template>
<el-dialog v-model="visible" :title="title" :destroy-on-close="true" width="600px">
<el-form ref="dataForm" :model="modelValue" :show-message="false" label-width="auto" size="small">
<el-dialog v-model="visible" :title="title" :destroy-on-close="true" width="600px" body-class="h-[65vh] overflow-auto">
<el-form ref="dataForm" :model="modelValue" scroll-to-error :show-message="false" label-width="auto" size="small">
<el-form-item
v-for="column in columns"
:key="column.columnName"
class="mb-1 w-full"
:prop="column.columnName"
:required="props.tableName != '' && !column.nullable && !column.isPrimaryKey && !column.autoIncrement"
>
@@ -24,10 +23,8 @@
</el-form-item>
</el-form>
<template #footer v-if="props.tableName">
<span class="dialog-footer">
<el-button @click="closeDialog">{{ $t('common.cancel') }}</el-button>
<el-button type="primary" @click="confirm">{{ $t('common.confirm') }}</el-button>
</span>
<el-button @click="onCloseDialog">{{ $t('common.cancel') }}</el-button>
<el-button type="primary" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
</template>
</el-dialog>
</template>
@@ -79,12 +76,12 @@ const setOldValue = () => {
}
};
const closeDialog = () => {
const onCloseDialog = () => {
visible.value = false;
modelValue.value = {};
};
const confirm = async () => {
const onConfirm = async () => {
await useI18nFormValidate(dataForm);
const dbInst = props.dbInst;
@@ -107,7 +104,7 @@ const confirm = async () => {
}
dbInst.promptExeSql(db, sql, null, () => {
closeDialog();
onCloseDialog();
emit('submitSuccess');
});
};

View File

@@ -68,7 +68,7 @@
:close-on-click-modal="false"
:modal="false"
@close="closeTermnial"
body-class="h-[560px]"
body-class="h-[65vh]"
draggable
append-to-body
>

View File

@@ -9,7 +9,7 @@
:show-close="true"
:destroy-on-close="true"
width="65%"
body-class="h-200"
body-class="h-[65vh]"
>
<page-table
ref="pageTableRef"

View File

@@ -15,14 +15,14 @@
<template #footer>
<el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
<el-button v-auth="'machine:file:write'" type="primary" @click="updateContent">{{ $t('common.save') }}</el-button>
<el-button v-loading="saveing" v-auth="'machine:file:write'" type="primary" @click="updateContent">{{ $t('common.save') }}</el-button>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { computed, reactive, toRefs, watch } from 'vue';
import { computed, reactive, Ref, ref, toRefs, watch } from 'vue';
import { machineApi } from '../api';
import MonacoEditor from '@/components/monaco/MonacoEditor.vue';
import { useI18nSaveSuccessMsg } from '@/hooks/useI18n';
@@ -42,9 +42,10 @@ const emit = defineEmits(['cancel', 'update:machineId']);
const updateFileContent = machineApi.updateFileContent;
const saveing: Ref<any> = ref(false);
const state = reactive({
loadingContent: false,
content: '',
fileType: '',
});
@@ -83,17 +84,22 @@ const handleClose = () => {
};
const updateContent = async () => {
await updateFileContent.request({
content: state.content,
id: props.fileId,
path: props.path,
machineId: props.machineId,
authCertName: props.authCertName,
protocol: props.protocol,
});
useI18nSaveSuccessMsg();
handleClose();
state.content = '';
try {
saveing.value = true;
await updateFileContent.request({
content: fileContent.value,
id: props.fileId,
path: props.path,
machineId: props.machineId,
authCertName: props.authCertName,
protocol: props.protocol,
});
useI18nSaveSuccessMsg();
handleClose();
fileContent.value = '';
} finally {
saveing.value = false;
}
};
const getFileType = (path: string) => {

View File

@@ -22,9 +22,9 @@
<el-row :gutter="20">
<el-col :lg="12" :md="12">
<el-descriptions class="redis-info info-cluster" :title="$t('redis.node')" :column="3" size="small" border>
<el-descriptions-item :label="$t('redis.clusterEnable')">{{ info.Cluster.cluster_enabled }}</el-descriptions-item>
<el-descriptions-item label="DB">{{ info.Cluster.databases }}</el-descriptions-item>
<el-descriptions-item :label="$t('redis.nodeCount')">{{ info.Cluster.nodecount }}</el-descriptions-item>
<el-descriptions-item :label="$t('redis.clusterEnable')">{{ info.Cluster?.cluster_enabled }}</el-descriptions-item>
<el-descriptions-item label="DB">{{ info.Cluster?.databases }}</el-descriptions-item>
<el-descriptions-item :label="$t('redis.nodeCount')">{{ info.Cluster?.nodecount }}</el-descriptions-item>
</el-descriptions>
</el-col>