添加事件

qianlishi 2 years ago
parent dbbda1fbd2
commit 8348691e28

@ -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>

@ -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;

@ -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;

@ -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",
"FROM",
"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;

@ -58,7 +58,7 @@
<ColorPicker <ColorPicker
v-if="item.type == 'vue-color'" v-if="item.type == 'vue-color'"
v-model="formData[item.name]" v-model="formData[item.name]"
@change="val => changed(val, item.name)" @change="(val) => changed(val, item.name)"
/> />
<customUpload <customUpload
v-if="item.type == 'custom-upload'" v-if="item.type == 'custom-upload'"
@ -69,7 +69,7 @@
<el-radio-group <el-radio-group
v-if="item.type == 'el-radio-group'" v-if="item.type == 'el-radio-group'"
v-model="formData[item.name]" v-model="formData[item.name]"
@change="val => changed(val, item.name)" @change="(val) => changed(val, item.name)"
> >
<el-radio <el-radio
v-for="itemChild in item.selectOptions" v-for="itemChild in item.selectOptions"
@ -85,7 +85,7 @@
v-model="formData[item.name]" v-model="formData[item.name]"
clearable clearable
placeholder="请选择" placeholder="请选择"
@change="val => changed(val, item.name)" @change="(val) => changed(val, item.name)"
> >
<el-option <el-option
v-for="itemChild in item.selectOptions" v-for="itemChild in item.selectOptions"
@ -98,7 +98,7 @@
<el-slider <el-slider
v-if="item.type == 'el-slider'" v-if="item.type == 'el-slider'"
v-model="formData[item.name]" v-model="formData[item.name]"
@change="val => changed(val, item.name)" @change="(val) => changed(val, item.name)"
/> />
<el-button <el-button
@ -110,6 +110,14 @@
>编辑</el-button >编辑</el-button
> >
<el-button
v-if="item.type == 'methods'"
type="primary"
size="mini"
@click="methodsVisible = true"
>添加事件</el-button
>
<!-- 弹窗 --> <!-- 弹窗 -->
<el-dialog <el-dialog
title="代码编辑" title="代码编辑"
@ -131,6 +139,23 @@
<el-button type="primary" @click="saveData"> </el-button> <el-button type="primary" @click="saveData"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog
title="代码编辑"
:visible.sync="methodsVisible"
width="50%"
:before-close="handleClose"
>
<monaco-editor
v-model.trim="formData[item.name]"
language="javascript"
style="height: 500px"
/>
<span slot="footer" class="dialog-footer">
<el-button @click="methodsVisible = false"> </el-button>
<el-button type="primary" @click="saveData"> </el-button>
</span>
</el-dialog>
</el-form-item> </el-form-item>
<dynamicComponents <dynamicComponents
v-if="item.type == 'dycustComponents' && inputShow[item.name]" v-if="item.type == 'dycustComponents' && inputShow[item.name]"
@ -149,7 +174,8 @@
v-if="item.type == 'dynamic-add-radar' && inputShow[item.name]" v-if="item.type == 'dynamic-add-radar' && inputShow[item.name]"
v-model="formData[item.name]" v-model="formData[item.name]"
:chart-type="item.chartType" :chart-type="item.chartType"
@change="changed($event, item.name)"/> @change="changed($event, item.name)"
/>
</div> </div>
<div v-else-if="isShowForm(item, '[object Array]')" :key="'a-' + index"> <div v-else-if="isShowForm(item, '[object Array]')" :key="'a-' + index">
<el-collapse accordion> <el-collapse accordion>
@ -207,7 +233,7 @@
<ColorPicker <ColorPicker
v-if="itemChildList.type == 'vue-color'" v-if="itemChildList.type == 'vue-color'"
v-model="formData[itemChildList.name]" v-model="formData[itemChildList.name]"
@change="val => changed(val, itemChildList.name)" @change="(val) => changed(val, itemChildList.name)"
/> />
<el-upload <el-upload
@ -220,7 +246,7 @@
<el-radio-group <el-radio-group
v-if="itemChildList.type == 'el-radio-group'" v-if="itemChildList.type == 'el-radio-group'"
v-model="formData[itemChildList.name]" v-model="formData[itemChildList.name]"
@change="val => changed(val, itemChildList.name)" @change="(val) => changed(val, itemChildList.name)"
> >
<el-radio <el-radio
v-for="it in itemChildList.selectOptions" v-for="it in itemChildList.selectOptions"
@ -236,7 +262,7 @@
v-model="formData[itemChildList.name]" v-model="formData[itemChildList.name]"
clearable clearable
placeholder="请选择" placeholder="请选择"
@change="val => changed(val, itemChildList.name)" @change="(val) => changed(val, itemChildList.name)"
> >
<el-option <el-option
v-for="it in itemChildList.selectOptions" v-for="it in itemChildList.selectOptions"
@ -249,7 +275,7 @@
<el-slider <el-slider
v-if="itemChildList.type == 'el-slider'" v-if="itemChildList.type == 'el-slider'"
v-model="formData[itemChildList.name]" v-model="formData[itemChildList.name]"
@change="val => changed(val, itemChildList.name)" @change="(val) => changed(val, itemChildList.name)"
/> />
</el-form-item> </el-form-item>
<customColorComponents <customColorComponents
@ -282,6 +308,7 @@ import customColorComponents from "./customColorComponents";
import dynamicAddTable from "./dynamicAddTable.vue"; import dynamicAddTable from "./dynamicAddTable.vue";
import customUpload from "./customUpload.vue"; import customUpload from "./customUpload.vue";
import dynamicAddRadar from "./dynamicAddRadar"; import dynamicAddRadar from "./dynamicAddRadar";
import MonacoEditor from "@/components/MonacoEditor/index";
export default { export default {
name: "DynamicForm", name: "DynamicForm",
components: { components: {
@ -291,24 +318,26 @@ export default {
customColorComponents, customColorComponents,
dynamicAddTable, dynamicAddTable,
customUpload, customUpload,
dynamicAddRadar dynamicAddRadar,
MonacoEditor,
}, },
model: { model: {
prop: "value", prop: "value",
event: "input" event: "input",
}, },
props: { props: {
options: Array, options: Array,
value: { value: {
type: [Object], type: [Object],
default: () => {} default: () => {},
} },
}, },
data() { data() {
return { return {
formData: {}, formData: {},
inputShow: {}, // inputShow: {}, //
dialogVisibleStaticData: false, dialogVisibleStaticData: false,
methodsVisible: false,
validationRules: "", validationRules: "",
optionsJavascript: { optionsJavascript: {
mode: "text/javascript", mode: "text/javascript",
@ -318,9 +347,9 @@ export default {
styleActiveLine: true, // styleActiveLine: true, //
hintOptions: { hintOptions: {
completeSingle: true // completeSingle: true, //
} },
} },
}; };
}, },
watch: { watch: {
@ -330,7 +359,7 @@ export default {
options(val) { options(val) {
this.setDefaultValue(); this.setDefaultValue();
this.isShowData(); this.isShowData();
} },
}, },
created() { created() {
this.isShowData(); this.isShowData();
@ -365,6 +394,7 @@ export default {
saveData() { saveData() {
this.$emit("onChanged", this.formData); this.$emit("onChanged", this.formData);
this.dialogVisibleStaticData = false; this.dialogVisibleStaticData = false;
this.methodsVisible = false;
}, },
// //
addStaticData() { addStaticData() {
@ -372,6 +402,7 @@ export default {
}, },
handleClose() { handleClose() {
this.dialogVisibleStaticData = false; this.dialogVisibleStaticData = false;
this.methodsVisible = false;
}, },
// //
isShowData() { isShowData() {
@ -386,7 +417,7 @@ export default {
data.push(this.options[i]); data.push(this.options[i]);
} }
} }
data.forEach(el => { data.forEach((el) => {
if (el.relactiveDomValue != currentData.value) { if (el.relactiveDomValue != currentData.value) {
this.inputShow[el.name] = false; this.inputShow[el.name] = false;
} }
@ -404,7 +435,7 @@ export default {
} else if (Object.prototype.toString.call(obj) == "[object Array]") { } else if (Object.prototype.toString.call(obj) == "[object Array]") {
for (let j = 0; j < obj.length; j++) { for (let j = 0; j < obj.length; j++) {
const list = obj[j].list; const list = obj[j].list;
list.forEach(el => { list.forEach((el) => {
this.formData[el.name] = el.value; this.formData[el.name] = el.value;
}); });
} }
@ -416,8 +447,8 @@ export default {
// //
isShowForm(val, type) { isShowForm(val, type) {
return Object.prototype.toString.call(val) == type; return Object.prototype.toString.call(val) == type;
} },
} },
}; };
</script> </script>

@ -270,6 +270,17 @@
@onChanged="(val) => widgetValueChanged('position', val)" @onChanged="(val) => widgetValueChanged('position', val)"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane
v-if="isNotNull(widgetOptions.methods)"
name="four"
label="方法"
>
<dynamicForm
ref="formData"
:options="widgetOptions.methods"
@onChanged="(val) => widgetValueChanged('methods', val)"
/>
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -360,6 +371,7 @@ export default {
top: 0, top: 0,
zIndex: 0, zIndex: 0,
}, },
methods: {},
}, },
// optionstools // optionstools
options: [], options: [],

@ -3,8 +3,8 @@
* @version: * @version:
* @Author: qianlishi * @Author: qianlishi
* @Date: 2021-08-29 07:21:45 * @Date: 2021-08-29 07:21:45
* @LastEditors: qianlishi * @LastEditors: qianlishi qianlishi@anji-plus.com
* @LastEditTime: 2021-09-28 14:08:29 * @LastEditTime: 2023-01-09 09:53:31
*/ */
export const widgetBarchart = { export const widgetBarchart = {
code: 'widget-barchart', code: 'widget-barchart',
@ -652,5 +652,20 @@ export const widgetBarchart = {
value: 200, value: 200,
}, },
], ],
// 事件
methods: [
{
type: 'methods',
label: '前置钩子',
name: 'beforeMethods',
value: 'function beforeMethods(data){\n\t//自定义脚本内容1\n\treturn data;\n}',
},
{
type: 'methods',
label: '后置钩子',
name: 'afterMethods',
value: 'function afterMethods(data){\n\t//自定义脚本内容2\n\treturn data;\n}',
},
]
} }
} }

Loading…
Cancel
Save