diff --git a/report-ui/package.json b/report-ui/package.json
index 0651496d..25549a78 100644
--- a/report-ui/package.json
+++ b/report-ui/package.json
@@ -24,6 +24,7 @@
     "js-cookie": "2.2.0",
     "miment": "^0.0.9",
     "moment": "^2.29.1",
+    "monaco-editor": "^0.20.0",
     "normalize.css": "7.0.0",
     "nprogress": "0.2.0",
     "sortablejs": "^1.10.2",
@@ -61,6 +62,7 @@
     "html-webpack-plugin": "4.0.0-alpha",
     "js-md5": "^0.7.3",
     "mini-css-extract-plugin": "0.4.1",
+    "monaco-editor-webpack-plugin": "^4.1.1",
     "node-notifier": "5.2.1",
     "node-sass": "^4.7.2",
     "optimize-css-assets-webpack-plugin": "5.0.0",
diff --git a/report-ui/src/views/report/resultset/components/EditDataSet.vue b/report-ui/src/views/report/resultset/components/EditDataSet.vue
index 44d3abec..ea3f81d6 100644
--- a/report-ui/src/views/report/resultset/components/EditDataSet.vue
+++ b/report-ui/src/views/report/resultset/components/EditDataSet.vue
@@ -62,11 +62,11 @@
           >
             <el-form-item label="查询SQL或请求体">
               <div class="codemirror">
-                <codemirror
+                <!-- <monaco-editor
                   v-model.trim="formData.dynSentence"
-                  :options="optionsSql"
-                  style="height: 190px"
-                />
+                  language="sql"
+                  style="height: 500px"
+                /> -->
               </div>
             </el-form-item>
           </el-col>
@@ -92,7 +92,7 @@
                       align="center"
                       label="序号"
                       type="index"
-                      width="80"
+                      min-width="80"
                     />
                     <el-table-column label="参数名" align="center">
                       <template slot-scope="scope">
@@ -349,10 +349,10 @@
     >
       <div class="codemirror">
         <!-- //自定义高级规则? -->
-        <codemirror
+        <monaco-editor
           v-model.trim="validationRules"
-          :options="optionsJavascript"
-          style="height: 210px;overflow: hidden;"
+          language="javascript"
+          style="height: 500px"
         />
       </div>
       <span slot="footer" class="dialog-footer">
@@ -382,10 +382,10 @@ import "codemirror/mode/javascript/javascript.js";
 import "codemirror/lib/codemirror.css"; // 核心样式
 import "codemirror/theme/cobalt.css"; // 引入主题后还需要在 options 中指定主题才会生效
 import vueJsonEditor from "vue-json-editor";
