Signed-off-by: chy <chy@163.com>

This commit is contained in:
chy
2026-02-02 23:28:29 +08:00
commit 84bdfdb8bc
576 changed files with 941155 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
<!--
* @Descripttion:
* @version:
* @Author: Raod
* @Date: 2021-8-4 14:48:27
* @LastEditors: qianlishi
* @LastEditTime: 2021-12-13 18:48:24
-->
<template>
<el-dialog
:title="caseResultTitle"
:close-on-click-modal="false"
:visible.sync="visib"
width="70%"
:before-close="closeDialog"
>
<vue-json-editor
v-model="caseResultContent"
:show-btns="false"
:mode="'code'"
lang="zh"
class="my-editor"
@json-change="onJsonChange"
@json-save="onJsonSave"
/>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="closeDialog">关闭</el-button>
</span>
</el-dialog>
</template>
<script>
import vueJsonEditor from "vue-json-editor";
export default {
name: "Support",
components: { vueJsonEditor },
props: {
visib: {
required: true,
type: Boolean,
default: false
}
},
data() {
return {
dialogCaseResult: false,
caseResultTitle: "",
caseResultContent: null
};
},
methods: {
dataViewPreview(caseResultTitle, caseResultContent) {
this.caseResultTitle = caseResultTitle;
this.caseResultContent = caseResultContent;
},
// 关闭模态框
closeDialog() {
this.$emit("handleClose");
},
onJsonChange(value) {},
onJsonSave(value) {}
}
};
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,140 @@
<!--
* @Descripttion:
* @version:
* @Author: qianlishi
* @Date: 2021-8-6 14:48:27
* @LastEditors: qianlishi
* @LastEditTime: 2021-12-13 18:48:24
-->
<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 lang="scss">
.main .view-lines * {
font-family: Consolas, "Courier New", monospace !important;
}
</style>

View File

