Commit 815f0ac8 authored by 王晓铜's avatar 王晓铜

添加监控sql编辑器

parent c83536d5
......@@ -2,7 +2,7 @@ import holmesRequest from '@/utils/holmesRequest'
// 获取sql监控列表
export function getSqlMonitorList(queryInfo) {
return holmesRequest({
url: '/monitor/task/list',
url: '/sql/monitor/list',
method: 'get',
params: queryInfo
})
......@@ -55,3 +55,19 @@ export function getSqlMonitorData(queryInfo) {
params: queryInfo
})
}
// 获取执行策略列表
export function getMonitorStrategy(queryInfo) {
return holmesRequest({
url: '/sql/monitor/strategy',
method: 'get',
params: queryInfo
})
}
// 启用、禁用接口
export function isEnableSqlMonitor(data) {
return holmesRequest({
url: '/sql/monitor/enable',
method: 'post',
data
})
}
......@@ -19,7 +19,9 @@ import hljs from 'highlight.js'
import 'highlight.js/styles/googlecode.css'
// 引用sql编辑器(2021-12-30)
import AFTableColumn from 'af-table-column'
import Plugin from 'v-fit-columns'
import { codemirror } from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
// import Sortable from 'sortablejs'
import {
......@@ -78,10 +80,11 @@ Vue.directive('highlight', function(el) {
})
// 设置自适应宽度的比率
const fontRate = {
CHAR_RATE: 0.1,
NUM_RATE: 0.1,
OTHER_RATE: 0.1
CHAR_RATE: 0.4,
NUM_RATE: 0.6,
OTHER_RATE: 0.6
}
const fontSize = 16
Vue.config.productionTip = false
......@@ -141,9 +144,8 @@ Vue.use(Checkbox)
Vue.use(CheckboxGroup)
Vue.use(Popover)
Vue.use(Alert)
Vue.use(AFTableColumn, fontRate)
Vue.use(Plugin)
Vue.use(AFTableColumn, { fontRate, fontSize })
Vue.use(codemirror)
// Vue.use(Sortable)
/* eslint-disable no-new */
......
<template>
<div>
<el-card>
<el-form ref="sqlMonitorFormRef" :model="sqlMonitorForm" label-width="90px">
<el-form-item label="模块名称:" style="width:400px">
<el-form ref="sqlMonitorFormRef" :rules="rules" :model="sqlMonitorForm" label-width="90px">
<el-form-item label="监控名称:" style="width:400px" prop="taskName">
<el-input v-model="sqlMonitorForm.taskName" placeholder="请输入监控名称"></el-input>
</el-form-item>
<el-form-item label="数据源:">
<el-form-item label="数据源:" prop="dsId">
<el-select v-model="sqlMonitorForm.dsId" placeholder="请选择数据源" style="width:310px" clearable>
<el-option v-for="item in dataSourceList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="SQL脚本:">
<textarea v-model="sqlMonitorForm.sql" placeholder="请数据sql语句" style="height:200px;width:600px"></textarea>
<el-form-item>
<el-button @click="sqlFormat">格式化</el-button>
</el-form-item>
<el-form-item label="SQL脚本:" prop="sql">
<!-- <textarea ref="mycode" v-model="sqlMonitorForm.sql" placeholder="请输入sql语句"
style="height:200px;width:600px"></textarea> -->
<codemirror ref="editQuerySQL" v-model="sqlMonitorForm.sql" :options="cmOptions" class="code"></codemirror>
</el-form-item>
<el-form-item style="margin-left:1000px">
<el-button type="primary" icon="el-icon-caret-right" @click="executeSqlBtn">执行</el-button>
......@@ -19,8 +24,9 @@
</el-form-item>
<el-form-item style="margin-left:-80px">
<!-- 动态绑定表格数据 -->
<el-table :data="sqlList" border style="font-size:10px;" :header-cell-style="{background:'#eee',color:'#606266'}">
<af-table-column v-for="(val, key) in columnArr" :label="val" :prop="val" :key="key">
<el-table :data="sqlList" border style="font-size:8px;"
:header-cell-style="{background:'#eee',color:'#606266'}" v-if="isShow">
<af-table-column v-for="(val, key) in columnArr" :label="val" :prop="val" :key="key" :fontRate="fontRate">
</af-table-column>
</el-table>
</el-form-item>
......@@ -28,91 +34,248 @@
</el-card>
<!-- 设置报警页面 -->
<el-dialog title="报警策略" :visible.sync="DialogVisible" width="50%">
<el-form ref="sqlMonitorFormRef" :model="sqlMonitorForm" label-width="90px">
<el-form-item label="执行策略:" style="width:500px">
<el-input v-model="sqlMonitorForm.taskCron"></el-input>
<el-form ref="sqlMonitorFormRef" :rules="rules" :model="sqlMonitorForm" label-width="90px">
<el-form-item label="服务名称:" prop="serviceName">
<el-select v-model="sqlMonitorForm.serviceName" placeholder="请选择服务名称" style="width:310px" filterable
clearable>
<el-option v-for="item in serviceList" :key="item.name" :label="item.name" :value="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="执行策略:" prop="taskCron">
<el-select v-model="sqlMonitorForm.taskCron" placeholder="请选择策略" style="width:310px" clearable>
<el-option v-for="item in taskCronList" :key="item.value" :value="item.value" :label="item.label">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="钉钉地址:" style="width:600px">
<el-form-item label="钉钉地址:" style="width:800px" prop="dingUrl">
<el-input v-model="sqlMonitorForm.dingUrl" placeholder="请输入钉钉通知地址" type="textarea" :rows="3">
</el-input>
</el-form-item>
<el-form-item label="消息内容:" style="width:600px">
<el-input v-model="sqlMonitorForm.dingText"
placeholder="请输入报警内容,{count}表示查出来的数据,{0}表示第一行第一列,{1}表示第一行第2列,依次类推,{n}表示第一行第n列" type="textarea" :rows="3">
<el-form-item label="消息内容:" style="width:800px" prop="dingText">
<el-input v-model="sqlMonitorForm.dingText" placeholder="可以使用表达式{0},{1}...表示取结果集的第N列值,使用{count}表示取数据总条数"
type="textarea" :rows="3">
</el-input>
</el-form-item>
<el-form-item label="是否启用:" style="width:500px">
<el-input v-model="sqlMonitorForm.status"></el-input>
<el-form-item label="是否启用:">
<el-select v-model="sqlMonitorForm.status" placeholder="请选择是否启用" style="width:310px">
<el-option v-for="item in enableList" :label="item.lable" :key="item.value" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="DialogVisible=false">取 消</el-button>
<el-button type="primary" @click="sendTest">发送测试</el-button>
<el-button type="primary" @click="saveSqlMonitorFrom">保 存</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { getSqlMonitorData, executeSqlMonitor } from '@/api/sqlMonitor'
import 'codemirror/theme/ambiance.css'
import {
getSqlMonitorData,
executeSqlMonitor,
getMonitorStrategy,
sendTestSqlMonitor,
addSqlMonitor,
editSqlMonitor
} from '@/api/sqlMonitor'
import { getGitProjectList } from '@/api/jira'
import { mapGetters } from 'vuex'
// 编辑器引用
// import { codemirror } from 'vue-codemirror'
// import 'codemirror/lib/codemirror.css'
// import 'codemirror/theme/base16-light.css'
// import 'codemirror/addon/hint/show-hint.css'
// import 'codemirror/theme/ambiance.css'
// let CodeMirror = require('codemirror/lib/codemirror')
// require('codemirror/mode/sql/sql.js')
// require('codemirror/addon/edit/matchbrackets')
// require('codemirror/addon/selection/active-line')
// require('codemirror/mode/sql/sql')
// require('codemirror/addon/hint/show-hint')
// require('codemirror/addon/hint/sql-hint')
// require('codemirror/addon/hint/sql-hint.js')
// require('codemirror/addon/hint/show-hint.js')
// require('codemirror/addon/selection/active-line.js')
// import sqlFormatter from 'sql-formatter'
import { codemirror } from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/idea.css'
import 'codemirror/theme/panda-syntax.css'
import 'codemirror/addon/hint/show-hint.css'
import sqlFormatter from 'sql-formatter'
let CodeMirror = require('codemirror/lib/codemirror')
require('codemirror/addon/edit/matchbrackets')
require('codemirror/addon/selection/active-line')
require('codemirror/lib/codemirror')
require('codemirror/mode/sql/sql')
require('codemirror/addon/hint/show-hint')
require('codemirror/addon/hint/sql-hint')
export default {
components: { codemirror },
name: 'codeMirror',
computed: {
...mapGetters({
// 获取用户名称(可当作全局变量使用)
getUserName: 'user/chineseName'
})
},
data() {
return {
sqlMonitorForm: {},
cmOptions: {
tabSize: 4,
lineNumbers: true,
line: true,
indentWithTabs: true,
smartIndent: true,
autofocus: false,
mode: 'text/x-mysql',
theme: 'idea',
hintOptions: {
completeSingle: false
}
},
isShow: false,
sqlMonitorForm: {
id: '',
taskName: '',
taskCron: '',
sql: '',
dsId: '',
dingUrl: '',
dingText: '',
status: 1,
serviceName: ''
// owner: this.getUserName
},
dataSourceList: [],
sqlList: [],
DialogVisible: false,
columnArr: []
columnArr: [],
taskCronList: [],
serviceList: [],
enableList: [
{
lable: '启用',
value: 1
},
{
lable: '禁用',
value: 0
}
],
rules: {
taskName: [
{
required: true,
message: '监控名称不能为空!',
trigger: 'blur'
}
],
dsId: [
{
required: true,
message: '数据源不能为空!',
trigger: 'blur'
}
],
sql: [
{
required: true,
message: 'sql脚本不能为空!',
trigger: 'blur'
}
],
serviceName: [
{
required: true,
message: '服务名称不能为空!',
trigger: 'blur'
}
],
taskCron: [
{
required: true,
message: '执行策略不能为空!',
trigger: 'blur'
}
],
dingUrl: [
{
required: true,
message: '钉钉地址不能为空!',
trigger: 'blur'
}
]
}
}
},
// 初始化sql编辑器
mounted() {
let mime = 'text/x-mysql'
// let theme = 'ambiance'//设置主题,不设置的会使用默认主题
let editor = CodeMirror.fromTextArea(this.$refs.mycode, {
mode: mime, // 选择对应代码编辑器的语言,我这边选的是数据库,根据个人情况自行设置即可
tabSize: 2,
indentWithTabs: true,
// 自动缩进
smartIndent: true,
// 显示行号
lineNumbers: true,
// 匹配结束符号
matchBrackets: true,
// theme: theme,
// 自动聚焦
autofocus: true,
// 自定义快捷键
// extraKeys: { Ctrl: 'autocomplete' }, // 自定义快捷键
// hint: CodeMirror.hint.sql,
hintOptions: {
// 自定义提示选项
// tables: {
// users: ['name', 'score', 'birthDate'],
// countries: ['name', 'population', 'size']
// }
tables: window.tablewords
}
})
// 代码自动提示功能,记住使用cursorActivity事件不要使用change事件,这是一个坑,那样页面直接会卡死 cursorActivity
editor.on('cursorActivity', function (cm, event) {
editor.showHint()
})
// 接收列表页面传递的参数
activated() {
var data = this.$route.query.data
// console.log('rrr', data)
if (data === 'add') {
this.sqlMonitorForm = {}
this.sqlMonitorForm.status = 1
} else {
this.sqlMonitorForm.id = data.id
this.sqlMonitorForm.dingText = data.dingText
this.sqlMonitorForm.dingUrl = data.dingUrl
this.sqlMonitorForm.dsId = data.dsId
this.sqlMonitorForm.serviceName = data.serviceName
this.sqlMonitorForm.sql = data.sql
this.sqlMonitorForm.status = data.status
this.sqlMonitorForm.taskCron = data.taskCron
this.sqlMonitorForm.taskName = data.taskName
}
},
created() {
this.getSqlMonitorDataSource()
},
mounted() {
// let mime = 'text/x-mariadb'
// // let theme = 'ambiance'//设置主题,不设置的会使用默认主题
// this.editor = CodeMirror.fromTextArea(this.$refs.mycode, {
// mode: mime, // 选择对应代码编辑器的语言,我这边选的是数据库,根据个人情况自行设置即可
// tabSize: 2,
// indentWithTabs: true,
// // 自动缩进
// smartIndent: true,
// // 显示行号
// lineNumbers: true,
// // 匹配结束符号
// matchBrackets: true,
// // theme: theme,
// // 自动聚焦
// autofocus: true,
// // 自定义快捷键
// // extraKeys: { Ctrl: 'autocomplete' }, // 自定义快捷键
// // hint: CodeMirror.hint.sql,
// hintOptions: {
// // 自定义提示选项
// tables: {
// users: ['name', 'score', 'birthDate'],
// countries: ['name', 'population', 'size']
// }
// // tables: window.tablewords
// }
// })
// 代码自动提示功能,记住使用cursorActivity事件不要使用change事件,这是一个坑,那样页面直接会卡死 cursorActivity
this.editQuerySQL.on('cursorActivity', function () {
console.log('iii', this.editQuerySQL)
this.editQuerySQL.showHint()
})
},
methods: {
sqlFormat() {
// let sqlContent = ''
// sqlContent = this.editor.getValue()
// /* 将sql内容进行格式后放入编辑器中 */
// this.editor.setValue(sqlFormatter.format(sqlContent))
},
// 获取数据源列表
getSqlMonitorDataSource() {
getSqlMonitorData().then((resp) => {
......@@ -120,14 +283,9 @@ export default {
// console.log('www', resp)
})
},
format() {
let sqlContent = ''
sqlContent = this.editor.getValue()
/* 将sql内容进行格式后放入编辑器中 */
this.editor.setValue(sqlFormatter.format(sqlContent))
},
// 执行sqla按钮
executeSqlBtn() {
console.log('sql值', this.sqlMonitorForm.sql)
var formData = new FormData()
formData.set('dsId', this.sqlMonitorForm.dsId)
formData.set('sql', this.sqlMonitorForm.sql)
......@@ -136,9 +294,11 @@ export default {
var data = resp.data.data
this.sqlList = data
if (data.length) {
this.isShow = true
// 获取表格第一行数据
const row = data[0]
const columnArr = []
// 循环获第一行的表头数据
// 循环获第一行的表头数据
for (let i in row) {
columnArr.push(i)
}
......@@ -149,9 +309,66 @@ export default {
// 点击设置报警按钮
setPoliceBtn() {
this.DialogVisible = true
this.getMonitorStrategy()
this.getServiceList()
},
// 发送测试按钮
sendTest() {
sendTestSqlMonitor(this.sqlMonitorForm).then((resp) => {
if (resp.data.businessCode === '0000') {
return this.$message.success(resp.data.msg)
} else {
return this.$message.error(resp.data.msg)
}
})
},
// 获取执行策略列表
getMonitorStrategy() {
getMonitorStrategy().then((resp) => {
this.taskCronList = resp.data.data
console.log('ww', this.taskCronList)
})
},
// 获取服务列表
getServiceList() {
getGitProjectList().then((resp) => {
this.serviceList = resp.data.data
})
},
// 保存按钮
saveSqlMonitorFrom() {}
saveSqlMonitorFrom() {
this.sqlMonitorForm.owner = this.getUserName
this.sqlMonitorForm.taskClass = 'SqlMonitorHandler'
// console.log('参数', this.sqlMonitorForm)
// 编辑接口
if (this.sqlMonitorForm.id) {
editSqlMonitor(this.sqlMonitorForm).then((resp) => {
if (resp.data.businessCode === '0000') {
this.$message.success('编辑成功!')
this.$router.push({
path: `/monitor/sqlMonitorList`,
query: { data: 'refresh' }
})
} else {
return this.$message.error(resp.data.msg)
}
})
} else {
// 添加接口
addSqlMonitor(this.sqlMonitorForm).then((resp) => {
if (resp.data.businessCode === '0000') {
this.$message.success('添加成功!')
this.$router.push({
path: `/monitor/sqlMonitorList`,
query: { data: 'refresh' }
})
} else {
return this.$message.error(resp.data.msg)
}
})
}
// 添加接口
}
}
}
</script>
......
......@@ -19,7 +19,13 @@
</template>
</el-table-column>
<el-table-column label="监控名称" prop="taskName" width="180px"></el-table-column>
<el-table-column label="执行策略" prop="taskCron" width="180px"></el-table-column>
<el-table-column label="执行策略" prop="taskCron" width="180px">
<template slot-scope="scope">
<p v-if="scope.row.taskCron==='0 0 * * * ?'">每小时执行一次</p>
<p v-if="scope.row.taskCron==='0 0 10 * * ?'">每天10点执行一次</p>
<p v-if="scope.row.taskCron==='0 0 10 ? * 2'">每周一上午10点执行一次</p>
</template>
</el-table-column>
<el-table-column label="sql" width="150px">
<template slot-scope="scope">
<el-popover placement="top-start" title="sql" width="50" trigger="hover" :content="scope.row.sql">
......@@ -27,7 +33,7 @@
</el-popover>
</template>
</el-table-column>
<el-table-column label="服务名称" prop="serviceName" width="100px"></el-table-column>
<el-table-column label="服务名称" prop="serviceName" width="150px"></el-table-column>
<el-table-column label="数据源" prop="dsName" width="80px"></el-table-column>
<el-table-column label="负责人" prop="owner" width="80px"></el-table-column>
<el-table-column label="当前状态" width="80px">
......@@ -39,12 +45,17 @@
<el-table-column label="创建时间" prop="createTime" width="180px"></el-table-column>
<el-table-column label="操作">
<slot slot-scope="scope">
<el-button type="warning" icon="el-icon-edit" @click="openEditDialog(scope.row)"
<el-button type="warning" icon="el-icon-edit" @click="openEditMonitorDialog(scope.row)"
v-permission="('monitor:sql:edit')">编辑</el-button>
<el-button type="success" icon="el-icon-success" @click="openEditDialog(scope.row)"
v-permission="('monitor:sql:enable')" style="margin-left:1px">启用</el-button>
<el-button type="info" icon="el-icon-error" @click="enableDislog(scope.row)"
v-permission="('monitor:sql:enable')" v-if="scope.row.status===1">禁用</el-button>
<el-button type="success" icon="el-icon-success" @click="unenableDialog(scope.row)"
v-permission="('monitor:sql:enable')" v-if="scope.row.status===0">启用</el-button>
<el-button type="danger" icon="el-icon-delete" @click="delSqlMonitor(scope.row)"
v-permission="('monitor:sql:del')" style="margin-left:1px">删除</el-button>
v-permission="('monitor:sql:del')">删除</el-button>
</slot>
</el-table-column>
</el-table>
......@@ -56,7 +67,11 @@
</div>
</template>
<script>
import { getSqlMonitorList, delSqlMonitor } from '@/api/sqlMonitor'
import {
getSqlMonitorList,
delSqlMonitor,
isEnableSqlMonitor
} from '@/api/sqlMonitor'
import { getGitProjectList } from '@/api/jira'
export default {
data() {
......@@ -72,6 +87,13 @@ export default {
serviceList: []
}
},
// 接收参数
activated() {
var data = this.$route.query.data
if (data === 'refresh') {
this.getSqlMonitorList()
}
},
created() {
this.getSqlMonitorList()
this.getServiceList()
......@@ -82,7 +104,6 @@ export default {
getSqlMonitorList(this.queryModuleInfo).then((resp) => {
this.sqlMonitorList = resp.data.data.list
this.totalNum = resp.data.data.total
// console.log('返回信息', resp)
})
},
// 查询按钮
......@@ -92,7 +113,19 @@ export default {
// 添加按钮
addSqlMonitor() {
this.$router.push({
path: `/monitor/addSqlMonitor`
path: `/monitor/addSqlMonitor`,
query: {
data: 'add'
}
})
},
// 编辑按钮
openEditMonitorDialog(row) {
this.$router.push({
path: `/monitor/addSqlMonitor`,
query: {
data: row
}
})
},
// 获取服务列表
......@@ -131,6 +164,39 @@ export default {
})
})
},
// 禁用按钮
enableDislog(row) {
var formData = new FormData()
formData.set('taskId', row.id)
formData.set('status', 0)
this.openMessage('是否需要禁用?', '确定', () => {
isEnableSqlMonitor(formData).then((resp) => {
if (resp.data.businessCode === '0000') {
this.getSqlMonitorList()
return this.$message.success(resp.data.msg)
} else {
return this.$message.error(resp.data.msg)
}
})
})
},
// 启用按钮
unenableDialog(row) {
this.openMessage('是否需要启用?', '确定', () => {
var formData = new FormData()
formData.set('taskId', row.id)
formData.set('status', 1)
isEnableSqlMonitor(formData).then((resp) => {
console.log('999', resp)
if (resp.data.businessCode === '0000') {
this.getSqlMonitorList()
return this.$message.success(resp.data.msg)
} else {
return this.$message.error(resp.data.msg)
}
})
})
},
handleSizeChange(newSize) {
this.queryModuleInfo.pageSize = newSize
......
......@@ -176,7 +176,6 @@
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
......
......@@ -394,7 +394,7 @@ export default {
)
this.addTestDescriptionForm.apollo = JSON.stringify(this.apolloList)
this.addTestDescriptionForm.database = JSON.stringify(this.databaseList)
console.log('88888', this.addTestDescriptionForm)
// console.log('88888', this.addTestDescriptionForm)
this.$refs.addTestDescriptionRef.validate((valid) => {
if (!valid) {
return false
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment