mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
feat: 数据库表格重构
This commit is contained in:
@@ -116,7 +116,7 @@ const loadTableData = async (inst: any, schema: string, tableName: string) => {
|
|||||||
tab.dbType = inst.type;
|
tab.dbType = inst.type;
|
||||||
tab.db = schema;
|
tab.db = schema;
|
||||||
tab.type = TabType.TableData;
|
tab.type = TabType.TableData;
|
||||||
tab.other = {
|
tab.params = {
|
||||||
table: tableName
|
table: tableName
|
||||||
}
|
}
|
||||||
state.tabs.set(label, tab)
|
state.tabs.set(label, tab)
|
||||||
@@ -136,7 +136,7 @@ const addQueryTab = async (inst: any, db: string, sqlName: string = '') => {
|
|||||||
} else {
|
} else {
|
||||||
let count = 1;
|
let count = 1;
|
||||||
state.tabs.forEach((v) => {
|
state.tabs.forEach((v) => {
|
||||||
if (v.type == TabType.Query && !v.other.sqlName) {
|
if (v.type == TabType.Query && !v.params.sqlName) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -153,7 +153,7 @@ const addQueryTab = async (inst: any, db: string, sqlName: string = '') => {
|
|||||||
tab.dbType = inst.type;
|
tab.dbType = inst.type;
|
||||||
tab.db = db;
|
tab.db = db;
|
||||||
tab.type = TabType.Query;
|
tab.type = TabType.Query;
|
||||||
tab.other = {
|
tab.params = {
|
||||||
sqlName: sqlName,
|
sqlName: sqlName,
|
||||||
dbs: instanceTreeRef.value.getSchemas(dbId)
|
dbs: instanceTreeRef.value.getSchemas(dbId)
|
||||||
}
|
}
|
||||||
@@ -258,7 +258,7 @@ const registerSqlCompletionItemProvider = () => {
|
|||||||
const tokens = textBeforePointer.trim().split(/\s+/)
|
const tokens = textBeforePointer.trim().split(/\s+/)
|
||||||
const lastToken = tokens[tokens.length - 1].toLowerCase()
|
const lastToken = tokens[tokens.length - 1].toLowerCase()
|
||||||
|
|
||||||
const dbs = nowTab.other && nowTab.other.dbs;
|
const dbs = nowTab.params && nowTab.params.dbs;
|
||||||
// console.log("光标前文本:=>" + textBeforePointerMulti)
|
// console.log("光标前文本:=>" + textBeforePointerMulti)
|
||||||
|
|
||||||
// console.log("最后输入的:=>" + lastToken)
|
// console.log("最后输入的:=>" + lastToken)
|
||||||
@@ -290,14 +290,6 @@ const registerSqlCompletionItemProvider = () => {
|
|||||||
if (tableInfo.tableName) {
|
if (tableInfo.tableName) {
|
||||||
let table = tableInfo.tableName
|
let table = tableInfo.tableName
|
||||||
let db = tableInfo.dbName;
|
let db = tableInfo.dbName;
|
||||||
// // 取出表名并提示
|
|
||||||
// let dbs = state.monacoOptions.dbTables[dbId + db]
|
|
||||||
// let columns = dbs ? (dbs[table] || []) : [];
|
|
||||||
// if ((!columns || columns.length === 0) && db) {
|
|
||||||
// state.monacoOptions.dbTables[dbId + db] = await loadHintTables(dbId, db)
|
|
||||||
// dbs = state.monacoOptions.dbTables[dbId + db]
|
|
||||||
// columns = dbs ? (dbs[table] || []) : [];
|
|
||||||
// }
|
|
||||||
// 取出表名并提示
|
// 取出表名并提示
|
||||||
let dbHits = await dbInst.loadDbHints(db)
|
let dbHits = await dbInst.loadDbHints(db)
|
||||||
let columns = dbHits[table]
|
let columns = dbHits[table]
|
||||||
|
|||||||
323
mayfly_go_web/src/views/ops/db/component/DbTable.vue
Normal file
323
mayfly_go_web/src/views/ops/db/component/DbTable.vue
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-table @cell-dblclick="(row: any, column: any, cell: any, event: any) => cellClick(row, column, cell)"
|
||||||
|
@sort-change="(sort: any) => onTableSortChange(sort)" @selection-change="onDataSelectionChange"
|
||||||
|
:data="datas" size="small" :max-height="tableHeight" v-loading="loading" element-loading-text="查询中..."
|
||||||
|
:empty-text="emptyText" stripe border class="mt5">
|
||||||
|
<el-table-column v-if="datas.length > 0 && table" type="selection" width="35" />
|
||||||
|
<el-table-column min-width="100" :width="DbInst.flexColumnWidth(item, datas)" align="center"
|
||||||
|
v-for="item in columnNames" :key="item" :prop="item" :label="item" show-overflow-tooltip
|
||||||
|
:sortable="sortable">
|
||||||
|
<template #header v-if="showColumnTip">
|
||||||
|
<el-tooltip raw-content placement="top" effect="customized">
|
||||||
|
<template #content> {{ getColumnTip(item) }} </template>
|
||||||
|
{{ item }}
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, watch, reactive, toRefs } from 'vue';
|
||||||
|
import { DbInst, UpdateFieldsMeta, FieldsMeta } from '../db';
|
||||||
|
|
||||||
|
const emits = defineEmits(['sortChange', 'deleteData', 'selectionChange', 'changeUpdatedField'])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
dbId: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
dbType: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
db: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
columnNames: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
sortable: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
emptyText: {
|
||||||
|
type: String,
|
||||||
|
default: '暂无数据',
|
||||||
|
},
|
||||||
|
showColumnTip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: String,
|
||||||
|
default: '600'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
dbId: 0, // 当前选中操作的数据库实例
|
||||||
|
dbType: '',
|
||||||
|
db: '', // 数据库名
|
||||||
|
table: '', // 当前的表名
|
||||||
|
datas: [],
|
||||||
|
columnNames: [],
|
||||||
|
columns: [],
|
||||||
|
sortable: false,
|
||||||
|
loading: false,
|
||||||
|
selectionDatas: [] as any,
|
||||||
|
showColumnTip: false,
|
||||||
|
tableHeight: '600',
|
||||||
|
emptyText: '',
|
||||||
|
updatedFields: [] as UpdateFieldsMeta[],// 各个tab表被修改的字段信息
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
tableHeight,
|
||||||
|
datas,
|
||||||
|
sortable,
|
||||||
|
loading,
|
||||||
|
columnNames,
|
||||||
|
showColumnTip,
|
||||||
|
} = toRefs(state);
|
||||||
|
|
||||||
|
watch(props, (newValue: any) => {
|
||||||
|
setState(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
console.log('in DbTable mounted');
|
||||||
|
setState(props);
|
||||||
|
})
|
||||||
|
|
||||||
|
const setState = (props: any) => {
|
||||||
|
state.dbId = props.dbId;
|
||||||
|
state.dbType = props.dbType;
|
||||||
|
state.db = props.db;
|
||||||
|
state.table = props.table;
|
||||||
|
state.datas = props.data;
|
||||||
|
state.tableHeight = props.height;
|
||||||
|
state.sortable = props.sortable;
|
||||||
|
state.loading = props.loading;
|
||||||
|
state.columnNames = props.columnNames;
|
||||||
|
state.showColumnTip = props.showColumnTip;
|
||||||
|
state.emptyText = props.emptyText;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getColumnTip = (columnName: string) => {
|
||||||
|
// 优先从 table map中获取
|
||||||
|
let columns = getNowDb().getColumns(state.table);
|
||||||
|
if (!columns) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const column = columns.find((c: any) => c.columnName == columnName);
|
||||||
|
const comment = column.columnComment;
|
||||||
|
return `${column.columnType} ${comment ? ' | ' + comment : ''}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表排序字段变更
|
||||||
|
*/
|
||||||
|
const onTableSortChange = async (sort: any) => {
|
||||||
|
if (!sort.prop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cancelUpdateFields();
|
||||||
|
emits('sortChange', sort);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDataSelectionChange = (datas: []) => {
|
||||||
|
state.selectionDatas = datas;
|
||||||
|
emits('selectionChange', datas);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听单元格点击事件
|
||||||
|
const cellClick = (row: any, column: any, cell: any) => {
|
||||||
|
const property = column.property;
|
||||||
|
// 如果当前操作的表名不存在 或者 当前列的property不存在(如多选框),则不允许修改当前单元格内容
|
||||||
|
if (!state.table || !property) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let div: HTMLElement = cell.children[0];
|
||||||
|
if (div && div.tagName === 'DIV') {
|
||||||
|
// 转为字符串比较,可能存在数字等
|
||||||
|
let text = (row[property] || row[property] == 0 ? row[property] : '') + '';
|
||||||
|
let input = document.createElement('input');
|
||||||
|
input.setAttribute('value', text);
|
||||||
|
// 将表格width也赋值于输入框,避免输入框长度超过表格长度
|
||||||
|
input.setAttribute('style', 'height:23px;text-align:center;border:none;' + div.getAttribute('style'));
|
||||||
|
cell.replaceChildren(input);
|
||||||
|
input.focus();
|
||||||
|
input.addEventListener('blur', async () => {
|
||||||
|
row[property] = input.value;
|
||||||
|
cell.replaceChildren(div);
|
||||||
|
if (input.value !== text) {
|
||||||
|
let currentUpdatedFields = state.updatedFields
|
||||||
|
const dbInst = getNowDbInst();
|
||||||
|
// 主键
|
||||||
|
const primaryKey = await dbInst.loadTableColumn(state.db, state.table);
|
||||||
|
const primaryKeyValue = row[primaryKey.columnName];
|
||||||
|
// 更新字段列信息
|
||||||
|
const updateColumn = await dbInst.loadTableColumn(state.db, state.table, property);
|
||||||
|
const newField = {
|
||||||
|
div, row,
|
||||||
|
fieldName: column.rawColumnKey,
|
||||||
|
fieldType: updateColumn.columnType,
|
||||||
|
oldValue: text,
|
||||||
|
newValue: input.value
|
||||||
|
} as FieldsMeta;
|
||||||
|
|
||||||
|
// 被修改的字段
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasKey = true
|
||||||
|
let hasField = primaryKeyFields[0].fields.some(a => {
|
||||||
|
if (a.fieldName === newField.fieldName) {
|
||||||
|
a.newValue = newField.newValue
|
||||||
|
}
|
||||||
|
return a.fieldName === newField.fieldName
|
||||||
|
})
|
||||||
|
if (!hasField) {
|
||||||
|
primaryKeyFields[0].fields.push(newField)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let fields = primaryKeyFields[0].fields
|
||||||
|
|
||||||
|
const fieldsParam = fields.filter((a) => {
|
||||||
|
if (a.fieldName === column.rawColumnKey) {
|
||||||
|
a.newValue = input.value
|
||||||
|
}
|
||||||
|
return a.fieldName === column.rawColumnKey
|
||||||
|
})
|
||||||
|
|
||||||
|
const field = fieldsParam.length > 0 && fieldsParam[0] || {} as FieldsMeta
|
||||||
|
if (field.oldValue === input.value) { // 新值=旧值
|
||||||
|
// 删除数据
|
||||||
|
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.rawColumnKey) : [];
|
||||||
|
a.fields.length <= 0 && delIndex.push(i)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
delIndex.forEach(i => delete currentUpdatedFields[i])
|
||||||
|
currentUpdatedFields = currentUpdatedFields.filter(a => a)
|
||||||
|
} else {
|
||||||
|
// 新增数据
|
||||||
|
div.classList.add('update_field_active')
|
||||||
|
if (hasKey) {
|
||||||
|
currentUpdatedFields.forEach((value, index, array) => {
|
||||||
|
if (value.primaryKey === primaryKeyValue) {
|
||||||
|
array[index].fields = fields
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
currentUpdatedFields.push({
|
||||||
|
primaryKey: primaryKeyValue,
|
||||||
|
primaryKeyName: primaryKey.columnName,
|
||||||
|
primaryKeyType: primaryKey.columnType,
|
||||||
|
fields
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.updatedFields = currentUpdatedFields;
|
||||||
|
changeUpdatedField();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitUpdateFields = () => {
|
||||||
|
let currentUpdatedFields = state.updatedFields;
|
||||||
|
if (currentUpdatedFields.length <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const db = state.db;
|
||||||
|
let res = '';
|
||||||
|
let divs: HTMLElement[] = [];
|
||||||
|
currentUpdatedFields.forEach(a => {
|
||||||
|
let sql = `UPDATE ${state.table} SET `;
|
||||||
|
let primaryKey = a.primaryKey;
|
||||||
|
let primaryKeyType = a.primaryKeyType;
|
||||||
|
let primaryKeyName = a.primaryKeyName;
|
||||||
|
a.fields.forEach(f => {
|
||||||
|
sql += ` ${f.fieldName} = ${DbInst.wrapColumnValue(f.fieldType, f.newValue)},`
|
||||||
|
divs.push(f.div)
|
||||||
|
})
|
||||||
|
sql = sql.substring(0, sql.length - 1)
|
||||||
|
sql += ` WHERE ${primaryKeyName} = ${DbInst.wrapColumnValue(primaryKeyType, primaryKey)} ;`
|
||||||
|
res += sql;
|
||||||
|
})
|
||||||
|
|
||||||
|
DbInst.getInst(state.dbId).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
|
||||||
|
})
|
||||||
|
})
|
||||||
|
state.updatedFields = [];
|
||||||
|
changeUpdatedField();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const changeUpdatedField = () => {
|
||||||
|
emits('changeUpdatedField', state.updatedFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getNowDb = () => {
|
||||||
|
return DbInst.getInst(state.dbId).getDb(state.db);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getNowDbInst = () => {
|
||||||
|
return DbInst.getInst(state.dbId, state.dbType);
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
submitUpdateFields,
|
||||||
|
cancelUpdateFields
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.update_field_active {
|
||||||
|
background-color: var(--el-color-success)
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -51,33 +51,28 @@
|
|||||||
<el-link type="success" :underline="false" @click="exportData"><span
|
<el-link type="success" :underline="false" @click="exportData"><span
|
||||||
style="font-size: 12px">导出</span></el-link>
|
style="font-size: 12px">导出</span></el-link>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="updatedFields.length > 0">
|
<span v-if="hasUpdatedFileds">
|
||||||
<el-divider direction="vertical" border-style="dashed" />
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
<el-link type="success" :underline="false" @click="submitUpdateFields()"><span
|
<el-link type="success" :underline="false" @click="submitUpdateFields()"><span
|
||||||
style="font-size: 12px">提交</span></el-link>
|
style="font-size: 12px">提交</span></el-link>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="updatedFields.length > 0">
|
<span v-if="hasUpdatedFileds">
|
||||||
<el-divider direction="vertical" border-style="dashed" />
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
<el-link type="warning" :underline="false" @click="cancelUpdateFields"><span
|
<el-link type="warning" :underline="false" @click="cancelUpdateFields"><span
|
||||||
style="font-size: 12px">取消</span></el-link>
|
style="font-size: 12px">取消</span></el-link>
|
||||||
</span>
|
</span>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table @cell-dblclick="(row: any, column: any, cell: any, event: any) => cellClick(row, column, cell)"
|
<db-table ref="dbTableRef" :db-id="state.ti.dbId" :db-type="state.ti.dbType" :db="state.ti.db"
|
||||||
@selection-change="onDataSelectionChange" size="small" :data="execRes.data" :max-height="250"
|
:data="execRes.data" :table="state.table" :column-names="execRes.tableColumn" :loading="loading"
|
||||||
v-loading="loading" element-loading-text="查询中..."
|
height="250" empty-text="tips: select *开头的单表查询或点击表名默认查询的数据,可双击数据在线修改"
|
||||||
empty-text="tips: select *开头的单表查询或点击表名默认查询的数据,可双击数据在线修改" stripe border class="mt5">
|
@selection-change="onDataSelectionChange" @change-updated-field="changeUpdatedField"></db-table>
|
||||||
<el-table-column v-if="execRes.tableColumn.length > 0 && table" type="selection" witih="35" />
|
|
||||||
<el-table-column min-witih="100" :witih="DbInst.flexColumnWidth(item, execRes.data)" align="center"
|
|
||||||
v-for="item in execRes.tableColumn" :key="item" :prop="item" :label="item" show-overflow-tooltip>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, watch, onMounted, computed, reactive, toRefs } from 'vue';
|
import { nextTick, watch, onMounted, computed, reactive, toRefs, ref, Ref } from 'vue';
|
||||||
import { useStore } from '@/store/index.ts';
|
import { useStore } from '@/store/index.ts';
|
||||||
import { getSession } from '@/common/utils/storage';
|
import { getSession } from '@/common/utils/storage';
|
||||||
import { isTrue, notBlank } from '@/common/assert';
|
import { isTrue, notBlank } from '@/common/assert';
|
||||||
@@ -91,8 +86,8 @@ import { editor } from 'monaco-editor';
|
|||||||
// 主题仓库 https://github.com/brijeshb42/monaco-themes
|
// 主题仓库 https://github.com/brijeshb42/monaco-themes
|
||||||
// 主题例子 https://editor.bitwiser.in/
|
// 主题例子 https://editor.bitwiser.in/
|
||||||
import SolarizedLight from 'monaco-themes/themes/Solarized-light.json';
|
import SolarizedLight from 'monaco-themes/themes/Solarized-light.json';
|
||||||
|
import DbTable from '../DbTable.vue'
|
||||||
import { DbInst, UpdateFieldsMeta, FieldsMeta, TabInfo } from '../../db';
|
import { TabInfo } from '../../db';
|
||||||
import { exportCsv } from '@/common/utils/export';
|
import { exportCsv } from '@/common/utils/export';
|
||||||
import { dateStrFormat } from '@/common/utils/date';
|
import { dateStrFormat } from '@/common/utils/date';
|
||||||
import { dbApi } from '../../api';
|
import { dbApi } from '../../api';
|
||||||
@@ -119,6 +114,7 @@ const props = defineProps({
|
|||||||
const store = useStore();
|
const store = useStore();
|
||||||
const token = getSession('token');
|
const token = getSession('token');
|
||||||
let monacoEditor = {} as editor.IStandaloneCodeEditor;
|
let monacoEditor = {} as editor.IStandaloneCodeEditor;
|
||||||
|
const dbTableRef = ref(null) as Ref;
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
token,
|
token,
|
||||||
@@ -135,7 +131,7 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
selectionDatas: [] as any,
|
selectionDatas: [] as any,
|
||||||
editorHeight: '500',
|
editorHeight: '500',
|
||||||
updatedFields: [] as UpdateFieldsMeta[],// 各个tab表被修改的字段信息
|
hasUpdatedFileds: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -145,7 +141,7 @@ const {
|
|||||||
table,
|
table,
|
||||||
sqlName,
|
sqlName,
|
||||||
loading,
|
loading,
|
||||||
updatedFields,
|
hasUpdatedFileds,
|
||||||
} = toRefs(state);
|
} = toRefs(state);
|
||||||
|
|
||||||
watch(() => props.editorHeight, (newValue: any) => {
|
watch(() => props.editorHeight, (newValue: any) => {
|
||||||
@@ -156,11 +152,11 @@ onMounted(async () => {
|
|||||||
console.log('in query mounted');
|
console.log('in query mounted');
|
||||||
state.ti = props.data;
|
state.ti = props.data;
|
||||||
state.editorHeight = props.editorHeight;
|
state.editorHeight = props.editorHeight;
|
||||||
const other = state.ti.other;
|
const params = state.ti.params;
|
||||||
state.dbs = other && other.dbs;
|
state.dbs = params && params.dbs;
|
||||||
|
|
||||||
if (other && other.sqlName) {
|
if (params && params.sqlName) {
|
||||||
state.sqlName = other.sqlName;
|
state.sqlName = params.sqlName;
|
||||||
const res = await dbApi.getSql.request({ id: state.ti.dbId, type: 1, name: state.sqlName, db: state.ti.db });
|
const res = await dbApi.getSql.request({ id: state.ti.dbId, type: 1, name: state.sqlName, db: state.ti.db });
|
||||||
state.sql = res.sql;
|
state.sql = res.sql;
|
||||||
}
|
}
|
||||||
@@ -495,6 +491,11 @@ const onDataSelectionChange = (datas: []) => {
|
|||||||
state.selectionDatas = datas;
|
state.selectionDatas = datas;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const changeUpdatedField = (updatedFields: []) => {
|
||||||
|
// 如果存在要更新字段,则显示提交和取消按钮
|
||||||
|
state.hasUpdatedFileds = updatedFields && updatedFields.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行删除数据事件
|
* 执行删除数据事件
|
||||||
*/
|
*/
|
||||||
@@ -513,153 +514,12 @@ const onDeleteData = async () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 监听单元格点击事件
|
|
||||||
const cellClick = (row: any, column: any, cell: any) => {
|
|
||||||
const property = column.property;
|
|
||||||
const table = state.table;
|
|
||||||
// 如果当前操作的表名不存在 或者 当前列的property不存在(如多选框),则不允许修改当前单元格内容
|
|
||||||
if (!table || !property) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let div: HTMLElement = cell.children[0];
|
|
||||||
if (div && div.tagName === 'DIV') {
|
|
||||||
// 转为字符串比较,可能存在数字等
|
|
||||||
let text = (row[property] || row[property] == 0 ? row[property] : '') + '';
|
|
||||||
let input = document.createElement('input');
|
|
||||||
input.setAttribute('value', text);
|
|
||||||
// 将表格witih也赋值于输入框,避免输入框长度超过表格长度
|
|
||||||
input.setAttribute('style', 'height:23px;text-align:center;border:none;' + div.getAttribute('style'));
|
|
||||||
cell.replaceChildren(input);
|
|
||||||
input.focus();
|
|
||||||
input.addEventListener('blur', async () => {
|
|
||||||
row[property] = input.value;
|
|
||||||
cell.replaceChildren(div);
|
|
||||||
if (input.value !== text) {
|
|
||||||
let currentUpdatedFields = state.updatedFields
|
|
||||||
const dbInst = state.ti.getNowDbInst()
|
|
||||||
const db = state.ti.getNowDb();
|
|
||||||
// 主键
|
|
||||||
const primaryKey = await dbInst.loadTableColumn(state.ti.db, table);
|
|
||||||
const primaryKeyValue = row[primaryKey.columnName];
|
|
||||||
// 更新字段列信息
|
|
||||||
const updateColumn = db.getColumn(table, property);
|
|
||||||
const newField = {
|
|
||||||
div, row,
|
|
||||||
fieldName: column.rawColumnKey,
|
|
||||||
fieldType: updateColumn.columnType,
|
|
||||||
oldValue: text,
|
|
||||||
newValue: input.value
|
|
||||||
} as FieldsMeta;
|
|
||||||
|
|
||||||
// 被修改的字段
|
|
||||||
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]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hasKey = true
|
|
||||||
let hasField = primaryKeyFields[0].fields.some(a => {
|
|
||||||
if (a.fieldName === newField.fieldName) {
|
|
||||||
a.newValue = newField.newValue
|
|
||||||
}
|
|
||||||
return a.fieldName === newField.fieldName
|
|
||||||
})
|
|
||||||
if (!hasField) {
|
|
||||||
primaryKeyFields[0].fields.push(newField)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let fields = primaryKeyFields[0].fields
|
|
||||||
|
|
||||||
const fieldsParam = fields.filter((a) => {
|
|
||||||
if (a.fieldName === column.rawColumnKey) {
|
|
||||||
a.newValue = input.value
|
|
||||||
}
|
|
||||||
return a.fieldName === column.rawColumnKey
|
|
||||||
})
|
|
||||||
|
|
||||||
const field = fieldsParam.length > 0 && fieldsParam[0] || {} as FieldsMeta
|
|
||||||
if (field.oldValue === input.value) { // 新值=旧值
|
|
||||||
// 删除数据
|
|
||||||
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.rawColumnKey) : [];
|
|
||||||
a.fields.length <= 0 && delIndex.push(i)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
delIndex.forEach(i => delete currentUpdatedFields[i])
|
|
||||||
currentUpdatedFields = currentUpdatedFields.filter(a => a)
|
|
||||||
} else {
|
|
||||||
// 新增数据
|
|
||||||
div.classList.add('update_field_active')
|
|
||||||
if (hasKey) {
|
|
||||||
currentUpdatedFields.forEach((value, index, array) => {
|
|
||||||
if (value.primaryKey === primaryKeyValue) {
|
|
||||||
array[index].fields = fields
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
currentUpdatedFields.push({
|
|
||||||
primaryKey: primaryKeyValue,
|
|
||||||
primaryKeyName: primaryKey.columnName,
|
|
||||||
primaryKeyType: primaryKey.columnType,
|
|
||||||
fields
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.updatedFields = currentUpdatedFields;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const submitUpdateFields = () => {
|
const submitUpdateFields = () => {
|
||||||
let currentUpdatedFields = state.updatedFields;
|
dbTableRef.value.submitUpdateFields();
|
||||||
if (currentUpdatedFields.length <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { db } = state.ti;
|
|
||||||
const table = state.table;
|
|
||||||
let res = '';
|
|
||||||
let divs: HTMLElement[] = [];
|
|
||||||
currentUpdatedFields.forEach(a => {
|
|
||||||
let sql = `UPDATE ${table} SET `;
|
|
||||||
let primaryKey = a.primaryKey;
|
|
||||||
let primaryKeyType = a.primaryKeyType;
|
|
||||||
let primaryKeyName = a.primaryKeyName;
|
|
||||||
a.fields.forEach(f => {
|
|
||||||
sql += ` ${f.fieldName} = ${DbInst.wrapColumnValue(f.fieldType, f.newValue)},`
|
|
||||||
divs.push(f.div)
|
|
||||||
})
|
|
||||||
sql = sql.substring(0, sql.length - 1)
|
|
||||||
sql += ` WHERE ${primaryKeyName} = ${DbInst.wrapColumnValue(primaryKeyType, primaryKey)} ;`
|
|
||||||
res += sql;
|
|
||||||
})
|
|
||||||
|
|
||||||
state.ti.getNowDbInst().promptExeSql(db, res, () => { }, () => {
|
|
||||||
currentUpdatedFields = [];
|
|
||||||
divs.forEach(a => {
|
|
||||||
a.classList.remove('update_field_active');
|
|
||||||
})
|
|
||||||
state.updatedFields = [];
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancelUpdateFields = () => {
|
const cancelUpdateFields = () => {
|
||||||
state.updatedFields.forEach((a: any) => {
|
dbTableRef.value.cancelUpdateFields();
|
||||||
a.fields.forEach((b: any) => {
|
|
||||||
b.div.classList.remove('update_field_active')
|
|
||||||
b.row[b.fieldName] = b.oldValue
|
|
||||||
})
|
|
||||||
})
|
|
||||||
state.updatedFields = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -28,13 +28,11 @@
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-divider direction="vertical" border-style="dashed" />
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
|
|
||||||
<el-tooltip v-if="state.updatedFields.length > 0" class="box-item" effect="dark" content="提交修改"
|
<el-tooltip v-if="hasUpdatedFileds" class="box-item" effect="dark" content="提交修改" placement="top">
|
||||||
placement="top">
|
|
||||||
<el-link @click="submitUpdateFields()" type="success" :underline="false" class="f12">提交</el-link>
|
<el-link @click="submitUpdateFields()" type="success" :underline="false" class="f12">提交</el-link>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-divider v-if="state.updatedFields.length > 0" direction="vertical" border-style="dashed" />
|
<el-divider v-if="hasUpdatedFileds" direction="vertical" border-style="dashed" />
|
||||||
<el-tooltip v-if="state.updatedFields.length > 0" class="box-item" effect="dark" content="取消修改"
|
<el-tooltip v-if="hasUpdatedFileds" class="box-item" effect="dark" content="取消修改" placement="top">
|
||||||
placement="top">
|
|
||||||
<el-link @click="cancelUpdateFields" type="warning" :underline="false" class="f12">取消</el-link>
|
<el-link @click="cancelUpdateFields" type="warning" :underline="false" class="f12">取消</el-link>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -65,22 +63,12 @@
|
|||||||
</el-input>
|
</el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table @cell-dblclick="(row: any, column: any, cell: any, event: any) => cellClick(row, column, cell)"
|
|
||||||
@sort-change="(sort: any) => onTableSortChange(sort)" @selection-change="onDataSelectionChange"
|
<db-table ref="dbTableRef" :db-id="state.ti.dbId" :db-type="state.ti.dbType" :db="state.ti.db" :data="datas"
|
||||||
:data="datas" size="small" :max-height="tableHeight" v-loading="loading" element-loading-text="查询中..."
|
:table="state.table" :column-names="columnNames" :loading="loading" :height="tableHeight"
|
||||||
empty-text="暂无数据" stripe border class="mt5">
|
:show-column-tip="true" :sortable="true" @sort-change="(sort: any) => onTableSortChange(sort)"
|
||||||
<el-table-column v-if="datas.length > 0" type="selection" width="35" />
|
@selection-change="onDataSelectionChange" @change-updated-field="changeUpdatedField"></db-table>
|
||||||
<el-table-column min-width="100" :width="DbInst.flexColumnWidth(item, datas)" align="center"
|
|
||||||
v-for="item in columnNames" :key="item" :prop="item" :label="item" show-overflow-tooltip
|
|
||||||
:sortable="'custom'">
|
|
||||||
<template #header>
|
|
||||||
<el-tooltip raw-content placement="top" effect="customized">
|
|
||||||
<template #content> {{ getColumnTip(item) }} </template>
|
|
||||||
{{ item }}
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<el-row type="flex" class="mt5" justify="center">
|
<el-row type="flex" class="mt5" justify="center">
|
||||||
<el-pagination small :total="count" @current-change="pageChange()" layout="prev, pager, next, total, jumper"
|
<el-pagination small :total="count" @current-change="pageChange()" layout="prev, pager, next, total, jumper"
|
||||||
v-model:current-page="pageNum" :page-size="DbInst.DefaultLimit"></el-pagination>
|
v-model:current-page="pageNum" :page-size="DbInst.DefaultLimit"></el-pagination>
|
||||||
@@ -115,16 +103,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, watch, reactive, toRefs } from 'vue';
|
import { onMounted, watch, reactive, toRefs, ref, Ref } from 'vue';
|
||||||
import { isTrue, notEmpty } from '@/common/assert';
|
import { isTrue, notEmpty, notBlank } from '@/common/assert';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
import { DbInst, UpdateFieldsMeta, FieldsMeta, TabInfo } from '../../db';
|
import { DbInst, TabInfo } from '../../db';
|
||||||
import { exportCsv } from '@/common/utils/export';
|
import { exportCsv } from '@/common/utils/export';
|
||||||
import { dateStrFormat } from '@/common/utils/date';
|
import { dateStrFormat } from '@/common/utils/date';
|
||||||
import { notBlank } from '../../../../../common/assert';
|
import DbTable from '../DbTable.vue'
|
||||||
|
|
||||||
const emits = defineEmits(['genInsertSql', 'clickSqlName', 'clickSchemaTable', 'changeSchema', 'loadSqlNames'])
|
const emits = defineEmits(['genInsertSql'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
@@ -137,9 +125,10 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const dbTableRef = ref(null) as Ref;
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
ti: {} as TabInfo,
|
ti: {} as TabInfo,
|
||||||
dbId: null, // 当前选中操作的数据库实例
|
|
||||||
table: '', // 当前的表名
|
table: '', // 当前的表名
|
||||||
datas: [],
|
datas: [],
|
||||||
sql: '', // 当前数据tab执行的sql
|
sql: '', // 当前数据tab执行的sql
|
||||||
@@ -161,7 +150,7 @@ const state = reactive({
|
|||||||
value: null
|
value: null
|
||||||
},
|
},
|
||||||
tableHeight: '600',
|
tableHeight: '600',
|
||||||
updatedFields: [] as UpdateFieldsMeta[],// 各个tab表被修改的字段信息
|
hasUpdatedFileds: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -172,6 +161,7 @@ const {
|
|||||||
columnNames,
|
columnNames,
|
||||||
pageNum,
|
pageNum,
|
||||||
count,
|
count,
|
||||||
|
hasUpdatedFileds,
|
||||||
conditionDialog,
|
conditionDialog,
|
||||||
} = toRefs(state);
|
} = toRefs(state);
|
||||||
|
|
||||||
@@ -183,8 +173,8 @@ onMounted(async () => {
|
|||||||
console.log('in table data mounted');
|
console.log('in table data mounted');
|
||||||
state.ti = props.data;
|
state.ti = props.data;
|
||||||
state.tableHeight = props.tableHeight;
|
state.tableHeight = props.tableHeight;
|
||||||
state.table = state.ti.other.table;
|
state.table = state.ti.params.table;
|
||||||
notBlank(state.table, "TableData组件other.table信息不能为空")
|
notBlank(state.table, "TableData组件params.table信息不能为空")
|
||||||
|
|
||||||
const columns = await state.ti.getNowDbInst().loadColumns(state.ti.db, state.table);
|
const columns = await state.ti.getNowDbInst().loadColumns(state.ti.db, state.table);
|
||||||
state.columns = columns;
|
state.columns = columns;
|
||||||
@@ -239,23 +229,6 @@ const exportData = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const getColumnTip = (columnName: string) => {
|
|
||||||
// 优先从 table map中获取
|
|
||||||
let columns = getColumns();
|
|
||||||
if (!columns) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const column = columns.find((c: any) => c.columnName == columnName);
|
|
||||||
const comment = column.columnComment;
|
|
||||||
return `${column.columnType} ${comment ? ' | ' + comment : ''}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getColumns = () => {
|
|
||||||
return state.ti.getNowDb().getColumns(state.table);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 条件查询,点击列信息后显示输入对应的值
|
* 条件查询,点击列信息后显示输入对应的值
|
||||||
*/
|
*/
|
||||||
@@ -319,6 +292,11 @@ const onDataSelectionChange = (datas: []) => {
|
|||||||
state.selectionDatas = datas;
|
state.selectionDatas = datas;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const changeUpdatedField = (updatedFields: []) => {
|
||||||
|
// 如果存在要更新字段,则显示提交和取消按钮
|
||||||
|
state.hasUpdatedFileds = updatedFields && updatedFields.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行删除数据事件
|
* 执行删除数据事件
|
||||||
*/
|
*/
|
||||||
@@ -336,151 +314,12 @@ const onGenerateInsertSql = async () => {
|
|||||||
emits('genInsertSql', state.ti.getNowDbInst().genInsertSql(state.ti.db, state.table, state.selectionDatas));
|
emits('genInsertSql', state.ti.getNowDbInst().genInsertSql(state.ti.db, state.table, state.selectionDatas));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 监听单元格点击事件
|
|
||||||
const cellClick = (row: any, column: any, cell: any) => {
|
|
||||||
const property = column.property;
|
|
||||||
// 如果当前操作的表名不存在 或者 当前列的property不存在(如多选框),则不允许修改当前单元格内容
|
|
||||||
if (!property) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let div: HTMLElement = cell.children[0];
|
|
||||||
if (div && div.tagName === 'DIV') {
|
|
||||||
// 转为字符串比较,可能存在数字等
|
|
||||||
let text = (row[property] || row[property] == 0 ? row[property] : '') + '';
|
|
||||||
let input = document.createElement('input');
|
|
||||||
input.setAttribute('value', text);
|
|
||||||
// 将表格width也赋值于输入框,避免输入框长度超过表格长度
|
|
||||||
input.setAttribute('style', 'height:23px;text-align:center;border:none;' + div.getAttribute('style'));
|
|
||||||
cell.replaceChildren(input);
|
|
||||||
input.focus();
|
|
||||||
input.addEventListener('blur', async () => {
|
|
||||||
row[property] = input.value;
|
|
||||||
cell.replaceChildren(div);
|
|
||||||
if (input.value !== text) {
|
|
||||||
let currentUpdatedFields = state.updatedFields
|
|
||||||
const db = state.ti.getNowDb();
|
|
||||||
// 主键
|
|
||||||
const primaryKey = db.getColumn(state.table);
|
|
||||||
const primaryKeyValue = row[primaryKey.columnName];
|
|
||||||
// 更新字段列信息
|
|
||||||
const updateColumn = db.getColumn(state.table, property);
|
|
||||||
const newField = {
|
|
||||||
div, row,
|
|
||||||
fieldName: column.rawColumnKey,
|
|
||||||
fieldType: updateColumn.columnType,
|
|
||||||
oldValue: text,
|
|
||||||
newValue: input.value
|
|
||||||
} as FieldsMeta;
|
|
||||||
|
|
||||||
// 被修改的字段
|
|
||||||
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]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hasKey = true
|
|
||||||
let hasField = primaryKeyFields[0].fields.some(a => {
|
|
||||||
if (a.fieldName === newField.fieldName) {
|
|
||||||
a.newValue = newField.newValue
|
|
||||||
}
|
|
||||||
return a.fieldName === newField.fieldName
|
|
||||||
})
|
|
||||||
if (!hasField) {
|
|
||||||
primaryKeyFields[0].fields.push(newField)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let fields = primaryKeyFields[0].fields
|
|
||||||
|
|
||||||
const fieldsParam = fields.filter((a) => {
|
|
||||||
if (a.fieldName === column.rawColumnKey) {
|
|
||||||
a.newValue = input.value
|
|
||||||
}
|
|
||||||
return a.fieldName === column.rawColumnKey
|
|
||||||
})
|
|
||||||
|
|
||||||
const field = fieldsParam.length > 0 && fieldsParam[0] || {} as FieldsMeta
|
|
||||||
if (field.oldValue === input.value) { // 新值=旧值
|
|
||||||
// 删除数据
|
|
||||||
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.rawColumnKey) : [];
|
|
||||||
a.fields.length <= 0 && delIndex.push(i)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
delIndex.forEach(i => delete currentUpdatedFields[i])
|
|
||||||
currentUpdatedFields = currentUpdatedFields.filter(a => a)
|
|
||||||
} else {
|
|
||||||
// 新增数据
|
|
||||||
div.classList.add('update_field_active')
|
|
||||||
if (hasKey) {
|
|
||||||
currentUpdatedFields.forEach((value, index, array) => {
|
|
||||||
if (value.primaryKey === primaryKeyValue) {
|
|
||||||
array[index].fields = fields
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
currentUpdatedFields.push({
|
|
||||||
primaryKey: primaryKeyValue,
|
|
||||||
primaryKeyName: primaryKey.columnName,
|
|
||||||
primaryKeyType: primaryKey.columnType,
|
|
||||||
fields
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.updatedFields = currentUpdatedFields;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const submitUpdateFields = () => {
|
const submitUpdateFields = () => {
|
||||||
let currentUpdatedFields = state.updatedFields;
|
dbTableRef.value.submitUpdateFields();
|
||||||
if (currentUpdatedFields.length <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { db } = state.ti;
|
|
||||||
let res = '';
|
|
||||||
let divs: HTMLElement[] = [];
|
|
||||||
currentUpdatedFields.forEach(a => {
|
|
||||||
let sql = `UPDATE ${state.table} SET `;
|
|
||||||
let primaryKey = a.primaryKey;
|
|
||||||
let primaryKeyType = a.primaryKeyType;
|
|
||||||
let primaryKeyName = a.primaryKeyName;
|
|
||||||
a.fields.forEach(f => {
|
|
||||||
sql += ` ${f.fieldName} = ${DbInst.wrapColumnValue(f.fieldType, f.newValue)},`
|
|
||||||
divs.push(f.div)
|
|
||||||
})
|
|
||||||
sql = sql.substring(0, sql.length - 1)
|
|
||||||
sql += ` WHERE ${primaryKeyName} = ${DbInst.wrapColumnValue(primaryKeyType, primaryKey)} ;`
|
|
||||||
res += sql;
|
|
||||||
})
|
|
||||||
|
|
||||||
state.ti.getNowDbInst().promptExeSql(db, res, () => { }, () => {
|
|
||||||
currentUpdatedFields = [];
|
|
||||||
divs.forEach(a => {
|
|
||||||
a.classList.remove('update_field_active');
|
|
||||||
})
|
|
||||||
state.updatedFields = [];
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancelUpdateFields = () => {
|
const cancelUpdateFields = () => {
|
||||||
state.updatedFields.forEach((a: any) => {
|
dbTableRef.value.cancelUpdateFields();
|
||||||
a.fields.forEach((b: any) => {
|
|
||||||
b.div.classList.remove('update_field_active')
|
|
||||||
b.row[b.fieldName] = b.oldValue
|
|
||||||
})
|
|
||||||
})
|
|
||||||
state.updatedFields = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加新数据行
|
// 添加新数据行
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ export class TabInfo {
|
|||||||
/**
|
/**
|
||||||
* tab需要的其他信息
|
* tab需要的其他信息
|
||||||
*/
|
*/
|
||||||
other: any
|
params: any
|
||||||
|
|
||||||
getNowDbInst() {
|
getNowDbInst() {
|
||||||
if (!this.dbType) {
|
if (!this.dbType) {
|
||||||
|
|||||||
Reference in New Issue
Block a user