From 0e601b503321e7e6eb9a5c1429fd05252ecaa617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=97=E6=B4=8B?= Date: Thu, 21 Dec 2023 15:02:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A1=A8=E6=A0=BC=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=BC=96=E8=BE=91json=E3=80=81xml=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mayfly_go_web/src/views/ops/db/SqlExec.vue | 31 ++-- .../ops/db/component/table/ColumnFormItem.vue | 8 +- .../ops/db/component/table/DbTableData.vue | 43 +++++- .../table/DbTableDataEditorDialog.ts | 45 ++++++ .../table/DbTableDataEditorDialog.vue | 142 ++++++++++++++++++ 5 files changed, 244 insertions(+), 25 deletions(-) create mode 100644 mayfly_go_web/src/views/ops/db/component/table/DbTableDataEditorDialog.ts create mode 100644 mayfly_go_web/src/views/ops/db/component/table/DbTableDataEditorDialog.vue diff --git a/mayfly_go_web/src/views/ops/db/SqlExec.vue b/mayfly_go_web/src/views/ops/db/SqlExec.vue index 9df780aa..a8d2e7b0 100644 --- a/mayfly_go_web/src/views/ops/db/SqlExec.vue +++ b/mayfly_go_web/src/views/ops/db/SqlExec.vue @@ -263,10 +263,20 @@ const NodeTypeDbInst = new NodeType(SqlExecNodeType.DbInst).withLoadNodesFunc((p const NodeTypeDb = new NodeType(SqlExecNodeType.Db) .withLoadNodesFunc(async (parentNode: TagTreeNode) => { const params = parentNode.params; + // pg类数据库会多一层schema if (params.type == 'postgres' || params.type === 'dm') { - return [new TagTreeNode(`${params.id}.${params.db}.schema-menu`, 'schema', NodeTypePostgresScheamMenu).withParams(params).withIcon(SchemaIcon)]; + const params = parentNode.params; + const { id, db } = params; + const schemaNames = await dbApi.pgSchemas.request({ id, db }); + return schemaNames.map((sn: any) => { + // 将db变更为 db/schema; + const nParams = { ...params }; + nParams.schema = sn; + nParams.db = nParams.db + '/' + sn; + nParams.dbs = schemaNames; + return new TagTreeNode(`${params.id}.${params.db}.schema.${sn}`, sn, NodeTypePostgresScheam).withParams(nParams).withIcon(SchemaIcon); + }); } - return [ new TagTreeNode(`${params.id}.${params.db}.table-menu`, '表', NodeTypeTableMenu).withParams(params).withIcon(TableIcon), new TagTreeNode(getSqlMenuNodeKey(params.id, params.db), 'SQL', NodeTypeSqlMenu).withParams(params).withIcon(SqlIcon), @@ -274,23 +284,6 @@ const NodeTypeDb = new NodeType(SqlExecNodeType.Db) }) .withNodeClickFunc(nodeClickChangeDb); -// postgres schema模式菜单 -const NodeTypePostgresScheamMenu = new NodeType(SqlExecNodeType.PgSchemaMenu) - .withLoadNodesFunc(async (parentNode: TagTreeNode) => { - const params = parentNode.params; - const { id, db } = params; - const schemaNames = await dbApi.pgSchemas.request({ id, db }); - return schemaNames.map((sn: any) => { - // 将db变更为 db/schema; - const nParams = { ...params }; - nParams.schema = sn; - nParams.db = nParams.db + '/' + sn; - nParams.dbs = schemaNames; - return new TagTreeNode(`${params.id}.${params.db}.schema.${sn}`, sn, NodeTypePostgresScheam).withParams(nParams).withIcon(SchemaIcon); - }); - }) - .withNodeClickFunc(nodeClickChangeDb); - // postgres schema模式 const NodeTypePostgresScheam = new NodeType(SqlExecNodeType.PgSchema) .withLoadNodesFunc(async (parentNode: TagTreeNode) => { diff --git a/mayfly_go_web/src/views/ops/db/component/table/ColumnFormItem.vue b/mayfly_go_web/src/views/ops/db/component/table/ColumnFormItem.vue index 7d0d5dfa..3cb847f7 100644 --- a/mayfly_go_web/src/views/ops/db/component/table/ColumnFormItem.vue +++ b/mayfly_go_web/src/views/ops/db/component/table/ColumnFormItem.vue @@ -11,7 +11,7 @@ /> { * @param colIndex ci */ const canEdit = (rowIndex: number, colIndex: number) => { - return state.table && nowUpdateCell && nowUpdateCell.rowIndex == rowIndex && nowUpdateCell.colIndex == colIndex; + return state.table && nowUpdateCell?.rowIndex == rowIndex && nowUpdateCell?.colIndex == colIndex && state.editorLang === 'string'; }; /** @@ -646,6 +648,29 @@ const onExportSql = async () => { ); }; +const getEditorLangByValue = (value: any) => { + if (typeof value === 'string') { + // 判断是否是json + try { + if (typeof JSON.parse(value) === 'object') { + return 'json'; + } + } catch (e) { + /* empty */ + } + // 判断是否是html + try { + const doc = new DOMParser().parseFromString(value, 'text/html'); + if (Array.from(doc.body.childNodes).some((node) => node.nodeType === 1)) { + return 'html'; + } + } catch (e) { + /* empty */ + } + } + return 'string'; +}; + const onEnterEditMode = (rowData: any, column: any, rowIndex = 0, columnIndex = 0) => { if (!state.table) { return; @@ -658,10 +683,24 @@ const onEnterEditMode = (rowData: any, column: any, rowIndex = 0, columnIndex = oldValue: rowData[column.dataKey], dataType: dbDialect.getDataType(column.columnType), }; + + // 编辑器语言,如:json、html、string,目前支持json、html使用MonacoEditor编辑器 + let editorLang = getEditorLangByValue(rowData[column.dataKey]); + state.editorLang = editorLang; + if (editorLang === 'html' || editorLang === 'json') { + TableDataEditorBox({ + content: rowData[column.dataKey], + title: '编辑字段' + column.dataKey, + language: editorLang, + runSuccessCallback: (newVal: any) => { + rowData[column.dataKey] = newVal; + onExitEditMode(rowData, column, rowIndex); + }, + }); + } }; const onExitEditMode = (rowData: any, column: any, rowIndex = 0) => { - console.trace('exit'); const oldValue = nowUpdateCell.oldValue; const newValue = rowData[column.dataKey]; diff --git a/mayfly_go_web/src/views/ops/db/component/table/DbTableDataEditorDialog.ts b/mayfly_go_web/src/views/ops/db/component/table/DbTableDataEditorDialog.ts new file mode 100644 index 00000000..1e04d619 --- /dev/null +++ b/mayfly_go_web/src/views/ops/db/component/table/DbTableDataEditorDialog.ts @@ -0,0 +1,45 @@ +import { h, render, VNode } from 'vue'; +import SqlExecDialog from './DbTableDataEditorDialog.vue'; + +export type TableDataEditorProps = { + content: string; + title: string; + language: string; + runSuccessCallback?: Function; + cancelCallback?: Function; +}; + +const boxId = 'table-data-editor-id'; + +const renderBox = (): VNode => { + const props: TableDataEditorProps = { + content: '', + title: '', + language: '', + }; + const container = document.createElement('div'); + container.id = boxId; + // 创建 虚拟dom + const boxVNode = h(SqlExecDialog, props); + // 将虚拟dom渲染到 container dom 上 + render(boxVNode, container); + // 最后将 container 追加到 body 上 + document.body.appendChild(container); + + return boxVNode; +}; + +let boxInstance: any; + +const TableDataEditorBox = (props: TableDataEditorProps): void => { + if (boxInstance) { + const boxVue = boxInstance.component; + // 调用open方法显示弹框,注意不能使用boxVue.ctx来调用组件函数(build打包后ctx会获取不到) + boxVue.exposed.open(props); + } else { + boxInstance = renderBox(); + TableDataEditorBox(props); + } +}; + +export default TableDataEditorBox; diff --git a/mayfly_go_web/src/views/ops/db/component/table/DbTableDataEditorDialog.vue b/mayfly_go_web/src/views/ops/db/component/table/DbTableDataEditorDialog.vue new file mode 100644 index 00000000..f97496de --- /dev/null +++ b/mayfly_go_web/src/views/ops/db/component/table/DbTableDataEditorDialog.vue @@ -0,0 +1,142 @@ + + + +