先上圖:左側是數據庫表,右側上部是sql編輯器,下部是執行sql的返回接口
HTML:
<el-row> <el-col :span="4" class="sqlTree"> <el-tree :data="sqlTree" :props="defaultProps" node-key="id" default-expand-all> <span slot-scope="{ node,data }"> <span v-if="data.icon == 'iconOne'"> <i class="el-icon-folder-opened"></i>{{ node.label }} </span> <span v-if="data.icon == 'iconTwo'"> <i class="el-icon-document"></i>{{ node.label }} </span> </span> </el-tree> </el-col> <el-col :span="20" class="sqlText"> <div class="sqlBtn"> <el-button class="runBtn" type="primary" icon="el-icon-caret-right" size="mini" @click="handleRestart(true)">運行</el-button> <el-button class="beatyBtn" type="success" icon="el-icon-magic-stick" size="mini" @click="sqlFormat">美化</el-button> </div> <!-- <codemirror ref="myCm" v-model="sqlText" :options="cmOptions" @ready="onCmReady" @focus="onCmFocus" @input="onCmCodeChange"></codemirror> --> <textarea ref="myCm" class="sqlTextarea" v-model="sqlText"></textarea> <el-tabs type="border-card" v-if="typeof (sqlInfo.hasResult) != 'undefined'"> <el-tab-pane label="信息" v-if="!sqlInfo.hasResult && !sqlInfo.result">ERROR>> {{sqlInfo.msg}}</el-tab-pane> <el-tab-pane label="信息" v-if="!sqlInfo.hasResult && sqlInfo.result">INFO>> {{sqlInfo.msg}}</el-tab-pane> <el-tab-pane label="結果" v-if="sqlInfo.hasResult"> <el-table :data="sqlInfo.resList" height="200" style="width: 100%"> <el-table-column v-for="(item, ind) in sqlInfo.header" :key="ind" :prop="item" :label="item"></el-table-column> </el-table> </el-tab-pane> </el-tabs> <div class="paginationBox" v-if="sqlInfo.hasResult"> <span> 展示 <!-- <span v-if="this.total"> {{this.pageBean.page == 1 ? 1 : (this.pageBean.page - 1) * 10 + 1}} -</span> --> {{ sqlInfo.resList.length }} 條數據 , 總共 {{sqlInfo.total}} 條記錄。 </span> <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageBean.page" :page-size="pageBean.pageSize" :total="sqlInfo.total" layout="prev, pager, next" style="float: right" > </el-pagination> </div> </el-col> </el-row>
JS:
// codemirror import { codemirror } from 'vue-codemirror' import 'codemirror/lib/codemirror.css' import 'codemirror/theme/base16-light.css' import 'codemirror/addon/hint/show-hint.css' let CodeMirror = require("codemirror/lib/codemirror"); // 高亮 // require("codemirror/mode/sql/sql.js") require("../../../public/static/sql.js") require('codemirror/addon/hint/sql-hint.js') require('codemirror/addon/hint/show-hint.js') require('codemirror/addon/selection/active-line.js') components: { codemirror }, methods: { //運行 handleRestart(flag) { this.sqlInfo = {} this.errorSql = '' this.payload(async () => { await this.restartExeTask(flag) }) }, //運行 async restartExeTask(flag) { let id = this.$route.query.id ? this.$route.query.id : '' let param = { sql: this.editor.getValue(), taskId: id, pageSize: 10, } // 如果是運行按鈕默認第一頁 if (flag) { param.pageIndex = 1 } else { param.pageIndex = this.pageBean.page } let response = await req.post(cig + `/governance/cigResFusionTaskExecute/v1/exeTask`, param); // sql運行 hasResult:true是表格,其他的是msg this.sqlInfo = response.data // 如果是運行按鈕默認第一頁 if (flag) { this.pageBean.page = 1 } }, // 美化sql代碼 sqlFormat() { /*獲取文本編輯器內容*/ let sqlContent=""; sqlContent=this.editor.getValue(); /*將sql內容進行格式后放入編輯器中*/ this.editor.setValue(sqlFormatter.format(sqlContent)); }, getSelectedRange() { return { from: this.editor.getCursor(true), to: this.editor.getCursor(false) }; }, checkListChange(value){ if(value == true){ this.tableData[this.rowIndex].detectionRule.push({ name: '空值率探查', type: 'success' }); }else{ this.tableData[this.rowIndex].detectionRule.forEach((item,index)=>{ if(item['name'] == "空值率探查"){ this.tableData[this.rowIndex].detectionRule.remove(item); } }) } }, tagClose(tag,index,rowIndex) { this.tableData[rowIndex].detectionRule.splice(index, 1); if(tag['name'] == "空值率探查"){ this.detectionInfo.nullRateDetection = false; } }, //下一步 handleNext() { if (this.stepActive == 0) { this.$refs['resForm'].validate((valid) => { if (valid) { this.stepActive++ } else { this.$message({ message: '表單數據有誤,請確認后重新操作!', type: 'warning' }); return false; } }); // 判斷是否已經存在codemirror 若存在 則不初始化 if (!this.hasMirror) { let _this = this this.$nextTick(() => { _this.initCdMirror() }) } }else if(this.stepActive == 1){ this.stepActive++ } }, // 初始化codemirror initCdMirror() { this.editor = CodeMirror.fromTextArea(this.$refs.myCm, { mode: 'text/xl-sql',//選擇對應代碼編輯器的語言,我這邊選的是數據庫,根據個人情況自行設置即可 tabSize: 2, indentWithTabs: true, smartIndent: true, lineNumbers: true, matchBrackets: true, theme: 'base16-light', line: false, autofocus: true, hint: CodeMirror.hint.sql, hintOptions: { tables: window.tablewords } // lineWrapping: true, //是否換行 // foldGutter: true, //是否折疊 // gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"] }) //代碼自動提示功能,記住使用cursorActivity事件不要使用change事件,這是一個坑,那樣頁面直接會卡死 this.editor.on("keyup", function (cm, event) { //所有的字母和'$','{','.'在鍵按下之后都將觸發自動完成 if (!cm.state.completionActive && ((event.keyCode >= 65 && event.keyCode <= 90 ) || event.keyCode == 52 || event.keyCode == 219 || event.keyCode == 190)) { CodeMirror.commands.autocomplete(cm, null, {completeSingle: false}); } }); this.hasMirror = true }, },
其中引用是三個文件需要自己從node_modules中copy出來
index.html需引入sql_formatter.min.js
<script src="<%= BASE_URL %>static/sql_formatter.min.js"></script>
sql.js:
/** 以下是自定義的 */ var ckeywords = ''; var funwords = []; let baseUrl = window.context.uc console.log(baseUrl) $.ajax({ type : "get", url : baseUrl+ '/governance/cigResFusionTask/v1/getAllWordsForEditor', dataType : "json", async:false, headers: { 'Authorization': 'Bearer ' + JSON.parse(sessionStorage.getItem('currentUser')).token }, success: function(r){ if(r){ funwords = r.funWords; ckeywords = sqlKeywords + r.keyWords; window.tablewords = r.tableWords; } }, error : function (r){ if(r.readyState == '0' && r.status == '0'){ alert('對不起,無法連接服務器,請檢查您的計算機硬件以及網絡連接是否正常!'); } } }); if(ckeywords && ckeywords.size <=0){ ckeywords = set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general get global grant grants group group_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"); } CodeMirror.defineMIME("text/xl-sql", { name: "sql", client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"), keywords: set(ckeywords), funwords:funwords, builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"), atoms: set("false true null unknown"), operatorChars: /^[*+\-%<>!=&|^]/, dateSQL: set("date time timestamp"), support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"), hooks: { "@": hookVar, "`": hookIdentifier, "\\": hookClient } });
參考來源:https://blog.csdn.net/xiweiller/article/details/96494504