diff --git a/mayfly_go_web/src/common/Api.ts b/mayfly_go_web/src/common/Api.ts index 80232cce..b66493cb 100644 --- a/mayfly_go_web/src/common/Api.ts +++ b/mayfly_go_web/src/common/Api.ts @@ -1,4 +1,5 @@ import request from './request'; +import { randomUuid } from './utils/string'; /** * 可用于各模块定义各自api请求 @@ -20,6 +21,8 @@ class Api { */ beforeHandler: Function; + static abortControllers: Map = new Map(); + constructor(url: string, method: string) { this.url = url; this.method = method; @@ -53,8 +56,63 @@ class Api { return request.request(this.method, this.url, param, headers, options); } + /** + * 请求对应的该api + * @param {Object} param 请求该api的参数 + */ + requestCanCancel(key: string, param: any = null, options: any = null, headers: any = null): Promise { + let controller = Api.abortControllers.get(key); + if (!controller) { + controller = new AbortController(); + Api.abortControllers.set(key, controller); + } + if (options) { + options.signal = controller.signal; + } else { + options = { + signal: controller.signal, + }; + } + + return this.request(param, options, headers); + } + /** 静态方法 **/ + /** + * 取消请求 + * @param key 请求key + */ + static cancelReq(key: string) { + let controller = Api.abortControllers.get(key); + if (controller) { + controller.abort(); + Api.removeAbortKey(key); + } + } + + static removeAbortKey(key: string) { + if (key) { + console.log('remove abort key: ', key); + Api.abortControllers.delete(key); + } + } + + /** + * 根据旧key生成新的abort key,可能旧key未取消,造成多余无用对象 + * @param oldKey 旧key + * @returns key + */ + static genAbortKey(oldKey: string) { + if (!oldKey) { + return randomUuid(); + } + if (Api.abortControllers.get(oldKey)) { + return oldKey; + } + return randomUuid(); + } + /** * 静态工厂,返回Api对象,并设置url与method属性 * @param url url diff --git a/mayfly_go_web/src/common/request.ts b/mayfly_go_web/src/common/request.ts index 370ab98c..b55fc039 100755 --- a/mayfly_go_web/src/common/request.ts +++ b/mayfly_go_web/src/common/request.ts @@ -4,6 +4,7 @@ import config from './config'; import { getClientId, getToken } from './utils/storage'; import { templateResolve } from './utils/string'; import { ElMessage } from 'element-plus'; +import axios from 'axios'; export interface Result { /** @@ -67,21 +68,26 @@ service.interceptors.request.use( service.interceptors.response.use( (response) => { // 获取请求返回结果 - const data: Result = response.data; - if (data.code === ResultEnum.SUCCESS) { - return data.data; + const res: Result = response.data; + if (res.code === ResultEnum.SUCCESS) { + return res.data; } // 如果提示没有权限,则移除token,使其重新登录 - if (data.code === ResultEnum.NO_PERMISSION) { + if (res.code === ResultEnum.NO_PERMISSION) { router.push({ path: '/401', }); } - return Promise.reject(data); + return Promise.reject(res); }, (e: any) => { const rejectPromise = Promise.reject(e); + if (axios.isCancel(e)) { + console.log('请求已取消'); + return rejectPromise; + } + const statusCode = e.response?.status; if (statusCode == 500) { notifyErrorMsg('服务器未知异常'); diff --git a/mayfly_go_web/src/views/ops/db/api.ts b/mayfly_go_web/src/views/ops/db/api.ts index bfc8e2b3..bbcc42c9 100644 --- a/mayfly_go_web/src/views/ops/db/api.ts +++ b/mayfly_go_web/src/views/ops/db/api.ts @@ -21,6 +21,7 @@ export const dbApi = { param.sql = Base64.encode(param.sql); } }), + sqlExecCancel: Api.newPost('/dbs/{id}/exec-sql/cancel/{execId}'), // 保存sql saveSql: Api.newPost('/dbs/{id}/sql'), // 获取保存的sql diff --git a/mayfly_go_web/src/views/ops/db/component/sqleditor/DbSqlEditor.vue b/mayfly_go_web/src/views/ops/db/component/sqleditor/DbSqlEditor.vue index 7e701312..6f8f3d01 100644 --- a/mayfly_go_web/src/views/ops/db/component/sqleditor/DbSqlEditor.vue +++ b/mayfly_go_web/src/views/ops/db/component/sqleditor/DbSqlEditor.vue @@ -103,6 +103,7 @@ :table="dt.table" :columns="dt.tableColumn" :loading="dt.loading" + :loading-key="dt.loadingKey" :height="tableDataHeight" empty-text="tips: select *开头的单表查询或点击表名默认查询的数据,可双击数据在线修改" @change-updated-field="changeUpdatedField($event, dt)" @@ -139,6 +140,7 @@ import { ElNotification } from 'element-plus'; import syssocket from '@/common/syssocket'; import SvgIcon from '@/components/svgIcon/index.vue'; import { getDbDialect } from '../../dialect'; +import { randomUuid } from '@/common/utils/string'; const emits = defineEmits(['saveSqlSuccess']); @@ -171,6 +173,8 @@ class ExecResTab { loading: boolean; + loadingKey: string; + dbTableRef: any; tableColumn: any[] = []; @@ -341,7 +345,10 @@ const onRunSql = async (newTab = false) => { execRes.errorMsg = ''; execRes.sql = ''; - const colAndData: any = await getNowDbInst().runSql(props.dbName, sql, execRemark); + const loadingKey = randomUuid(); + execRes.loadingKey = loadingKey; + + const colAndData: any = await getNowDbInst().runSql(props.dbName, sql, execRemark, loadingKey); if (!colAndData.res || colAndData.res.length === 0) { ElMessage.warning('未查询到结果集'); } diff --git a/mayfly_go_web/src/views/ops/db/component/table/DbTableData.vue b/mayfly_go_web/src/views/ops/db/component/table/DbTableData.vue index 484ee032..f3e0e844 100644 --- a/mayfly_go_web/src/views/ops/db/component/table/DbTableData.vue +++ b/mayfly_go_web/src/views/ops/db/component/table/DbTableData.vue @@ -90,9 +90,14 @@ -