-
+import MonacoEditor from "./MonacoEditor.vue";
 export default {
   name: "Support",
-  components: { Dictionary, codemirror, vueJsonEditor },
+  components: { Dictionary, codemirror, vueJsonEditor, MonacoEditor },
   props: {
     visib: {
       required: true,
diff --git a/report-ui/src/views/report/resultset/components/MonacoEditor.vue b/report-ui/src/views/report/resultset/components/MonacoEditor.vue
new file mode 100644
index 00000000..8f5325b1
--- /dev/null
+++ b/report-ui/src/views/report/resultset/components/MonacoEditor.vue
@@ -0,0 +1,132 @@
+<template>
+  <div ref="editor" class="main"></div>
+</template>
+
+<script>
+import * as monaco from "monaco-editor";
+import createSqlCompleter from "./util/sql-completion";
+import createJavascriptCompleter from "./util/javascript-completion";
+import registerLanguage from "./util/log-language";
+const global = {};
+
+const getHints = model => {
+  let id = model.id.substring(6);
+  return (global[id] && global[id].hints) || [];
+};
+monaco.languages.registerCompletionItemProvider(
+  "sql",
+  createSqlCompleter(getHints)
+);
+monaco.languages.registerCompletionItemProvider(
+  "javascript",
+  createJavascriptCompleter(getHints)
+);
+registerLanguage(monaco);
+/**
+ * monaco options
+ * https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandaloneeditorconstructionoptions.html
+ */
+export default {
+  props: {
+    options: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    value: {
+      type: String,
+      required: false
+    },
+    language: {
+      type: String
+    },
+    hints: {
+      type: Array,
+      default() {
+        return [];
+      }
+    }
+  },
+  name: "MonacoEditor",
+  data() {
+    return {
+      editorInstance: null,
+      defaultOptions: {
+        theme: "vs-dark",
+        fontSize: 14
+      }
+    };
+  },
+  watch: {
+    value() {
+      if (this.value !== this.editorInstance.getValue()) {
+        this.editorInstance.setValue(this.value);
+      }
+    }
+  },
+  mounted() {
+    this.initEditor();
+    global[this.editorInstance._id] = this;
+    window.addEventListener("resize", this.layout);
+  },
+  destroyed() {
+    this.editorInstance.dispose();
+    global[this.editorInstance._id] = null;
+    window.removeEventListener("resize", this.layout);
+  },
+  methods: {
+    layout() {
+      this.editorInstance.layout();
+    },
+    undo() {
+      this.editorInstance.trigger("anyString", "undo");
+      this.onValueChange();
+    },
+    redo() {
+      this.editorInstance.trigger("anyString", "redo");
+      this.onValueChange();
+    },
+    getOptions() {
+      let props = { value: this.value };
+      this.language !== undefined && (props.language = this.language);
+      let options = Object.assign({}, this.defaultOptions, this.options, props);
+      return options;
+    },
+    onValueChange() {
+      this.$emit("input", this.editorInstance.getValue());
+      this.$emit("change", this.editorInstance.getValue());
+    },
+    initEditor() {
+      this.MonacoEnvironment = {
+        getWorkerUrl: function() {
+          return "./editor.worker.bundle.js";
+        }
+      };
+
+      this.editorInstance = monaco.editor.create(
+        this.$refs.editor,
+        this.getOptions()
+      );
+      this.editorInstance.onContextMenu(e => {
+        this.$emit("contextmenu", e);
+      });
+      this.editorInstance.onDidChangeModelContent(() => {
+        this.onValueChange();
+      });
+      this.editorInstance.addCommand(
+        monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S,
+        () => {
+          this.$emit("save", this.editorInstance.getValue());
+        }
+      );
+    }
+  }
+};
+</script>
+
+<style scoped>
+.main /deep/ .view-lines * {
+  font-family: Consolas, "Courier New", monospace !important;
+}
+</style>
diff --git a/report-ui/src/views/report/resultset/components/util/javascript-completion.js b/report-ui/src/views/report/resultset/components/util/javascript-completion.js
new file mode 100644
index 00000000..3999cc29
--- /dev/null
+++ b/report-ui/src/views/report/resultset/components/util/javascript-completion.js
@@ -0,0 +1,38 @@
+import * as monaco from 'monaco-editor'
+// js 有内置提示
+function createCompleter(getExtraHints) {
+    const createSuggestions = function (model, textUntilPosition) {
+        let text = model.getValue();
+        textUntilPosition = textUntilPosition.replace(/[\*\[\]@\$\(\)]/g, "").replace(/(\s+|\.)/g, " ");
+        let arr = textUntilPosition.split(/[\s;]/);
+        let activeStr = arr[arr.length - 1];
+        let len = activeStr.length;
+        let rexp = new RegExp("([^\\w]|^)" + activeStr + "\\w*", "gim");
+        let match = text.match(rexp);
+        let mergeHints = Array.from(new Set([...getExtraHints(model)]))
+            .sort()
+            .filter(ele => {
+                let rexp = new RegExp(ele.substr(0, len), "gim");
+                return (match && match.length === 1 && ele === activeStr) ||
+                    ele.length === 1 ? false : activeStr.match(rexp);
+            });
+        return mergeHints.map(ele => ({
+            label: ele,
+            kind: monaco.languages.CompletionItemKind.Text,
+            documentation: ele,
+            insertText: ele
+        }));
+    };
+    return {
+        provideCompletionItems(model, position) {
+            let textUntilPosition = model.getValueInRange({
+                startLineNumber: position.lineNumber,
+                startColumn: 1,
+                endLineNumber: position.lineNumber,
+                endColumn: position.column
+            });
+            return { suggestions: createSuggestions(model, textUntilPosition) };
+        }
+    }
+}
+export default createCompleter;
\ No newline at end of file
diff --git a/report-ui/src/views/report/resultset/components/util/log-language.js b/report-ui/src/views/report/resultset/components/util/log-language.js
new file mode 100644
index 00000000..a3db9c6b
--- /dev/null
+++ b/report-ui/src/views/report/resultset/components/util/log-language.js
@@ -0,0 +1,58 @@
+function registerLanguage(monaco) {
+    monaco.languages.register({
+      id: "log"
+    });
+    monaco.languages.setMonarchTokensProvider("log", {
+      tokenizer: {
+        root: [
+          [/(^[=a-zA-Z].*|\d\s.*)/, "log-normal"],
+          [/\sERROR\s.*/, "log-error"],
+          [/\sWARN\s.*/, "log-warn"],
+          [/\sINFO\s.*/, "log-info"],
+          [
+            /^([0-9]{4}||[0-9]{2})-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{3})?/,
+            "log-date",
+          ],
+          [
+            /^[0-9]{2}\/[0-9]{2}\/[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{3})?/,
+            "log-date",
+          ],
+          [/(^\*\*Waiting queue:.*)/, "log-info"],
+          [/(^\*\*result tips:.*)/, "log-info"],
+        ],
+      },
+    });
+    monaco.editor.defineTheme("log", {
+      base: "vs",
+      inherit: true,
+      rules: [{
+          token: "log-info",
+          foreground: "4b71ca"
+        },
+        {
+          token: "log-error",
+          foreground: "ff0000",
+          fontStyle: "bold"
+        },
+        {
+          token: "log-warn",
+          foreground: "FFA500"
+        },
+        {
+          token: "log-date",
+          foreground: "008800"
+        },
+        {
+          token: "log-normal",
+          foreground: "808080"
+        },
+      ],
+      colors: {
+        "editor.lineHighlightBackground": "#ffffff",
+        "editorGutter.background": "#f7f7f7",
+      },
+    });
+  
+  }
+  
+  export default registerLanguage;
\ No newline at end of file
diff --git a/report-ui/src/views/report/resultset/components/util/sql-completion.js b/report-ui/src/views/report/resultset/components/util/sql-completion.js
new file mode 100644
index 00000000..537057be
--- /dev/null
+++ b/report-ui/src/views/report/resultset/components/util/sql-completion.js
@@ -0,0 +1,82 @@
+import * as monaco from 'monaco-editor'
+const hints = [
+    "SELECT",
+    "INSERT",
+    "DELETE",
+    "UPDATE",
+    "CREATE TABLE",
+    "DROP TABLE",
+    "ALTER TABLE",
+    "CREATE VIEW",
+    "DROP VIEW",
+    "CREATE INDEX",
+    "DROP INDEX",
+    "CREATE PROCEDURE",
+    "DROP PROCEDURE",
+    "CREATE TRIGGER",
+    "DROP TRIGGER",
+    "CREATE SCHEMA",
+    "DROP SCHEMA",
+    "CREATE DOMAIN",
+    "ALTER DOMAIN",
+    "DROP DOMAIN",
+    "GRANT",
+    "DENY",
+    "REVOKE",
+    "COMMIT",
+    "ROLLBACK",
+    "SET TRANSACTION",
+    "DECLARE",
+    "EXPLAN",
+    "OPEN",
+    "FETCH",
+    "CLOSE",
+    "PREPARE",
+    "EXECUTE",
+    "DESCRIBE",
+    "FORM",
+    "ORDER BY"]
+function createCompleter(getExtraHints) {
+    const createSuggestions = function (model, textUntilPosition) {
+        let text = model.getValue();
+        textUntilPosition = textUntilPosition.replace(/[\*\[\]@\$\(\)]/g, "").replace(/(\s+|\.)/g, " ");
+        let arr = textUntilPosition.split(/[\s;]/);
+        let activeStr = arr[arr.length - 1];
+        let len = activeStr.length;
+        let rexp = new RegExp("([^\\w]|^)" + activeStr + "\\w*", "gim");
+        let match = text.match(rexp);
+        let textHints = !match ? [] :
+            match.map(ele => {
+                let rexp = new RegExp(activeStr, "gim");
+                let search = ele.search(rexp);
+                return ele.substr(search);
+            });
+        let mergeHints = Array.from(new Set([...hints, ...textHints, ...getExtraHints(model)]))
+            .sort()
+            .filter(ele => {
+                let rexp = new RegExp(ele.substr(0, len), "gim");
+                return (match && match.length === 1 && ele === activeStr) ||
+                    ele.length === 1 ? false : activeStr.match(rexp);
+            });
+        return mergeHints.map(ele => ({
+            label: ele,
+            kind: hints.indexOf(ele) > -1 ?
+                monaco.languages.CompletionItemKind.Keyword :
+                monaco.languages.CompletionItemKind.Text,
+            documentation: ele,
+            insertText: ele
+        }));
+    };
+    return {
+        provideCompletionItems(model, position) {
+            let textUntilPosition = model.getValueInRange({
+                startLineNumber: position.lineNumber,
+                startColumn: 1,
+                endLineNumber: position.lineNumber,
+                endColumn: position.column
+            });
+            return { suggestions: createSuggestions(model, textUntilPosition) };
+        }
+    }
+}
+export default createCompleter;
\ No newline at end of file
diff --git a/report-ui/webpack.config.js b/report-ui/webpack.config.js
index ae796712..d731edd7 100644
--- a/report-ui/webpack.config.js
+++ b/report-ui/webpack.config.js
@@ -1,5 +1,6 @@
 'use strict'
 const path = require('path')
+const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
 
 module.exports = {
   resolve: {
@@ -8,5 +9,8 @@ module.exports = {
       '@': path.resolve('src'),
       'vue$': 'vue/dist/vue.esm.js'
     }
-  }
+  },
+  plugins: [
+    new MonacoWebpackPlugin()
+  ]
 }