diff --git a/mayfly_go_web/src/views/ops/db/DbEdit.vue b/mayfly_go_web/src/views/ops/db/DbEdit.vue
index aa67b2bc..95a56889 100644
--- a/mayfly_go_web/src/views/ops/db/DbEdit.vue
+++ b/mayfly_go_web/src/views/ops/db/DbEdit.vue
@@ -292,10 +292,7 @@ export default defineComponent({
emit('cancel');
setTimeout(() => {
resetInputDb();
- dbForm.value.resetFields();
- // 重置对象属性为null
- state.form = {} as any;
- }, 200);
+ }, 500);
};
return {
diff --git a/mayfly_go_web/src/views/ops/db/DbList.vue b/mayfly_go_web/src/views/ops/db/DbList.vue
index 5fb7b658..9871f270 100644
--- a/mayfly_go_web/src/views/ops/db/DbList.vue
+++ b/mayfly_go_web/src/views/ops/db/DbList.vue
@@ -59,8 +59,11 @@
-
+
+
+ SQL执行记录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UPDATE
+ DELETE
+ INSERT
+
+
+
+
+
+
+
+ {{ $filters.dateFormat(scope.row.createTime) }}
+
+
+
+
+
+
+
+
+
@@ -195,7 +246,18 @@ export default defineComponent({
},
datas: [],
total: 0,
-
+ // sql执行记录弹框
+ sqlExecLogDialog: {
+ title: '',
+ visible: false,
+ data: [],
+ total: 0,
+ query: {
+ dbId: 0,
+ pageNum: 1,
+ pageSize: 12,
+ },
+ },
chooseTableName: '',
tableInfoDialog: {
visible: false,
@@ -284,6 +346,32 @@ export default defineComponent({
} catch (err) {}
};
+ const onShowSqlExec = async (row: any) => {
+ state.sqlExecLogDialog.title = `${row.name}[${row.host}:${row.port}]`;
+ state.sqlExecLogDialog.query.dbId = row.id;
+ searchSqlExecLog();
+ state.sqlExecLogDialog.visible = true;
+ };
+
+ const onBeforeCloseSqlExecDialog = () => {
+ state.sqlExecLogDialog.visible = false;
+ state.sqlExecLogDialog.data = [];
+ state.sqlExecLogDialog.total = 0;
+ state.sqlExecLogDialog.query.dbId = 0;
+ state.sqlExecLogDialog.query.pageNum = 1;
+ };
+
+ const searchSqlExecLog = async () => {
+ const res = await dbApi.getSqlExecs.request(state.sqlExecLogDialog.query);
+ state.sqlExecLogDialog.data = res.list;
+ state.sqlExecLogDialog.total = res.total;
+ };
+
+ const handleSqlExecPageChange = (curPage: number) => {
+ state.sqlExecLogDialog.query.pageNum = curPage;
+ searchSqlExecLog();
+ };
+
const showTableInfo = async (row: any, db: string) => {
state.tableInfoDialog.infos = await dbApi.tableInfos.request({ id: row.id, db });
state.dbId = row.id;
@@ -360,6 +448,10 @@ export default defineComponent({
editDb,
valChange,
deleteDb,
+ onShowSqlExec,
+ onBeforeCloseSqlExecDialog,
+ handleSqlExecPageChange,
+ searchSqlExecLog,
showTableInfo,
closeTableInfo,
showColumns,
diff --git a/mayfly_go_web/src/views/ops/db/SqlExec.vue b/mayfly_go_web/src/views/ops/db/SqlExec.vue
index eee6c4a8..a7a18595 100644
--- a/mayfly_go_web/src/views/ops/db/SqlExec.vue
+++ b/mayfly_go_web/src/views/ops/db/SqlExec.vue
@@ -239,7 +239,6 @@ import 'codemirror/theme/base16-light.css';
import 'codemirror/addon/selection/active-line';
import _CodeMirror from 'codemirror';
-// import 'codemirror/mode/sql/sql.js';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/sql-hint.js';
@@ -390,7 +389,44 @@ export default defineComponent({
let sql = getSql();
isTrue(sql && sql.trim(), '请选中需要执行的sql');
- state.queryTab.loading = true;
+ // 去除字符串前的空格、换行等
+ sql = sql.replace(/(^\s*)/g, '');
+ let execRemark = '';
+ let canRun = true;
+ if (
+ sql.startsWith('update') ||
+ sql.startsWith('UPDATE') ||
+ sql.startsWith('INSERT') ||
+ sql.startsWith('insert') ||
+ sql.startsWith('DELETE') ||
+ sql.startsWith('delete')
+ ) {
+ const res: any = await ElMessageBox.prompt('请输入备注', 'Tip', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/,
+ inputErrorMessage: '请输入执行该sql的备注信息',
+ });
+ execRemark = res.value;
+ if (!execRemark) {
+ canRun = false;
+ }
+ }
+ if (!canRun) {
+ return;
+ }
+
+ try {
+ state.queryTab.loading = true;
+ const colAndData: any = await runSql(sql, execRemark);
+ state.queryTab.execRes.data = colAndData.res;
+ state.queryTab.execRes.tableColumn = colAndData.colNames;
+ state.queryTab.loading = false;
+ } catch (e: any) {
+ state.queryTab.loading = false;
+ }
+ closeExecBtns();
+
// 即只有以该字符串开头的sql才可修改表数据内容
if (sql.startsWith('SELECT *') || sql.startsWith('select *') || sql.startsWith('SELECT\n *')) {
state.queryTab.selectionDatas = [];
@@ -407,16 +443,6 @@ export default defineComponent({
state.queryTab.nowTableName = '';
state.nowTableName = '';
}
-
- try {
- const colAndData: any = await runSql(sql);
- state.queryTab.execRes.data = colAndData.res;
- state.queryTab.execRes.tableColumn = colAndData.colNames;
- state.queryTab.loading = false;
- } catch (e: any) {
- state.queryTab.loading = false;
- }
- closeExecBtns();
};
/**
@@ -424,12 +450,40 @@ export default defineComponent({
*
* @param sql 执行的sql
*/
- const runSql = (sql: string) => {
- return dbApi.sqlExec.request({
+ const runSql = async (sql: string, remark: string = '') => {
+ return await dbApi.sqlExec.request({
id: state.dbId,
db: state.db,
sql: sql.trim(),
+ remark,
});
+ // const sqlTrim = sql.trim();
+ // let remark = '';
+ // let canRun = true;
+ // const needRemark = ['update', 'UPDATE', 'delete', 'DELETE', 'INSERT', 'insert'].indexOf(sqlTrim.split(' ')[0]);
+ // if (needRemark) {
+ // const res: any = await ElMessageBox.prompt('请输入备注', 'Tip', {
+ // confirmButtonText: '确定',
+ // cancelButtonText: '取消',
+ // });
+ // remark = res.value;
+ // if (!remark) {
+ // canRun = false;
+ // }
+ // }
+
+ // if (!canRun) {
+ // return;
+ // }
+ // try {
+ // state.queryTab.loading = true;
+ // return await dbApi.sqlExec.request({
+ // id: state.dbId,
+ // db: state.db,
+ // sql: sqlTrim,
+ // remark,
+ // });
+ // } catch (e: any) {}
};
const removeDataTab = (targetName: string) => {
@@ -497,8 +551,9 @@ export default defineComponent({
if (flag === 'equal') {
// 获取该列中第一个不为空的数据(内容)
for (let i = 0; i < tableData.length; i++) {
- if (tableData[i][str].length > 0) {
- columnContent = tableData[i][str];
+ // 转为字符串后比较
+ if ((tableData[i][str] + '').length > 0) {
+ columnContent = tableData[i][str] + '';
break;
}
}
@@ -515,7 +570,7 @@ export default defineComponent({
index = i;
}
}
- columnContent = tableData[index][str];
+ columnContent = tableData[index][str] + '';
}
const contentWidth: number = getContentWidth(columnContent);
// 获取列名称的长度 加上排序图标长度
@@ -899,7 +954,8 @@ export default defineComponent({
if (!state.nowTableName || !property) {
return;
}
- let text = row[property];
+ // 转为字符串比较,可能存在数字等
+ let text = row[property] + '';
let div = cell.children[0];
if (div) {
let input = document.createElement('input');
diff --git a/mayfly_go_web/src/views/ops/db/api.ts b/mayfly_go_web/src/views/ops/db/api.ts
index 3c7173a3..ffe31bc7 100644
--- a/mayfly_go_web/src/views/ops/db/api.ts
+++ b/mayfly_go_web/src/views/ops/db/api.ts
@@ -12,7 +12,7 @@ export const dbApi = {
columnMetadata: Api.create("/dbs/{id}/c-metadata", 'get'),
// 获取表即列提示
hintTables: Api.create("/dbs/{id}/hint-tables", 'get'),
- sqlExec: Api.create("/dbs/{id}/exec-sql", 'get'),
+ sqlExec: Api.create("/dbs/{id}/exec-sql", 'post'),
// 保存sql
saveSql: Api.create("/dbs/{id}/sql", 'post'),
// 获取保存的sql
@@ -20,4 +20,6 @@ export const dbApi = {
// 获取保存的sql names
getSqlNames: Api.create("/dbs/{id}/sql-names", 'get'),
deleteDbSql: Api.create("/dbs/{id}/sql", 'delete'),
+ // 获取数据库sql执行记录
+ getSqlExecs: Api.create("/dbs/{id}/sql-execs", 'get'),
}
\ No newline at end of file
diff --git a/mayfly_go_web/src/views/ops/db/component/SqlExecDialog.vue b/mayfly_go_web/src/views/ops/db/component/SqlExecDialog.vue
index 0bb39e91..c00b3ea2 100644
--- a/mayfly_go_web/src/views/ops/db/component/SqlExecDialog.vue
+++ b/mayfly_go_web/src/views/ops/db/component/SqlExecDialog.vue
@@ -1,6 +1,7 @@
+