@@ -0,0 +1,83 @@
<!--
* @Descripttion:
* @version:
* @Author: qianlishi
* @Date: 2022-05-17 16:55:05
* @LastEditors: qianlishi
* @LastEditTime: 2022-05-17 17:38:54
-->
<template>
<el-dialog
class="tree_dialog"
title="数据集--复制"
width="30%"
:close-on-click-modal="false"
center
:visible.sync="visib"
:before-close="close"
>
<el-form
:model="form"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="数据集名称" prop="setName">
<el-input v-model="form.setName" />
</el-form-item>
<el-form-item label="数据集编码" prop="setCode">
<el-input v-model="form.setCode" />
</el-form-item>
</el-form>
<div slot="footer" style="text-align: center">
<el-button type="danger" plain @click="close">取消</el-button>
<el-button type="primary" plain @click="save">保存</el-button>
</div>
</el-dialog>
</template>
<script>
import {reportDataSetCopy} from "@/api/reportDataSet"
export default {
props: {
visib: Boolean,
rowData: Object
},
data() {
return {
form: {},
rules: {
setName: [
{ required: true, message: "请输入数据集名称", trigger: "blur" }
],
setCode: [
{ required: true, message: "请输入数据集编码", trigger: "blur" }
]
}
};
},
watch: {
visib(val) {
this.form = this.deepClone(this.rowData);
this.form.setCode = this.form.setCode + "_" + Date.now();
}
},
methods: {
save() {
this.$refs.ruleForm.validate(async valid => {
if (valid) {
const { code } = await reportDataSetCopy(this.form);
if (code != "200") {
return;
}
this.$message.success("复制成功");
this.close();
}
});
},
close() {
this.$emit("close");
}
}
};
</script>

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,341 @@
<!--
* @Descripttion: 用户权限--数据集
* @version:
* @Author: qianlishi
* @Date: 2021-12-11 14:48:27
* @LastEditors: qianlishi
* @LastEditTime: 2022-04-14 18:48:24
-->
<template>
<anji-crud ref="listPage" :option="crudOption">
<template v-slot:tableButtons>
<el-dropdown placement="bottom" @command="operateDataset">
<el-button type="primary" icon="el-icon-plus">
新增
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="sql">SQL</el-dropdown-item>
<el-dropdown-item command="http">HTTP</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<template v-slot:pageSection>
<EditDataSet
ref="EditDataSet"
:dataSet="dataSet"
:visib="dialogVisibleSetDataSet"
@handleClose="dialogVisibleSetDataSet = false"
@refreshList="refreshList"
/>
<DataView
ref="DataView"
:visib="dialogCaseResult"
@handleClose="dialogCaseResult = false"
/>
<copyDialog :visib.sync="copyVisible" :rowData="rowData" @close="close" />
</template>
</anji-crud>
</template>
<script>
import {
reportDataSetList,
reportDataSetAdd,
reportDataSetDeleteBatch,
reportDataSetUpdate,
reportDataSetDetail,
reportDataSetCopy
} from "@/api/reportDataSet";
import EditDataSet from "./components/EditDataSet";
import DataView from "./components/DataView";
import copyDialog from "./components/copyDialog.vue";
export default {
name: "ReportDataSet",
components: {
EditDataSet: EditDataSet,
DataView: DataView,
copyDialog
},
data() {
return {
dialogVisibleSetDataSet: false,
dataSet: {},
dialogCaseResult: false,
crudOption: {
// 使用菜单做为页面标题
title: "数据集",
// 详情页中输入框左边文字宽度
labelWidth: "120px",
// 查询表单条件
queryFormFields: [
{
inputType: "input",
label: "数据集编码",
field: "setCode"
},
{
inputType: "input",
label: "数据集名称",
field: "setName"
},
{
inputType: "anji-select", //form表单类型 input|input-number|anji-select(传递url或者dictCode)|anji-tree(左侧树)|date|datetime|datetimerange
anjiSelectOption: {
url: "/dataSource/queryAllDataSource",
label: "sourceName",
option: "sourceCode",
mergeLabel: true
},
label: "数据源",
field: "sourceCode"
},
{
inputType: "anji-select", //form表单类型 input|input-number|anji-select(传递url或者dictCode)|anji-tree(左侧树)|date|datetime|datetimerange
anjiSelectOption: {
dictCode: "SET_TYPE"
},
label: "数据集类型",
field: "setType"
}
],
// 表头按钮
tableButtons: [
{
label: "删除",
type: "danger",
permission: "resultsetManage:delete",
icon: "el-icon-delete",
plain: false,
click: () => {
return this.$refs.listPage.handleDeleteBatch();
}
}
],
// 表格行按钮
rowButtons: [
{
label: "编辑",
permission: "resultsetManage:update",
click: row => {
return this.operateDataset("edit", row);
}
},
{
label: "数据预览",
permission: "resultsetManage:query",
click: this.dataView
},
{
label: "复制",
permission: "resultsetManage:copy",
click: this.copyDataSet
},
{
label: "删除",
permission: "resultsetManage:delete",
click: row => {
return this.$refs.listPage.handleDeleteBatch(row);
}
}
],
// 操作按钮
buttons: {
rowButtonsWidth: 180, // row自定义按钮表格宽度
query: {
api: reportDataSetList,
permission: "resultsetManage:query",
sort: "update_time",
order: "DESC"
},
queryByPrimarykey: {
api: reportDataSetDetail,
permission: "resultsetManage:detail"
},
add: {
api: reportDataSetAdd,
permission: "resultsetManage:insert",
isShow: false
},
delete: {
api: reportDataSetDeleteBatch,
permission: "resultsetManage:delete"
},
edit: {
api: reportDataSetUpdate,
permission: "resultsetManage:update",
isShow: false
}
},
// 表格列
columns: [
{
label: "",
field: "id",
primaryKey: true, // 根据主键查询详情或者根据主键删除时, 主键的
tableHide: true, // 表格中不显示
editHide: true // 编辑弹框中不显示
},
{
label: "数据集编码", //数据集编码
placeholder: "",
field: "setCode",
editField: "setCode",
inputType: "input",
rules: [
{ min: 1, max: 50, message: "不超过50个字符", trigger: "blur" }
],
disabled: false
},
{
label: "数据集名称", //数据集名称
placeholder: "",
field: "setName",
editField: "setName",
inputType: "input",
rules: [
{ min: 1, max: 100, message: "不超过100个字符", trigger: "blur" }
],
disabled: false
},
{
label: "描述", //数据集描述
placeholder: "",
field: "setDesc",
editField: "setDesc",
inputType: "input",
rules: [
{ min: 1, max: 255, message: "不超过255个字符", trigger: "blur" }
],
disabled: false
},
{
label: "数据源编码", //数据源编码
placeholder: "",
field: "sourceCode",
editField: "sourceCode",
inputType: "input",
rules: [
{ min: 1, max: 50, message: "不超过50个字符", trigger: "blur" }
],
disabled: false
},
{
label: "数据集类型", //数据源编码
placeholder: "",
field: "setType",
editField: "setType",
inputType: "input",
rules: [
{ min: 1, max: 50, message: "不超过50个字符", trigger: "blur" }
],
disabled: false
},
{
label: "动态查询sql或者接口中的请求体", //动态查询sql或者接口中的请求体
placeholder: "",
field: "dynSentence",
editField: "dynSentence",
tableHide: true,
inputType: "input",
rules: [
{
min: 1,
max: 2048,
message: "不超过2048个字符",
trigger: "blur"
}
],
disabled: false
},
{
label: "结果案例", //结果案例
placeholder: "",
field: "caseResult",
tableHide: true,
editField: "caseResult",
inputType: "input",
rules: [
{
min: 1,
max: 65535,
message: "不超过65535个字符",
trigger: "blur"
}
],
disabled: false
},
{
label: "状态", //0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG
placeholder: "",
field: "enableFlag",
fieldTableRowRenderer: row => {
return this.getDictLabelByCode("ENABLE_FLAG", row["enableFlag"]);
},
colorStyle: {
0: "table-danger", //key为editField渲染的值字典的提交值'红色': 'danger','蓝色': 'primary','绿色': 'success','黄色': 'warning','灰色': 'info','白色'''
1: "table-success"
},
editField: "enableFlag",
inputType: "input",
rules: [],
disabled: false
},
{
label: "删除标记", //0--未删除 1--已删除 DIC_NAME=DELETE_FLAG
placeholder: "",
field: "deleteFlag",
editField: "deleteFlag",
tableHide: true,
inputType: "input",
rules: [],
disabled: false
}
]
},
// 复制
copyVisible: false,
rowData: {}
};
},
methods: {
operateDataset(type, prop) {
this.dialogVisibleSetDataSet = true;
if (prop && prop.setType) {
this.dataSet = prop;
type = prop.setType;
} else {
this.dataSet = {};
}
this.$refs.EditDataSet.addOrEditDataSet(this.dataSet, type);
},
refreshList() {
this.$refs.listPage.handleQueryForm("query");
},
dataView(prop) {
this.dialogCaseResult = true;
this.$refs.DataView.dataViewPreview(
prop.setName,
JSON.parse(prop.caseResult)
);
},
//复制
async copyDataSet(val) {
this.copyVisible = true;
this.rowData = val;
},
close() {
this.copyVisible = false;
this.$refs.listPage.handleQueryForm("query");
}
}
};
</script>
<style lang="scss">
.el-dropdown {
margin-right: 20px;
}
</style>