This commit is contained in:
parent
4a4ff0df10
commit
4b3e8e4dbe
|
@ -14,7 +14,7 @@
|
|||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@element-plus/icons": "^0.0.11",
|
||||
"axios": "^1.4.0",
|
||||
"codemirror": "^6.0.1",
|
||||
"codemirror-editor-vue3": "^2.3.0",
|
||||
"element-plus": "^2.3.5",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"jsplumb": "^2.15.6",
|
||||
|
@ -23,9 +23,8 @@
|
|||
"sass": "^1.62.1",
|
||||
"vform3-builds": "^3.0.10",
|
||||
"vue": "^3.2.47",
|
||||
"vue-codemirror": "^6.1.1",
|
||||
"vue-router": "4",
|
||||
"vuedraggable": "^2.24.3"
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.1.0",
|
||||
|
|
BIN
public.zip
BIN
public.zip
Binary file not shown.
17
src/App.vue
17
src/App.vue
|
@ -1,5 +1,20 @@
|
|||
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 4px;
|
||||
background: #8f8f8f;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
}
|
||||
</style>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
|
@ -0,0 +1,193 @@
|
|||
<template>
|
||||
<div class="codemirror">
|
||||
<codemirror
|
||||
ref="codemirror"
|
||||
v-model:value="code"
|
||||
:options="cmOption"
|
||||
:autofocus="true"
|
||||
@cursorActivity="onCmCursorActivity"
|
||||
@ready="onCmReady"
|
||||
@focus="onCmFocus"
|
||||
@blur="onCmBlur"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Codemirror from "codemirror-editor-vue3";
|
||||
|
||||
// base style
|
||||
import "codemirror/lib/codemirror.css";
|
||||
|
||||
// language
|
||||
import "codemirror/mode/vue/vue.js";
|
||||
|
||||
// active-line.js
|
||||
import "codemirror/addon/selection/active-line.js";
|
||||
|
||||
// styleSelectedText
|
||||
import "codemirror/addon/selection/mark-selection.js";
|
||||
import "codemirror/addon/search/searchcursor.js";
|
||||
|
||||
// highlightSelectionMatches
|
||||
import "codemirror/addon/scroll/annotatescrollbar.js";
|
||||
import "codemirror/addon/search/matchesonscrollbar.js";
|
||||
import "codemirror/addon/search/searchcursor.js";
|
||||
import "codemirror/addon/search/match-highlighter.js";
|
||||
|
||||
// keyMap
|
||||
import "codemirror/mode/clike/clike.js";
|
||||
import "codemirror/addon/edit/matchbrackets.js";
|
||||
import "codemirror/addon/comment/comment.js";
|
||||
import "codemirror/addon/dialog/dialog.js";
|
||||
import "codemirror/addon/dialog/dialog.css";
|
||||
import "codemirror/addon/search/searchcursor.js";
|
||||
import "codemirror/addon/search/search.js";
|
||||
import "codemirror/keymap/sublime.js";
|
||||
|
||||
// foldGutter
|
||||
import "codemirror/addon/fold/foldgutter.css";
|
||||
import "codemirror/addon/fold/brace-fold.js";
|
||||
import "codemirror/addon/fold/comment-fold.js";
|
||||
import "codemirror/addon/fold/foldcode.js";
|
||||
import "codemirror/addon/fold/foldgutter.js";
|
||||
import "codemirror/addon/fold/indent-fold.js";
|
||||
import "codemirror/addon/fold/markdown-fold.js";
|
||||
import "codemirror/addon/fold/xml-fold.js";
|
||||
|
||||
// import axios from 'axios';
|
||||
|
||||
export default {
|
||||
props: ["initCode", "mode"],
|
||||
name: "code-editor",
|
||||
title: "Mode: text/x-vue & Theme: monokai",
|
||||
components: {
|
||||
Codemirror,
|
||||
},
|
||||
|
||||
created() {
|
||||
// self.axios = axios.create({
|
||||
// baseURL: '',
|
||||
// timeout: 1000,
|
||||
// });
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.refreshScript();
|
||||
},
|
||||
|
||||
computed: {
|
||||
code: {
|
||||
get() {
|
||||
return this.codeStore;
|
||||
},
|
||||
set(newVal) {
|
||||
this.codeStore = newVal;
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
initCode() {
|
||||
this.codeStore = this.initCode;
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
codeStore: this.initCode,
|
||||
cmOption: {
|
||||
smartIndent: true, //智能缩进
|
||||
indentUnit: 4, // 智能缩进单元长度为 4 个空格
|
||||
matchBrackets: true, //每当光标位于匹配的方括号旁边时,都会使其高亮显示
|
||||
autofocus: true,
|
||||
showCursorWhenSelecting: true,
|
||||
autoRefresh: true,
|
||||
|
||||
tabSize: 4,
|
||||
foldGutter: true,
|
||||
styleActiveLine: true,
|
||||
lineNumbers: true,
|
||||
line: true,
|
||||
keyMap: "sublime",
|
||||
mode: this.mode,
|
||||
theme: "monokai",
|
||||
extraKeys: {
|
||||
F11(cm) {
|
||||
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||
},
|
||||
Esc(cm) {
|
||||
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
refreshScript() {
|
||||
let codemirror = this.$refs["codemirror"].cminstance;
|
||||
setTimeout(() => {
|
||||
codemirror.refresh();
|
||||
}, 100);
|
||||
},
|
||||
onCmCursorActivity(codemirror) {
|
||||
//内容发生改变
|
||||
console.log("onCmCursorActivity", codemirror);
|
||||
},
|
||||
onCmReady(codemirror) {
|
||||
//加载完成
|
||||
console.log("onCmReady", codemirror);
|
||||
},
|
||||
onCmFocus(codemirror) {
|
||||
//获取焦点
|
||||
console.log("onCmFocus", codemirror);
|
||||
},
|
||||
onCmBlur(codemirror) {
|
||||
//失去焦点
|
||||
console.log("onCmBlur", codemirror);
|
||||
},
|
||||
|
||||
getEditorCode() {
|
||||
//获取内容
|
||||
console.log("getEditorCode", getEditorCode);
|
||||
return this.codeStore;
|
||||
},
|
||||
insert() {
|
||||
let codemirror = this.$refs["codemirror"].cminstance;
|
||||
// const editor = this.$refs["codemirror"].getCodeMirror();
|
||||
// editor.setValue('1212');
|
||||
|
||||
// this.CodeMirrorEditor.setValue(“Hello Kitty”):设置编辑器内容
|
||||
// this.CodeMirrorEditor.getValue():获取编辑器内容
|
||||
// this.CodeMirrorEditor.getLine(n):获取第n行的内容
|
||||
// this.CodeMirrorEditor.lineCount():获取当前行数
|
||||
// this.CodeMirrorEditor.lastLine():获取最后一行的行号
|
||||
// this.CodeMirrorEditor.isClean():boolean类型判断编译器是否是clean的
|
||||
// this.CodeMirrorEditor.getSelection():获取选中内容
|
||||
// this.CodeMirrorEditor.getSelections():返回array类型选中内容
|
||||
// this.CodeMirrorEditor.replaceSelection(“替换后的内容”):替换选中的内容
|
||||
// this.CodeMirrorEditor.getCursor():获取光标位置,返回{line,char}
|
||||
// this.CodeMirrorEditor.setOption("",""):设置编译器属性
|
||||
// this.CodeMirrorEditor.getOption(""):获取编译器属性
|
||||
// this.CodeMirrorEditor.addKeyMap("",""):添加key-map键值,该键值具有比原来键值更高的优先级
|
||||
// this.CodeMirrorEditor.removeKeyMap(""):移除key-map
|
||||
// this.CodeMirrorEditor.addOverlay(""):Enable a highlighting overlay…没试出效果
|
||||
// this.CodeMirrorEditor.removeOverlay(""):移除Overlay
|
||||
// this.CodeMirrorEditor.setSize(width,height):设置编译器大小
|
||||
// this.CodeMirrorEditor.scrollTo(x,y):设置scroll到position位置
|
||||
// this.CodeMirrorEditor.refresh():刷新编辑器
|
||||
// this.CodeMirrorEditor.execCommand(“命令”):执行命令
|
||||
|
||||
console.log(codemirror.replaceSelection("1212"));
|
||||
},
|
||||
replaceSelection(val){
|
||||
this.$refs["codemirror"].cminstance.replaceSelection(val)
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.CodeMirror-scroll {
|
||||
min-height: 200px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,52 @@
|
|||
<template>
|
||||
<div
|
||||
class="context-menu"
|
||||
:style="{
|
||||
top: contextMenuData.axis.y + 'px',
|
||||
left: contextMenuData.axis.x + 'px',
|
||||
}"
|
||||
>
|
||||
<div @click="clickDel">删除</div>
|
||||
</div>
|
||||
|
||||
<a-modal v-model:visible="visible" @ok="handleOk" @cancel="handleCancel">
|
||||
<template #title> 提示 </template>
|
||||
<div>确定要删除节点 线索新增 ,删除后后面的节点数据将清空 ?</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import { toRefs, ref } from "vue";
|
||||
const emit = defineEmits(["deletedata",'cancel']);
|
||||
const visible = ref(false);
|
||||
const props = defineProps({
|
||||
contextMenuData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
//使用父组件传递过来的值
|
||||
const { contextMenuData } = toRefs(props);
|
||||
const clickDel = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
const handleOk = () => {
|
||||
emit("deletedata");
|
||||
};
|
||||
const handleCancel = () => {
|
||||
|
||||
emit("cancel");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.context-menu {
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: #ffffff;
|
||||
padding: 8px 16px;
|
||||
box-shadow: 0 0 5px 2px #efefef;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
|
@ -5,7 +5,8 @@ import router from "./router";
|
|||
import { createPinia } from "pinia";
|
||||
|
||||
import ElementPlus from "element-plus"; //引入element-plus库
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
import * as ElementPlusIconsVue from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import VForm3 from "vform3-builds"; //引入VForm3库
|
||||
|
||||
import "element-plus/dist/index.css"; //引入element-plus样式
|
||||
|
@ -78,12 +79,10 @@ export const loadView = (view) => {
|
|||
};
|
||||
|
||||
app.config.globalProperties.$http = http;
|
||||
|
||||
|
||||
app.config.globalProperties.$message = ElMessage;
|
||||
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component)
|
||||
app.component(key, component);
|
||||
}
|
||||
|
||||
|
||||
app.use(ElementPlus).use(VForm3).use(createPinia()).use(router).mount("#app");
|
||||
|
|
|
@ -48,14 +48,14 @@ const routes = [
|
|||
},
|
||||
component: () => import("../views/codemirror/index.vue"),
|
||||
},
|
||||
// {
|
||||
// path: "/data-flow-editor",
|
||||
// name: "data-flow-editor",
|
||||
// mete: {
|
||||
// title: "数据中台",
|
||||
// },
|
||||
// component: () => import("../views/data-flow-editor/index.vue"),
|
||||
// },
|
||||
{
|
||||
path: "/data-flow-editor",
|
||||
name: "data-flow-editor",
|
||||
mete: {
|
||||
title: "数据中台",
|
||||
},
|
||||
component: () => import("../views/data-flow-editor/index.vue"),
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import axios from "axios";
|
||||
import tools from "@/utils/tools";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
// axios.defaults.baseURL = '/api'
|
||||
axios.defaults.timeout = 10000;
|
||||
|
||||
|
||||
// HTTP request 拦截器
|
||||
axios.interceptors.request.use(
|
||||
(config) => {
|
||||
|
@ -26,22 +28,22 @@ axios.interceptors.response.use(
|
|||
(error) => {
|
||||
if (error.response) {
|
||||
if (error.response.status == 401) {
|
||||
this.$message.error("请重新登录!");
|
||||
ElMessage.error("请重新登录!");
|
||||
// router.replace({
|
||||
// path: '/login'
|
||||
// });
|
||||
} else if (error.response.status == 404) {
|
||||
this.$message.error("Status:404,正在请求不存在的服务器记录!");
|
||||
ElMessage.error("Status:404,正在请求不存在的服务器记录!");
|
||||
} else if (error.response.status == 500) {
|
||||
this.$message.error({
|
||||
ElMessage.error({
|
||||
title: "请求错误",
|
||||
message: "Status:500,服务器发生错误!",
|
||||
});
|
||||
} else {
|
||||
this.$message.error(`Status:${error.response.status},未知错误!`);
|
||||
ElMessage.error(`Status:${error.response.status},未知错误!`);
|
||||
}
|
||||
} else {
|
||||
this.$message.error("请求服务器无响应!");
|
||||
ElMessage.error("请求服务器无响应!");
|
||||
}
|
||||
return Promise.reject(error.response);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<template>
|
||||
<div>
|
||||
<codemirror
|
||||
v-model="welcomeCode"
|
||||
placeholder="Code goes here..."
|
||||
:style="{ height: '400px' }"
|
||||
:autofocus="true"
|
||||
:indent-with-tab="true"
|
||||
:tab-size="2"
|
||||
:extensions="extensions"
|
||||
@blur="change()"
|
||||
/>
|
||||
|
||||
<component v-bind:is="currentTabComponent"></component>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { Codemirror } from "vue-codemirror";
|
||||
import { javascript } from "@codemirror/lang-javascript";
|
||||
import { oneDark } from "@codemirror/theme-one-dark";
|
||||
import { compileFile } from "@/compiler/sfc-compiler.js";
|
||||
import { babelParse } from "@vue/compiler-sfc";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { table } from "@/compiler/testCode";
|
||||
|
||||
// 这个 id 是 scopeId,用于 css scope,保证唯一即可
|
||||
const id = Date.now().toString();
|
||||
const scopeId = `data-v-${id}`;
|
||||
|
||||
const welcomeCode = ref(table);
|
||||
|
||||
const extensions = [javascript(), oneDark];
|
||||
|
||||
const change = (e) => {
|
||||
console.log("change", e);
|
||||
generateComponent(e);
|
||||
};
|
||||
|
||||
const currentTabComponent = ref(eval(""));
|
||||
|
||||
const generateComponent = () => {
|
||||
let compiled = {};
|
||||
compileFile("TestCode.vue", welcomeCode.value, compiled);
|
||||
|
||||
if (compiled.errors.length > 0) {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
duration: 0,
|
||||
showClose: true,
|
||||
message: `
|
||||
发生错误:
|
||||
${compiled.errors[0]}
|
||||
`,
|
||||
});
|
||||
console.error(`发生错误`);
|
||||
console.error(compiled.errors[0]);
|
||||
throw compiled.errors[0];
|
||||
} else {
|
||||
var code = compiled.js;
|
||||
var ast = babelParse(code, {
|
||||
sourceType: "module",
|
||||
});
|
||||
var replaceCode = (node, subCode) =>
|
||||
code.substring(0, node.start) + subCode + code.substring(node.end);
|
||||
for (var i = ast.program.body.length - 1; i >= 0; i--) {
|
||||
var node = ast.program.body[i];
|
||||
if (node.type === "ImportDeclaration") {
|
||||
code = replaceCode(
|
||||
node,
|
||||
node.specifiers
|
||||
.map(
|
||||
(it) =>
|
||||
`const ${
|
||||
it.local?.name || it.imported?.name || "*"
|
||||
} = ___grape__import__('${node.source.value}', '${
|
||||
it.imported?.name || "*"
|
||||
}');`
|
||||
)
|
||||
.join("\r\n")
|
||||
);
|
||||
} else if (node.type === "ExportDefaultDeclaration") {
|
||||
code = replaceCode(node, `return ${node.declaration.name}`);
|
||||
}
|
||||
}
|
||||
code = `(function(){
|
||||
${code}
|
||||
})()`;
|
||||
|
||||
var componentStyle = document.createElement("style");
|
||||
componentStyle.innerHTML = compiled.css;
|
||||
document.head.appendChild(componentStyle);
|
||||
currentTabComponent.value = eval(code);
|
||||
// app.component(item.name, eval(code));
|
||||
// console.log(code);
|
||||
}
|
||||
};
|
||||
generateComponent()
|
||||
</script>
|
||||
<style>
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
|
@ -1,105 +1,196 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="codemirror">
|
||||
<codemirror
|
||||
v-model="welcomeCode"
|
||||
placeholder="Code goes here..."
|
||||
:style="{ height: '400px' }"
|
||||
ref="codemirror"
|
||||
v-model:value="code"
|
||||
:options="cmOption"
|
||||
:autofocus="true"
|
||||
:indent-with-tab="true"
|
||||
:tab-size="2"
|
||||
:extensions="extensions"
|
||||
@blur="change()"
|
||||
@cursorActivity="onCmCursorActivity"
|
||||
@ready="onCmReady"
|
||||
@focus="onCmFocus"
|
||||
@blur="onCmBlur"
|
||||
/>
|
||||
|
||||
<component v-bind:is="currentTabComponent"></component>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { Codemirror } from "vue-codemirror";
|
||||
import { javascript } from "@codemirror/lang-javascript";
|
||||
import { oneDark } from "@codemirror/theme-one-dark";
|
||||
import { compileFile } from "@/compiler/sfc-compiler.js";
|
||||
import { babelParse } from "@vue/compiler-sfc";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { table } from "@/compiler/testCode";
|
||||
|
||||
// 这个 id 是 scopeId,用于 css scope,保证唯一即可
|
||||
const id = Date.now().toString();
|
||||
const scopeId = `data-v-${id}`;
|
||||
<script>
|
||||
import Codemirror from "codemirror-editor-vue3";
|
||||
|
||||
const welcomeCode = ref(table);
|
||||
// base style
|
||||
import "codemirror/lib/codemirror.css";
|
||||
|
||||
const extensions = [javascript(), oneDark];
|
||||
// language
|
||||
import "codemirror/mode/vue/vue.js";
|
||||
|
||||
const change = (e) => {
|
||||
console.log("change", e);
|
||||
generateComponent(e);
|
||||
// active-line.js
|
||||
import "codemirror/addon/selection/active-line.js";
|
||||
|
||||
// styleSelectedText
|
||||
import "codemirror/addon/selection/mark-selection.js";
|
||||
import "codemirror/addon/search/searchcursor.js";
|
||||
|
||||
// highlightSelectionMatches
|
||||
import "codemirror/addon/scroll/annotatescrollbar.js";
|
||||
import "codemirror/addon/search/matchesonscrollbar.js";
|
||||
import "codemirror/addon/search/searchcursor.js";
|
||||
import "codemirror/addon/search/match-highlighter.js";
|
||||
|
||||
// keyMap
|
||||
import "codemirror/mode/clike/clike.js";
|
||||
import "codemirror/addon/edit/matchbrackets.js";
|
||||
import "codemirror/addon/comment/comment.js";
|
||||
import "codemirror/addon/dialog/dialog.js";
|
||||
import "codemirror/addon/dialog/dialog.css";
|
||||
import "codemirror/addon/search/searchcursor.js";
|
||||
import "codemirror/addon/search/search.js";
|
||||
import "codemirror/keymap/sublime.js";
|
||||
|
||||
// foldGutter
|
||||
import "codemirror/addon/fold/foldgutter.css";
|
||||
import "codemirror/addon/fold/brace-fold.js";
|
||||
import "codemirror/addon/fold/comment-fold.js";
|
||||
import "codemirror/addon/fold/foldcode.js";
|
||||
import "codemirror/addon/fold/foldgutter.js";
|
||||
import "codemirror/addon/fold/indent-fold.js";
|
||||
import "codemirror/addon/fold/markdown-fold.js";
|
||||
import "codemirror/addon/fold/xml-fold.js";
|
||||
|
||||
// import axios from 'axios';
|
||||
|
||||
export default {
|
||||
props: ["initCode", "mode"],
|
||||
name: "code-editor",
|
||||
title: "Mode: text/x-vue & Theme: monokai",
|
||||
components: {
|
||||
Codemirror,
|
||||
},
|
||||
|
||||
created() {
|
||||
// self.axios = axios.create({
|
||||
// baseURL: '',
|
||||
// timeout: 1000,
|
||||
// });
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.refreshScript();
|
||||
},
|
||||
|
||||
computed: {
|
||||
code: {
|
||||
get() {
|
||||
return this.codeStore;
|
||||
},
|
||||
set(newVal) {
|
||||
this.codeStore = newVal;
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
initCode() {
|
||||
this.codeStore = this.initCode;
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
codeStore: this.initCode,
|
||||
cmOption: {
|
||||
smartIndent: true, //智能缩进
|
||||
indentUnit: 4, // 智能缩进单元长度为 4 个空格
|
||||
matchBrackets: true, //每当光标位于匹配的方括号旁边时,都会使其高亮显示
|
||||
autofocus: true,
|
||||
showCursorWhenSelecting: true,
|
||||
autoRefresh: true,
|
||||
|
||||
tabSize: 4,
|
||||
foldGutter: true,
|
||||
styleActiveLine: true,
|
||||
lineNumbers: true,
|
||||
line: true,
|
||||
keyMap: "sublime",
|
||||
mode: this.mode,
|
||||
theme: "monokai",
|
||||
extraKeys: {
|
||||
F11(cm) {
|
||||
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||
},
|
||||
Esc(cm) {
|
||||
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||
},
|
||||
},
|
||||
currentTabComponent:''
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
refreshScript() {
|
||||
let codemirror = this.$refs["codemirror"].cminstance;
|
||||
setTimeout(() => {
|
||||
codemirror.refresh();
|
||||
}, 100);
|
||||
},
|
||||
onCmCursorActivity(codemirror) {
|
||||
//内容发生改变
|
||||
console.log("onCmCursorActivity", codemirror);
|
||||
},
|
||||
onCmReady(codemirror) {
|
||||
//加载完成
|
||||
console.log("onCmReady", codemirror);
|
||||
},
|
||||
onCmFocus(codemirror) {
|
||||
//获取焦点
|
||||
console.log("onCmFocus", codemirror);
|
||||
},
|
||||
onCmBlur(codemirror) {
|
||||
//失去焦点
|
||||
console.log("onCmBlur", codemirror);
|
||||
},
|
||||
|
||||
getEditorCode() {
|
||||
//获取内容
|
||||
console.log("getEditorCode", getEditorCode);
|
||||
return this.codeStore;
|
||||
},
|
||||
insert() {
|
||||
let codemirror = this.$refs["codemirror"].cminstance;
|
||||
// const editor = this.$refs["codemirror"].getCodeMirror();
|
||||
// editor.setValue('1212');
|
||||
|
||||
// this.CodeMirrorEditor.setValue(“Hello Kitty”):设置编辑器内容
|
||||
// this.CodeMirrorEditor.getValue():获取编辑器内容
|
||||
// this.CodeMirrorEditor.getLine(n):获取第n行的内容
|
||||
// this.CodeMirrorEditor.lineCount():获取当前行数
|
||||
// this.CodeMirrorEditor.lastLine():获取最后一行的行号
|
||||
// this.CodeMirrorEditor.isClean():boolean类型判断编译器是否是clean的
|
||||
// this.CodeMirrorEditor.getSelection():获取选中内容
|
||||
// this.CodeMirrorEditor.getSelections():返回array类型选中内容
|
||||
// this.CodeMirrorEditor.replaceSelection(“替换后的内容”):替换选中的内容
|
||||
// this.CodeMirrorEditor.getCursor():获取光标位置,返回{line,char}
|
||||
// this.CodeMirrorEditor.setOption("",""):设置编译器属性
|
||||
// this.CodeMirrorEditor.getOption(""):获取编译器属性
|
||||
// this.CodeMirrorEditor.addKeyMap("",""):添加key-map键值,该键值具有比原来键值更高的优先级
|
||||
// this.CodeMirrorEditor.removeKeyMap(""):移除key-map
|
||||
// this.CodeMirrorEditor.addOverlay(""):Enable a highlighting overlay…没试出效果
|
||||
// this.CodeMirrorEditor.removeOverlay(""):移除Overlay
|
||||
// this.CodeMirrorEditor.setSize(width,height):设置编译器大小
|
||||
// this.CodeMirrorEditor.scrollTo(x,y):设置scroll到position位置
|
||||
// this.CodeMirrorEditor.refresh():刷新编辑器
|
||||
// this.CodeMirrorEditor.execCommand(“命令”):执行命令
|
||||
|
||||
console.log(codemirror.replaceSelection("1212"));
|
||||
},
|
||||
replaceSelection(val) {
|
||||
this.$refs["codemirror"].cminstance.replaceSelection(val);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const currentTabComponent = ref(eval(""));
|
||||
|
||||
const generateComponent = () => {
|
||||
let compiled = {};
|
||||
compileFile("TestCode.vue", welcomeCode.value, compiled);
|
||||
|
||||
if (compiled.errors.length > 0) {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
duration: 0,
|
||||
showClose: true,
|
||||
message: `
|
||||
发生错误:
|
||||
${compiled.errors[0]}
|
||||
`,
|
||||
});
|
||||
console.error(`发生错误`);
|
||||
console.error(compiled.errors[0]);
|
||||
throw compiled.errors[0];
|
||||
} else {
|
||||
var code = compiled.js;
|
||||
var ast = babelParse(code, {
|
||||
sourceType: "module",
|
||||
});
|
||||
var replaceCode = (node, subCode) =>
|
||||
code.substring(0, node.start) + subCode + code.substring(node.end);
|
||||
for (var i = ast.program.body.length - 1; i >= 0; i--) {
|
||||
var node = ast.program.body[i];
|
||||
if (node.type === "ImportDeclaration") {
|
||||
code = replaceCode(
|
||||
node,
|
||||
node.specifiers
|
||||
.map(
|
||||
(it) =>
|
||||
`const ${
|
||||
it.local?.name || it.imported?.name || "*"
|
||||
} = ___grape__import__('${node.source.value}', '${
|
||||
it.imported?.name || "*"
|
||||
}');`
|
||||
)
|
||||
.join("\r\n")
|
||||
);
|
||||
} else if (node.type === "ExportDefaultDeclaration") {
|
||||
code = replaceCode(node, `return ${node.declaration.name}`);
|
||||
}
|
||||
}
|
||||
code = `(function(){
|
||||
${code}
|
||||
})()`;
|
||||
|
||||
var componentStyle = document.createElement("style");
|
||||
componentStyle.innerHTML = compiled.css;
|
||||
document.head.appendChild(componentStyle);
|
||||
currentTabComponent.value = eval(code);
|
||||
// app.component(item.name, eval(code));
|
||||
// console.log(code);
|
||||
}
|
||||
};
|
||||
generateComponent()
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
.CodeMirror-scroll {
|
||||
min-height: 200px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<!-- 算法公式 -->
|
||||
|
||||
<template>
|
||||
<a-tabs
|
||||
default-active-key="1"
|
||||
@change="tabsChange"
|
||||
<el-tabs
|
||||
v-model="activeName"
|
||||
@tab-click="tabsChange"
|
||||
v-if="conArrData.length > 0"
|
||||
>
|
||||
<a-tab-pane key="1" title="节点配置">
|
||||
<el-tab-pane name="1" label="节点配置">
|
||||
<div class="dataExtend_content">
|
||||
<div class="left">
|
||||
<div>
|
||||
|
@ -17,7 +17,7 @@
|
|||
v-for="(item, index) in fieldList"
|
||||
:key="index"
|
||||
>
|
||||
<a-input
|
||||
<el-input
|
||||
v-model="item.value"
|
||||
size="small"
|
||||
class="fieldList_item_input"
|
||||
|
@ -34,25 +34,23 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div v-else class="dissatisfy">
|
||||
<div class="dissatisfy_box">
|
||||
<img src="@/assets/imgs/oneNode.f1997e1e.png" alt="" />
|
||||
<img src="@/assets/images/oneNode.f1997e1e.png" alt="" />
|
||||
<p>请将1个节点连接至本节点</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 配置 -->
|
||||
<a-modal
|
||||
width="auto"
|
||||
v-model:visible="visible"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
<el-dialog
|
||||
width="800"
|
||||
v-model="visible"
|
||||
class="a-modal"
|
||||
title="函数配置"
|
||||
>
|
||||
<template #title> 函数配置 </template>
|
||||
<div class="deploy_content">
|
||||
<div style="width: 1000px">
|
||||
<div style="width: 100%">
|
||||
<codemirror
|
||||
v-if="codemirrorIf"
|
||||
:initCode="code"
|
||||
|
@ -75,11 +73,11 @@
|
|||
</div>
|
||||
<div class="right deploy_deploy_box">
|
||||
<p class="title">函数列表</p>
|
||||
<div>
|
||||
<a-collapse :default-active-key="[0]" accordion>
|
||||
<a-collapse-item
|
||||
:header="item.title"
|
||||
:key="index"
|
||||
<el-scrollbar height="200px">
|
||||
<el-collapse v-model="activeNames" accordion>
|
||||
<el-collapse-item
|
||||
:title="item.title"
|
||||
:name="index"
|
||||
v-for="(item, index) in mainList"
|
||||
>
|
||||
<ul>
|
||||
|
@ -90,13 +88,21 @@
|
|||
{{ item2.label }}
|
||||
</li>
|
||||
</ul>
|
||||
</a-collapse-item>
|
||||
</a-collapse>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleCancel()">取消</el-button>
|
||||
<el-button type="primary" @click="handleOk()">
|
||||
确定
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
@ -119,6 +125,9 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const activeName = ref("1");
|
||||
const activeNames = ref(["1"]);
|
||||
|
||||
const mainList = [
|
||||
{
|
||||
title: "基础函数 - 数学函数",
|
||||
|
@ -284,8 +293,11 @@ const deploy = () => {
|
|||
codemirrorIf.value = true;
|
||||
});
|
||||
};
|
||||
const handleOk = () => {};
|
||||
const handleCancel = () => {};
|
||||
const handleOk = () => {
|
||||
visible.value = false
|
||||
};
|
||||
const handleCancel = () => {
|
||||
visible.value = false};
|
||||
|
||||
const code = ref("");
|
||||
|
||||
|
@ -317,7 +329,7 @@ disposeLineList();
|
|||
|
||||
const codemirrorRef = ref(null);
|
||||
const clickDeploy = (value) => {
|
||||
codemirrorRef.value.replaceSelection(value)
|
||||
codemirrorRef.value.replaceSelection(value);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -336,10 +348,12 @@ const clickDeploy = (value) => {
|
|||
margin: 0px 6px 8px;
|
||||
}
|
||||
.fieldList {
|
||||
padding-left: 5px;
|
||||
.fieldList_item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
font-size: 0;
|
||||
.fieldList_item_input {
|
||||
width: 165px;
|
||||
background-color: #fff;
|
||||
|
@ -348,6 +362,7 @@ const clickDeploy = (value) => {
|
|||
}
|
||||
span {
|
||||
margin-left: 5px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +400,7 @@ const clickDeploy = (value) => {
|
|||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding: 0 15px;
|
||||
li {
|
||||
padding: 3px 0;
|
||||
cursor: pointer;
|
||||
|
@ -407,11 +422,17 @@ const clickDeploy = (value) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
.a-modal .arco-modal-body {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.cm-component {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.deploy_deploy_box {
|
||||
.el-collapse-item__header {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<!-- 字段设置 -->
|
||||
|
||||
<template>
|
||||
<a-tabs
|
||||
default-active-key="1"
|
||||
@change="tabsChange"
|
||||
<el-tabs
|
||||
v-model="activeName"
|
||||
@tab-chang="tabsChange"
|
||||
v-if="conArrData.length > 0"
|
||||
>
|
||||
<a-tab-pane key="1" title="字段配置">
|
||||
<el-tab-pane name="1" label="字段配置">
|
||||
<draggable
|
||||
v-model="data.fieldSettingList"
|
||||
class="fun-classify"
|
||||
|
@ -19,7 +19,7 @@
|
|||
<div class="field-item-head">
|
||||
<span>{{ element.name }}</span>
|
||||
<div class="head-action" @click="clickSet(element)">
|
||||
<icon-settings />
|
||||
<el-icon><Setting /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-item-cell">
|
||||
|
@ -33,8 +33,8 @@
|
|||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div v-else class="dissatisfy">
|
||||
<div class="dissatisfy_box">
|
||||
<img src="@/assets/imgs/oneNode.f1997e1e.png" alt="" />
|
||||
|
@ -42,78 +42,93 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<a-modal
|
||||
width="auto"
|
||||
v-model:visible="visible"
|
||||
<el-dialog
|
||||
width="800"
|
||||
v-model="visible"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<template #title> 字段设置 </template>
|
||||
<a-form :model="form" :style="{ width: '500px' }" label-align="left">
|
||||
<a-form-item field="name" label="字段名:">
|
||||
<a-input v-model="form.name" placeholder="请输入字段名" />
|
||||
</a-form-item>
|
||||
<a-form-item field="type" label="类型:">
|
||||
<a-select placeholder="请选择数据类型">
|
||||
<a-option>字符串</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item field="type" label="值替换:">
|
||||
<a-button type="outline" @click="addList">新增替换</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-form
|
||||
<el-form
|
||||
:model="form"
|
||||
:style="{ width: '500px' }"
|
||||
label-align="left"
|
||||
label-width="100"
|
||||
>
|
||||
<el-form-item field="name" label="字段名:">
|
||||
<el-input v-model="form.name" placeholder="请输入字段名" />
|
||||
</el-form-item>
|
||||
<el-form-item field="type" label="类型:">
|
||||
<el-select placeholder="请选择数据类型">
|
||||
<el-option value="string" label="字符串" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item field="type" label="值替换:">
|
||||
<el-button type="outline" @click="addList">新增替换</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form
|
||||
:model="form"
|
||||
:style="{ width: '100%' }"
|
||||
label-align="left"
|
||||
label-width="80"
|
||||
layout="vertical"
|
||||
>
|
||||
<a-row
|
||||
<el-row
|
||||
class="replace-item"
|
||||
:gutter="12"
|
||||
v-for="(item, index) in form.list"
|
||||
:key="index"
|
||||
>
|
||||
<a-col :span="7">
|
||||
<a-form-item label="替换类型:">
|
||||
<a-select placeholder="未选择" v-model="item.type">
|
||||
<a-option value="null">空值</a-option>
|
||||
<a-option value="custom">自定义值</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="7" v-if="item.type == 'custom'">
|
||||
<a-form-item field="name" label="原来值:">
|
||||
<a-input
|
||||
<el-col :span="6">
|
||||
<el-form-item label="替换类型:">
|
||||
<el-select placeholder="未选择" v-model="item.type">
|
||||
<el-option value="null" label="空值" :key="item.value" />
|
||||
<el-option value="custom" label="自定义值" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6" v-if="item.type == 'custom'">
|
||||
<el-form-item field="name" label="原来值:">
|
||||
<el-input
|
||||
placeholder="请输入原来的值"
|
||||
allow-clear
|
||||
v-model="item.oldVal"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="7" v-if="item.type == 'custom' || item.type == 'null'">
|
||||
<a-form-item field="name" label="替换值:">
|
||||
<a-input
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6" v-if="item.type == 'custom' || item.type == 'null'">
|
||||
<el-form-item field="name" label="替换值:">
|
||||
<el-input
|
||||
placeholder="请输入替换值"
|
||||
allow-clear
|
||||
v-model="item.newVal"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="3">
|
||||
<a-form-item>
|
||||
<div class="del" @click="clickDel(index)"><icon-delete /></div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<div class="del" @click="clickDel(index)">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleOk"> 确定 </el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick, toRefs } from "vue";
|
||||
import draggable from "vuedraggable";
|
||||
import { IconSettings, IconDelete } from "@arco-design/web-vue/es/icon";
|
||||
import http from "@/scripts/request";
|
||||
import http from "@/utils/request";
|
||||
|
||||
const activeName = ref("1");
|
||||
|
||||
const data = reactive({
|
||||
fieldSettingList: [],
|
||||
|
@ -232,8 +247,13 @@ const handleOk = () => {
|
|||
});
|
||||
console.log("dataList", dataList);
|
||||
nodeValue.value.data = JSON.stringify(dataList);
|
||||
|
||||
visible.value = false;
|
||||
};
|
||||
const handleCancel = () => {
|
||||
|
||||
visible.value = false;
|
||||
};
|
||||
const handleCancel = () => {};
|
||||
|
||||
// 新增值替换
|
||||
const addList = () => {
|
||||
|
@ -340,9 +360,10 @@ const clickDel = (index) => {
|
|||
}
|
||||
.replace-item {
|
||||
position: relative;
|
||||
.del {
|
||||
}
|
||||
.del {
|
||||
cursor: pointer;
|
||||
margin-top: 26px;
|
||||
}
|
||||
margin-top: 8px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,43 +1,40 @@
|
|||
<!-- 数据筛选 -->
|
||||
|
||||
<template>
|
||||
<a-tabs
|
||||
default-active-key="1"
|
||||
@change="tabsChange"
|
||||
v-if="conArrData.length > 0"
|
||||
>
|
||||
<a-tab-pane key="1" title="节点配置">
|
||||
<el-tabs @tab-chang="tabsChange" v-if="conArrData.length > 0">
|
||||
<el-tab-pane label="节点配置">
|
||||
<div class="data-filter-box">
|
||||
<div>
|
||||
<span>筛选出符合以下</span>
|
||||
<a-select
|
||||
<el-select
|
||||
:style="{ width: '80px', margin: '0 10px' }"
|
||||
placeholder="Select"
|
||||
:trigger-props="{ autoFitPopupMinWidth: true }"
|
||||
v-model="data.type"
|
||||
>
|
||||
<a-option value="and">所有</a-option>
|
||||
<a-option value="or">任一</a-option>
|
||||
</a-select>
|
||||
<el-option value="and" label="所有" />
|
||||
<el-option value="or" label="任一" />
|
||||
</el-select>
|
||||
<span>条件的数据</span>
|
||||
</div>
|
||||
<div class="data-filter-add">
|
||||
<a-dropdown @select="handleSelect" position="bl">
|
||||
<a-button type="primary" size="small">
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
<template #default>添加过滤条件</template>
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-doption
|
||||
<el-dropdown @command="handleSelect">
|
||||
<el-button type="primary">
|
||||
添加过滤条件<el-icon class="el-icon--right"
|
||||
><arrow-down
|
||||
/></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in columnList"
|
||||
:key="item.id"
|
||||
:value="item.keyword"
|
||||
>{{ item.name }}</a-doption
|
||||
:command="item.keyword"
|
||||
>{{ item.name }}</el-dropdown-item
|
||||
>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<div class="filter-add-list">
|
||||
<div
|
||||
|
@ -45,14 +42,14 @@
|
|||
v-for="(item, index) in data.conditionList"
|
||||
:key="index"
|
||||
>
|
||||
<a-input
|
||||
<el-input
|
||||
class="item"
|
||||
:style="{ width: '200px' }"
|
||||
v-model="item.columnText"
|
||||
placeholder="Please enter something"
|
||||
readonly
|
||||
/>
|
||||
<a-select
|
||||
<el-select
|
||||
class="item"
|
||||
v-model="item.condition"
|
||||
:style="{ width: '150px', marginRight: '15px' }"
|
||||
|
@ -60,11 +57,11 @@
|
|||
:trigger-props="{ autoFitPopupMinWidth: true }"
|
||||
@change="update"
|
||||
>
|
||||
<a-option value="eq">等于</a-option>
|
||||
<a-option value="ne">不等于</a-option>
|
||||
</a-select>
|
||||
<el-option value="eq" label="等于" />
|
||||
<el-option value="ne" label="不等于" />
|
||||
</el-select>
|
||||
<div>
|
||||
<a-input
|
||||
<el-input
|
||||
class="item"
|
||||
:style="{ width: '200px' }"
|
||||
v-model="item.val"
|
||||
|
@ -72,46 +69,15 @@
|
|||
allow-clear
|
||||
@blur="update"
|
||||
/>
|
||||
<!-- <a-tag
|
||||
v-for="(tag, index) of tags"
|
||||
:key="tag"
|
||||
:closable="index !== 0"
|
||||
@close="handleRemove(tag)"
|
||||
>
|
||||
{{ tag }}
|
||||
</a-tag>
|
||||
|
||||
<a-input
|
||||
v-if="showInput"
|
||||
ref="inputRef"
|
||||
:style="{ width: '90px' }"
|
||||
size="mini"
|
||||
v-model.trim="inputVal"
|
||||
@keyup.enter="handleAdd"
|
||||
@blur="handleAdd"
|
||||
/>
|
||||
<a-tag
|
||||
v-else
|
||||
:style="{
|
||||
width: '90px',
|
||||
backgroundColor: 'var(--color-fill-2)',
|
||||
border: '1px dashed var(--color-fill-3)',
|
||||
cursor: 'pointer',
|
||||
}"
|
||||
@click="handleEdit"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
添加
|
||||
</a-tag> -->
|
||||
</div>
|
||||
<div class="del" @click="clickDel(index)"><icon-delete /></div>
|
||||
<div class="del" @click="clickDel(index)">
|
||||
<el-icon><Delete /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div v-else class="dissatisfy">
|
||||
<div class="dissatisfy_box">
|
||||
<img src="@/assets/imgs/oneNode.f1997e1e.png" alt="" />
|
||||
|
@ -121,7 +87,6 @@
|
|||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick, toRefs } from "vue";
|
||||
import { IconPlus, IconDelete } from "@arco-design/web-vue/es/icon";
|
||||
|
||||
const data = reactive({
|
||||
type: "and",
|
||||
|
@ -168,9 +133,9 @@ const disposeLineList = () => {
|
|||
|
||||
columnList.value = JSON.parse(JSON.stringify(conArrItem.columnList));
|
||||
|
||||
columnList.value.map(item=>{
|
||||
item.nodeId = nodeValue.value.id
|
||||
})
|
||||
columnList.value.map((item) => {
|
||||
item.nodeId = nodeValue.value.id;
|
||||
});
|
||||
|
||||
nodeValue.value.columnList = JSON.parse(
|
||||
JSON.stringify(columnList.value)
|
||||
|
@ -227,6 +192,7 @@ const handleRemove = (key) => {
|
|||
// end tab
|
||||
|
||||
const handleSelect = (val) => {
|
||||
console.log(val);
|
||||
columnList.value.map((item) => {
|
||||
if (item.keyword == val) {
|
||||
data.conditionList.push({
|
||||
|
@ -249,16 +215,15 @@ const update = () => {
|
|||
nodeValue.value.data = JSON.stringify(nodeValueDate);
|
||||
};
|
||||
|
||||
|
||||
const clickDel = (index)=>{
|
||||
data.conditionList.splice(index,1)
|
||||
}
|
||||
|
||||
const clickDel = (index) => {
|
||||
data.conditionList.splice(index, 1);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.data-filter-box {
|
||||
padding: 0 16px;
|
||||
font-size: 14px;
|
||||
.data-filter-add {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
|
|
@ -1,35 +1,38 @@
|
|||
<template>
|
||||
<a-tabs
|
||||
default-active-key="1"
|
||||
@change="tabsChange"
|
||||
<el-tabs
|
||||
v-model="activeName"
|
||||
@tab-change="tabsChange"
|
||||
v-if="conArrData.length > 0"
|
||||
>
|
||||
<a-tab-pane key="1" title="节点配置">
|
||||
<el-tab-pane name="1" label="节点配置">
|
||||
<div class="grouping-content">
|
||||
<div class="grouping-content-left">
|
||||
<div class="group-title"><span class="label">分组字段</span></div>
|
||||
<a-dropdown @select="handleSelect" position="bl">
|
||||
<a-button type="primary" size="small">
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
<template #default>添加分组字段</template>
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-doption
|
||||
<el-dropdown @command="handleSelect" position="bl">
|
||||
<el-button type="primary">
|
||||
添加分组字段<el-icon class="el-icon--right"
|
||||
><arrow-down
|
||||
/></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in columnList"
|
||||
:key="item.id"
|
||||
:value="item.keyword"
|
||||
>{{ item.name }}</a-doption
|
||||
:command="item.keyword"
|
||||
>{{ item.name }}</el-dropdown-item
|
||||
>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</el-dropdown>
|
||||
<div class="grouping-list">
|
||||
<div class="grouping-list-item" v-for="item in leftGroupingList">
|
||||
<span class="name">{{ item.name }}</span>
|
||||
|
||||
<div class="del" @click="clickLeftDel(index)">
|
||||
<icon-delete />
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -39,57 +42,67 @@
|
|||
<span class="label">汇总字段</span>
|
||||
<div>
|
||||
<span>是否保留原字段:</span>
|
||||
<a-switch v-model="nodeValueData.isRetain" @change="initData">
|
||||
<template #checked> 是 </template>
|
||||
<template #unchecked> 否 </template>
|
||||
</a-switch>
|
||||
<el-switch
|
||||
v-model="nodeValueData.isRetain"
|
||||
@change="initData"
|
||||
active-text="是"
|
||||
inactive-text="否"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<a-dropdown @select="addSummary" position="bl">
|
||||
<a-button type="primary" size="small">
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
<template #default>添加汇总字段</template>
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-doption
|
||||
|
||||
|
||||
<el-dropdown @command="addSummary" position="bl">
|
||||
<el-button type="primary">
|
||||
添加汇总字段<el-icon class="el-icon--right"
|
||||
><arrow-down
|
||||
/></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in columnList"
|
||||
:key="item.id"
|
||||
:value="item.keyword"
|
||||
>{{ item.name }}</a-doption
|
||||
:command="item.keyword"
|
||||
>{{ item.name }}</el-dropdown-item
|
||||
>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</el-dropdown>
|
||||
|
||||
<div class="grouping-list">
|
||||
<div class="grouping-list-item" v-for="item in rightGroupingList">
|
||||
<span class="name">{{ item.name }}</span>
|
||||
<a-select
|
||||
<el-select
|
||||
:style="{ width: '160px' }"
|
||||
v-model="item.type"
|
||||
placeholder="请选择汇总方式"
|
||||
@change="initData()"
|
||||
>
|
||||
<a-option value="count">总数</a-option>
|
||||
</a-select>
|
||||
<el-option value="count" label="总数" />
|
||||
</el-select>
|
||||
<div class="del" @click="clickRightDel(index)">
|
||||
<icon-delete />
|
||||
<el-icon><Delete /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" title="查看数据">
|
||||
<a-table
|
||||
:columns="dataColumnList"
|
||||
:data="columnListData"
|
||||
:pagination="false"
|
||||
size="small"
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="2" label="查看数据">
|
||||
|
||||
|
||||
<el-table :data="columnListData" stripe style="width: 100%" height="345" empty-text="暂无数据">
|
||||
<el-table-column
|
||||
:prop="item.dataIndex"
|
||||
:label="item.title"
|
||||
v-for="(item, index) in dataColumnList"
|
||||
:key="index"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</el-table>
|
||||
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div v-else class="dissatisfy">
|
||||
<div class="dissatisfy_box">
|
||||
<img src="@/assets/imgs/oneNode.f1997e1e.png" alt="" />
|
||||
|
@ -98,11 +111,10 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup >
|
||||
import http from "@/scripts/request";
|
||||
<script setup>
|
||||
import http from "@/utils/request";
|
||||
import { ref, reactive, nextTick, toRefs } from "vue";
|
||||
import { IconPlus, IconDelete } from "@arco-design/web-vue/es/icon";
|
||||
|
||||
const activeName = ref("1");
|
||||
const columnList = ref([]);
|
||||
|
||||
const leftGroupingList = ref([]); //left 数据列表
|
||||
|
@ -218,6 +230,7 @@ const tabsChange = (key) => {
|
|||
// left 列表数据处理
|
||||
|
||||
const handleSelect = (keyword) => {
|
||||
console.log(keyword);
|
||||
columnList.value.map((item) => {
|
||||
if (item.keyword == keyword) {
|
||||
leftGroupingList.value.push(item);
|
||||
|
@ -262,13 +275,12 @@ const initData = () => {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
nodeValue.value.data = JSON.stringify(nodeValueData.value);
|
||||
};
|
||||
|
||||
//查看数据
|
||||
const dataColumnList = ref([])
|
||||
const columnListData = ref([])
|
||||
const dataColumnList = ref([]);
|
||||
const columnListData = ref([]);
|
||||
const getDataStream = () => {
|
||||
http
|
||||
.post("/api/metadata/data_stream/exec", {
|
||||
|
|
|
@ -1,58 +1,62 @@
|
|||
<!-- 数据连接 -->
|
||||
<template>
|
||||
<a-tabs default-active-key="1" @change="tabsChange" v-if="passIf">
|
||||
<a-tab-pane key="1" :title="nodeValue.name">
|
||||
<el-tabs v-model="activeName" @tab-chang="tabsChange" v-if="passIf">
|
||||
<el-tab-pane name="1" :label="nodeValue.name">
|
||||
<div id="join_content">
|
||||
<div class="left">
|
||||
<h4>1.设置连接方式</h4>
|
||||
<a-radio-group v-model="data.joinType" :options="options" />
|
||||
<el-radio-group v-model="data.joinType">
|
||||
<el-radio :label="item.value" v-for="(item,index) in options" :key="index">{{item.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="right">
|
||||
<h4>2.添加连接方式</h4>
|
||||
<div class="content">
|
||||
<div>
|
||||
<h5>左侧表单:</h5>
|
||||
<a-select
|
||||
<el-select
|
||||
v-model="data.leftColumnName"
|
||||
:style="{ width: '220px' }"
|
||||
placeholder="请选择左侧表单字段"
|
||||
@change="setData"
|
||||
>
|
||||
<a-option
|
||||
<el-option
|
||||
v-for="item in conArrData[0].columnList"
|
||||
:label="item.name"
|
||||
:value="item.keyword"
|
||||
>{{ item.name }}</a-option
|
||||
>
|
||||
</a-select>
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div>
|
||||
<h5>右侧表单:</h5>
|
||||
<a-select
|
||||
<el-select
|
||||
v-model="data.rightColumnName"
|
||||
:style="{ width: '220px' }"
|
||||
placeholder="请选择右侧表单字段"
|
||||
@change="setData"
|
||||
>
|
||||
<a-option
|
||||
<el-option
|
||||
v-for="item in conArrData[1].columnList"
|
||||
:label="item.name"
|
||||
:value="item.keyword"
|
||||
>{{ item.name }}</a-option
|
||||
>
|
||||
</a-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" title="查看数据">
|
||||
<a-table
|
||||
:columns="columnList"
|
||||
:data="columnListData"
|
||||
:pagination="false"
|
||||
size="small"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="2" label="查看数据">
|
||||
<el-table :data="columnListData" stripe style="width: 100%" height="345" empty-text="暂无数据">
|
||||
<el-table-column
|
||||
:prop="item.dataIndex"
|
||||
:label="item.title"
|
||||
v-for="(item, index) in columnList"
|
||||
:key="index"
|
||||
/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div v-else class="dissatisfy">
|
||||
<div class="dissatisfy_box">
|
||||
<img
|
||||
|
@ -64,8 +68,9 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import http from "@/scripts/request";
|
||||
import http from "@/utils/request";
|
||||
import { reactive, toRefs, watch, ref } from "vue";
|
||||
const activeName = ref("1");
|
||||
const data = ref({
|
||||
joinType: "inner",
|
||||
rightNodeId: "",
|
||||
|
@ -208,6 +213,15 @@ const tabsChange = (key) => {
|
|||
flex: 1;
|
||||
display: flex;
|
||||
padding: 0px 16px;
|
||||
font-size: 14px;
|
||||
h4 {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
h5 {
|
||||
font-size: 14px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.left {
|
||||
flex: 0 0 300px;
|
||||
}
|
||||
|
@ -215,6 +229,7 @@ const tabsChange = (key) => {
|
|||
flex: auto;
|
||||
.content {
|
||||
display: flex;
|
||||
|
||||
& > div {
|
||||
flex: 1;
|
||||
margin-left: 16px;
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
<template>
|
||||
<div id="output" v-if="LinkedDataIf">
|
||||
<a-table
|
||||
:columns="columnList"
|
||||
:data="columnListData"
|
||||
:pagination="false"
|
||||
size="small"
|
||||
|
||||
<el-table :data="columnListData" stripe style="width: 100%" height="400" empty-text="暂无数据">
|
||||
<el-table-column
|
||||
:prop="item.dataIndex"
|
||||
:label="item.title"
|
||||
v-for="(item, index) in columnList"
|
||||
:key="index"
|
||||
/>
|
||||
</el-table>
|
||||
</div>
|
||||
<div v-else class="dissatisfy">
|
||||
<div class="dissatisfy_box">
|
||||
|
@ -17,7 +20,7 @@
|
|||
|
||||
<script setup>
|
||||
import { ref, toRefs } from "vue";
|
||||
import http from "@/scripts/request";
|
||||
import http from "@/utils/request";
|
||||
const props = defineProps({
|
||||
nodeValue: {
|
||||
type: Object,
|
||||
|
|
|
@ -22,12 +22,14 @@
|
|||
</ul>
|
||||
</div>
|
||||
<div class="disposition_right">
|
||||
<a-table
|
||||
:columns="columnList"
|
||||
:data="columnListData"
|
||||
:pagination="false"
|
||||
size="small"
|
||||
<el-table :data="columnListData" stripe style="width: 100%" height="360" empty-text="暂无数据">
|
||||
<el-table-column
|
||||
:prop="item.dataIndex"
|
||||
:label="item.title"
|
||||
v-for="(item, index) in columnList"
|
||||
:key="index"
|
||||
/>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -64,6 +66,7 @@ const clickChange = () => {
|
|||
flex: 0 0 300px;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
border-right: 1px solid #e9e9e9;
|
||||
.title {
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
|
@ -77,6 +80,7 @@ const clickChange = () => {
|
|||
span {
|
||||
color: #0db3a6;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
ul {
|
||||
|
|
|
@ -1,50 +1,64 @@
|
|||
<template>
|
||||
<a-tabs
|
||||
default-active-key="1"
|
||||
@change="tabsChange"
|
||||
<el-tabs
|
||||
v-model="activeName"
|
||||
@tab-change="tabsChange"
|
||||
v-if="conArrData.length == 0"
|
||||
>
|
||||
<a-tab-pane key="1" title="节点配置">
|
||||
<el-tab-pane name="1" label="节点配置">
|
||||
<div class="grouping-content">
|
||||
<div class="grouping-content-left">
|
||||
<div class="group-title"><span class="label">结构解析字段</span></div>
|
||||
<a-dropdown @select="handleSelect" position="bl">
|
||||
<a-button type="primary" size="small">
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
<template #default>添加结构解析字段</template>
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-doption
|
||||
|
||||
|
||||
<el-dropdown @command="handleSelect" position="bl">
|
||||
<el-button type="primary">
|
||||
添加结构解析字段<el-icon class="el-icon--right"
|
||||
><arrow-down
|
||||
/></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in columnList"
|
||||
:key="item.id"
|
||||
:value="item.keyword"
|
||||
>{{ item.name }}</a-doption
|
||||
:command="item.keyword"
|
||||
>{{ item.name }}</el-dropdown-item
|
||||
>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</el-dropdown>
|
||||
|
||||
<div class="grouping-list">
|
||||
<div class="grouping-list-item" v-for="item in leftGroupingList">
|
||||
<span class="name">{{ item.name }}</span>
|
||||
|
||||
<div class="del" @click="clickLeftDel(index)">
|
||||
<icon-delete />
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" title="查看数据">
|
||||
<a-table
|
||||
:columns="dataColumnList"
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="2" label="查看数据">
|
||||
<el-table
|
||||
:data="columnListData"
|
||||
:pagination="false"
|
||||
size="small"
|
||||
stripe
|
||||
style="width: 100%"
|
||||
height="360"
|
||||
empty-text="暂无数据"
|
||||
>
|
||||
<el-table-column
|
||||
:prop="item.dataIndex"
|
||||
:label="item.title"
|
||||
v-for="(item, index) in dataColumnList"
|
||||
:key="index"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div v-else class="dissatisfy">
|
||||
<div class="dissatisfy_box">
|
||||
<img src="@/assets/imgs/oneNode.f1997e1e.png" alt="" />
|
||||
|
@ -54,10 +68,10 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import http from "@/scripts/request";
|
||||
import http from "@/utils/request";
|
||||
import { ref, reactive, nextTick, toRefs } from "vue";
|
||||
import { IconPlus, IconDelete } from "@arco-design/web-vue/es/icon";
|
||||
|
||||
const activeName = ref("1");
|
||||
const columnList = ref([]);
|
||||
|
||||
const leftGroupingList = ref([]); //left 数据列表
|
||||
|
@ -123,7 +137,6 @@ const disposeLineList = () => {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
console.log("不存在");
|
||||
nodeValueData.value = {
|
||||
|
@ -179,14 +192,13 @@ const initData = () => {
|
|||
nodeValueData.value.groupColumnNameList.push(item.keyword);
|
||||
});
|
||||
|
||||
|
||||
nodeValue.value.data = JSON.stringify(nodeValueData.value);
|
||||
console.log(nodeValue.value);
|
||||
};
|
||||
|
||||
//查看数据
|
||||
const dataColumnList = ref([])
|
||||
const columnListData = ref([])
|
||||
const dataColumnList = ref([]);
|
||||
const columnListData = ref([]);
|
||||
const getDataStream = () => {
|
||||
http
|
||||
.post("/api/metadata/data_stream/exec", {
|
||||
|
|
|
@ -71,15 +71,26 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<a-modal
|
||||
width="auto"
|
||||
v-model:visible="data.visible"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
|
||||
|
||||
<el-dialog
|
||||
v-model="data.visible"
|
||||
title="选择数据库"
|
||||
width="60%"
|
||||
:before-close="handleCancel"
|
||||
>
|
||||
<template #title> 选择数据库 </template>
|
||||
<usedatabase ref="usedatabaseRef"></usedatabase>
|
||||
</a-modal>
|
||||
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleCancel">确定</el-button>
|
||||
<el-button type="primary" @click="handleCancel">
|
||||
取消
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<div id="disposition" v-if="dispositionIf">
|
||||
<configureSource
|
||||
|
@ -109,23 +120,17 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
// import configureSource from "./components/source.vue";
|
||||
// import output from "./components/output.vue";
|
||||
// import join from "./components/join.vue";
|
||||
// import dataExtend from "./components/dataExtend.vue";
|
||||
// import fieldSetting from "./components/fieldSetting.vue";
|
||||
// import filter from "./components/filter.vue";
|
||||
// import group from "./components/group.vue";
|
||||
// import structure from "./components/structure.vue";
|
||||
// import usedatabase from "./usedatabase.vue";
|
||||
import http from '@/utils/request.js'
|
||||
import {
|
||||
reactive,
|
||||
nextTick,
|
||||
ref,
|
||||
getCurrentInstance,
|
||||
markRaw,
|
||||
} from "vue";
|
||||
import configureSource from "./components/source.vue";
|
||||
import output from "./components/output.vue";
|
||||
import join from "./components/join.vue";
|
||||
import dataExtend from "./components/dataExtend.vue"; //算法公式
|
||||
import fieldSetting from "./components/fieldSetting.vue"; //字段设置
|
||||
import filter from "./components/filter.vue";
|
||||
import group from "./components/group.vue";
|
||||
import structure from "./components/structure.vue";
|
||||
import usedatabase from "./usedatabase.vue";
|
||||
import http from "@/utils/request.js";
|
||||
import { reactive, nextTick, ref, getCurrentInstance, markRaw } from "vue";
|
||||
import draggable from "vuedraggable";
|
||||
import { jsPlumb } from "jsplumb";
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
@ -218,7 +223,7 @@ const data = reactive({
|
|||
],
|
||||
nodeValue: {}, //临时存储目标节点
|
||||
lineList: [], //连接线数据
|
||||
visible: false,
|
||||
visible: true,
|
||||
});
|
||||
const conArr = ref([]);
|
||||
const plumbIns = ref(null);
|
||||
|
@ -960,11 +965,13 @@ const cancel = () => {
|
|||
.data-design-right {
|
||||
width: calc(100vw - 150px);
|
||||
height: calc(100vh - 45px);
|
||||
background: #f0f3fa;
|
||||
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACFJREFUeNpiZGBg4GegAsBlCD8TqSYNQg2Mo6FEBAAIMACdPABtrSW/IQAAAABJRU5ErkJggg==");
|
||||
background-repeat: repeat;
|
||||
background-attachment: fixed;
|
||||
background-color: #f0f3fa;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
&.on {
|
||||
height: calc(100vh - 445px);
|
||||
}
|
||||
|
@ -984,6 +991,7 @@ const cancel = () => {
|
|||
border: 1px solid #acafb3;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
&.on,
|
||||
&:hover {
|
||||
|
@ -1038,5 +1046,11 @@ const cancel = () => {
|
|||
bottom: 0;
|
||||
left: 150px;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.el-tabs__nav-scroll {
|
||||
padding: 0 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,30 +1,36 @@
|
|||
<template>
|
||||
<div class="usedatabase">
|
||||
<div class="usedatabase_left">
|
||||
<a-tree :data="treeData" :load-more="loadMore" @select="select" />
|
||||
<el-tree
|
||||
:data="treeData"
|
||||
:props="props"
|
||||
:load="loadMore"
|
||||
lazy
|
||||
@node-click="select"
|
||||
/>
|
||||
</div>
|
||||
<div class="usedatabase_right">
|
||||
<div class="usedatabase_right" v-loading="loading">
|
||||
<div v-if="fieldList.length != 0">
|
||||
<div>
|
||||
<a-checkbox
|
||||
:model-value="checkedAll"
|
||||
<el-checkbox
|
||||
v-model="checkedAll"
|
||||
:indeterminate="indeterminate"
|
||||
@change="handleChangeAll"
|
||||
>全选
|
||||
</a-checkbox>
|
||||
</div>
|
||||
<a-checkbox-group
|
||||
v-model="data"
|
||||
@change="handleChange"
|
||||
direction="vertical"
|
||||
>全选</el-checkbox
|
||||
>
|
||||
<a-checkbox :value="item.id" v-for="item in fieldList">{{
|
||||
item.name
|
||||
}}</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</div>
|
||||
<el-checkbox-group v-model="data" @change="handleChange" style="display: flex;
|
||||
flex-direction: column;">
|
||||
<el-checkbox
|
||||
v-for="city in fieldList"
|
||||
:key="city.id"
|
||||
:label="city.id"
|
||||
>{{ city.name }}</el-checkbox
|
||||
>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
<div v-else class="empty">
|
||||
<a-empty />
|
||||
<el-empty description="暂无数据" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,34 +38,43 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
import http from "@/scripts/request";
|
||||
import http from "@/utils/request";
|
||||
import { del } from "vue-demi";
|
||||
|
||||
const fieldList = ref([]);
|
||||
|
||||
const treeData = ref([]);
|
||||
const loading = ref(false);
|
||||
|
||||
const props = {
|
||||
label: "label",
|
||||
children: "children",
|
||||
isLeaf: "leaf",
|
||||
};
|
||||
|
||||
const metadataId = ref(""); //选中的表单id
|
||||
const metadataName = ref(""); //选中的表单id
|
||||
|
||||
//查询库
|
||||
const getProject = () => {
|
||||
const getProject = (resolve) => {
|
||||
http.get("/api/metadata/project").then((resp) => {
|
||||
let arr = [];
|
||||
resp.data.records.map((item) => {
|
||||
arr.push({
|
||||
title: item.name,
|
||||
key: item.id,
|
||||
label: item.name,
|
||||
children: [],
|
||||
isLeaf: false,
|
||||
key: item.id,
|
||||
leaf: false,
|
||||
});
|
||||
});
|
||||
|
||||
treeData.value = arr;
|
||||
// treeData.value = arr;
|
||||
resolve(arr);
|
||||
});
|
||||
};
|
||||
|
||||
//查询字段接口
|
||||
const getMetadata = (id) => {
|
||||
loading.value = true;
|
||||
http
|
||||
.get("/api/metadata/metadataColumn", {
|
||||
metadataId: id,
|
||||
|
@ -73,41 +88,49 @@ const getMetadata = (id) => {
|
|||
resp.data.records.map((item) => {
|
||||
data.value.push(item.id);
|
||||
});
|
||||
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getProject();
|
||||
// getProject();
|
||||
});
|
||||
|
||||
const select = (arr, nodeData) => {
|
||||
if (nodeData.node.isLeaf) {
|
||||
console.log(nodeData.node);
|
||||
metadataName.value = nodeData.node.title;
|
||||
metadataId.value = nodeData.node.key;
|
||||
getMetadata(nodeData.node.key);
|
||||
console.log(nodeData.isLeaf);
|
||||
|
||||
if (nodeData.isLeaf) {
|
||||
console.log(nodeData);
|
||||
metadataName.value = nodeData.data.label;
|
||||
metadataId.value = nodeData.data.key;
|
||||
getMetadata(nodeData.data.key);
|
||||
}
|
||||
};
|
||||
|
||||
const loadMore = (nodeData) => {
|
||||
console.log(nodeData);
|
||||
return new Promise((resolve) => {
|
||||
const loadMore = (nodeData, resolve) => {
|
||||
console.log("nodeData", nodeData);
|
||||
if (nodeData.level === 0) {
|
||||
getProject(resolve);
|
||||
return;
|
||||
}
|
||||
|
||||
http
|
||||
.get("api/metadata/metadata", {
|
||||
projectId: nodeData.key,
|
||||
projectId: nodeData.data.key,
|
||||
})
|
||||
.then((resp) => {
|
||||
let arr = [];
|
||||
resp.data.records.map((item) => {
|
||||
arr.push({
|
||||
title: item.name,
|
||||
label: item.name,
|
||||
key: item.id,
|
||||
isLeaf: true,
|
||||
children: [],
|
||||
leaf: true,
|
||||
});
|
||||
});
|
||||
nodeData.children = arr;
|
||||
resolve();
|
||||
});
|
||||
console.log("arr", arr);
|
||||
return resolve(arr);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -158,7 +181,7 @@ const getColumnList = (clickEfNodeId) => {
|
|||
sortNo: item.sortNo,
|
||||
type: item.type,
|
||||
typeStr: item.typeStr,
|
||||
typeColor:item.typeColor
|
||||
typeColor: item.typeColor,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -172,7 +195,7 @@ const getColumnList = (clickEfNodeId) => {
|
|||
|
||||
const assignInit = (nodeValue) => {
|
||||
let metadataId = JSON.parse(nodeValue.data).metadataId;
|
||||
console.log(metadataId);
|
||||
console.log("metadataId", metadataId);
|
||||
getMetadata(metadataId);
|
||||
};
|
||||
|
||||
|
@ -183,7 +206,7 @@ defineExpose({
|
|||
</script>
|
||||
<style lang="scss">
|
||||
.usedatabase {
|
||||
width: 800px;
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
display: flex;
|
||||
.usedatabase_left {
|
||||
|
@ -191,6 +214,7 @@ defineExpose({
|
|||
padding-right: 20px;
|
||||
margin-right: 20px;
|
||||
border-right: 1px solid rgba(229, 230, 235, 1);
|
||||
overflow-y: auto;
|
||||
}
|
||||
.usedatabase_right {
|
||||
flex: 1;
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
<template>
|
||||
<a-spin :loading="loading" style="width: 100vw; height: 100vh">
|
||||
<a-affix :offsetTop="0">
|
||||
<UIHeader
|
||||
@changeTabName="handleChangeTabName"
|
||||
@submit="handleSubmit"
|
||||
></UIHeader>
|
||||
</a-affix>
|
||||
|
||||
<div class="wk-content">
|
||||
<div class="wk-page-basic" v-show="tabName == 'basic'">
|
||||
<a-card title="基本设置" :bordered="false">
|
||||
<a-form :model="pageStore.page" layout="vertical">
|
||||
<a-form-item
|
||||
field="name"
|
||||
label="列表名称"
|
||||
:rules="[{ required: true, message: '请输入列表名称' }]"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
>
|
||||
<a-input v-model="pageStore.page.name" placeholder="列表名称" />
|
||||
</a-form-item>
|
||||
<a-form-item field="remarks" label="描述">
|
||||
<a-textarea
|
||||
v-model="pageStore.page.remarks"
|
||||
placeholder="描述"
|
||||
:max-length="255"
|
||||
allow-clear
|
||||
show-word-limit
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-card>
|
||||
<a-card title="预览设置" style="margin-top: 20px" :bordered="false">
|
||||
<template #extra>可以复制地址直接访问</template>
|
||||
<a-input v-model="url" readonly disabled />
|
||||
</a-card>
|
||||
</div>
|
||||
<div class="wk-page-list" v-show="tabName == 'list'">
|
||||
<a-card title="数据管理设计" :bordered="false">
|
||||
<a-tabs type="capsule">
|
||||
<a-tab-pane key="tab-datamodel" title="数据模型">
|
||||
<UITableDataModel />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="tab-listpage" title="列表页面">
|
||||
<UITableColumn />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="tab-button" title="按钮配置">
|
||||
<UITableButton />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="tab-filter" title="列表过滤">
|
||||
<UITableFilter />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-card>
|
||||
</div>
|
||||
</div>
|
||||
<a-modal
|
||||
title="提示"
|
||||
v-model:visible="visible"
|
||||
@ok="handleModalOk"
|
||||
@cancel="handleModalCancel"
|
||||
:ok-loading="loading"
|
||||
title-align="start"
|
||||
>
|
||||
保存使用新的设计,此操作无法恢复,是否确认保存?
|
||||
</a-modal>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { nextTick, ref, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
|
||||
import UIHeader from "./ui/ui-header.vue";
|
||||
import UITableDataModel from "./ui/ui-table-datamodel.vue";
|
||||
import UITableColumn from "./ui/ui-table-column.vue";
|
||||
import UITableButton from "./ui/ui-table-button.vue";
|
||||
import UITableFilter from "./ui/ui-table-filter.vue";
|
||||
|
||||
import useAppPageStore from "./store";
|
||||
import http from "@/scripts/request";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const tabName = ref("basic");
|
||||
let pageStore = useAppPageStore();
|
||||
const datamodel = ref(pageStore.datamodel);
|
||||
const loading = ref(false);
|
||||
const visible = ref(false);
|
||||
|
||||
const id = route.params.id;
|
||||
if (id) {
|
||||
loading.value = true;
|
||||
nextTick(() => {
|
||||
initData();
|
||||
});
|
||||
}
|
||||
|
||||
const initData = () => {
|
||||
http.get(`/api/app_page/${id}`).then((resp) => {
|
||||
if (resp.code == 200) {
|
||||
pageStore.page = resp.data;
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleChangeTabName = (name) => {
|
||||
tabName.value = name;
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
const handleModalOk = () => {
|
||||
loading.value = true;
|
||||
var url = pageStore.page.id
|
||||
? "/api/app_page/" + pageStore.page.id
|
||||
: "/api/app_page";
|
||||
http.post(url, pageStore.page).then((resp) => {
|
||||
loading.value = false;
|
||||
if (resp.code == 200) {
|
||||
Message.success("保存页面成功");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleModalCancel = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const url =
|
||||
"http://frame.bctools.cn/page-design-ui/#/list/use?id=796051017488568320&dataModelId=796051014330257408&jvsAppId=dc2d6befc3efaf034ea7a65460d49dc7";
|
||||
</script>
|
||||
|
||||
<style scope>
|
||||
.wk-page-basic {
|
||||
width: 800px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.wk-page-list {
|
||||
width: 1000px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,49 @@
|
|||
import { defineStore } from "pinia";
|
||||
|
||||
const useAppPageStore = defineStore("appPageData", {
|
||||
state: () => ({
|
||||
page: {
|
||||
id: "",
|
||||
name: "",
|
||||
remarks: "",
|
||||
type: "crud",
|
||||
models: [],
|
||||
columns: [],
|
||||
buttons: [
|
||||
{
|
||||
label: "新增",
|
||||
place: "top",
|
||||
type: "new",
|
||||
},
|
||||
{
|
||||
label: "修改",
|
||||
place: "row",
|
||||
type: "edit",
|
||||
},
|
||||
{
|
||||
label: "详情",
|
||||
place: "row",
|
||||
type: "detail",
|
||||
},
|
||||
{
|
||||
label: "删除",
|
||||
place: "row",
|
||||
type: "del",
|
||||
},
|
||||
{
|
||||
label: "导入",
|
||||
place: "top",
|
||||
type: "import",
|
||||
},
|
||||
{
|
||||
label: "导出",
|
||||
place: "top",
|
||||
type: "export",
|
||||
},
|
||||
],
|
||||
filters: [],
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
export default useAppPageStore;
|
|
@ -0,0 +1,45 @@
|
|||
<template>
|
||||
<div class="wk-header">
|
||||
<div class="wk-header-left">页面编辑器</div>
|
||||
<div class="wk-header-center">
|
||||
<el-tabs :hide-content="true" @tab-click="handleChangeTab">
|
||||
<el-tab-pane key="basic" title="页面设置"></el-tab-pane>
|
||||
<a-tab-pane key="list" title="列表设计"></a-tab-pane>
|
||||
<a-tab-pane key="role" title="页面权限"></a-tab-pane>
|
||||
<a-tab-pane key="data" title="数据设置"></a-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div class="wk-header-right">
|
||||
<el-button size="small" type="primary" @click="handlerSubmit"
|
||||
>保存</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const emit = defineEmits(["changeTabName", "submit"]);
|
||||
|
||||
const handleChangeTab = (tabName) => {
|
||||
emit("changeTabName", tabName);
|
||||
};
|
||||
|
||||
const handlerSubmit = () => {
|
||||
emit("submit");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.wk-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
-webkit-box-align: center;
|
||||
padding: 0 20px;
|
||||
height: 45px;
|
||||
border-bottom: 2px solid #f0f2f5;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,198 @@
|
|||
<template>
|
||||
<div class="toolbar">
|
||||
<a-button size="mini" @click="handleAddClick">新增一行</a-button>
|
||||
</div>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="pageStore.page.buttons"
|
||||
:pagination="false"
|
||||
:draggable="{ type: 'handle', width: 40 }"
|
||||
@change="handleDraggable"
|
||||
>
|
||||
<template #label="{ rowIndex }">
|
||||
<a-input
|
||||
size="mini"
|
||||
placeholder="请输入按钮名称"
|
||||
v-model="pageStore.page.buttons[rowIndex].label"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #place="{ rowIndex, record }">
|
||||
<a-select
|
||||
size="mini"
|
||||
placeholder="请选择按钮位置"
|
||||
v-model="pageStore.page.buttons[rowIndex].place"
|
||||
:disabled="!record.is_edit"
|
||||
>
|
||||
<a-option
|
||||
v-for="item of placeOptions"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
:key="item.value"
|
||||
/>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<template #type="{ rowIndex, record }">
|
||||
<a-select
|
||||
size="mini"
|
||||
placeholder="请选择按钮类型"
|
||||
v-model="pageStore.page.buttons[rowIndex].type"
|
||||
:disabled="!hasShowOtherButton(record)"
|
||||
>
|
||||
<a-option
|
||||
v-for="item of hasShowOtherButton(record)
|
||||
? buttonTypeOptions
|
||||
: defaultButtonTypeOptions"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
:key="item.value"
|
||||
/>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #isShow="{ rowIndex }">
|
||||
<a-switch
|
||||
size="mini"
|
||||
v-model="pageStore.page.buttons[rowIndex].is_show"
|
||||
/>
|
||||
</template>
|
||||
<template #actions="{ rowIndex, record }">
|
||||
<a-link
|
||||
@click="handleDelClick(rowIndex)"
|
||||
v-if="hasShowDesignButton(record)"
|
||||
>设计</a-link
|
||||
>
|
||||
<a-link
|
||||
@click="handleDelClick(rowIndex)"
|
||||
v-if="hasShowOtherButton(record)"
|
||||
>删除</a-link
|
||||
>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import useAppPageStore from "../store";
|
||||
|
||||
const pageStore = useAppPageStore();
|
||||
|
||||
const placeOptions = ref([
|
||||
{
|
||||
label: "顶部",
|
||||
value: "top",
|
||||
},
|
||||
{
|
||||
label: "行内",
|
||||
value: "row",
|
||||
},
|
||||
]);
|
||||
|
||||
const defaultButtonTypeOptions = ref([
|
||||
{
|
||||
label: "新增",
|
||||
value: "new",
|
||||
},
|
||||
{
|
||||
label: "修改",
|
||||
value: "edit",
|
||||
},
|
||||
{
|
||||
label: "详情",
|
||||
value: "detail",
|
||||
},
|
||||
{
|
||||
label: "删除",
|
||||
value: "del",
|
||||
},
|
||||
{
|
||||
label: "导入",
|
||||
value: "import",
|
||||
},
|
||||
{
|
||||
label: "导出",
|
||||
value: "export",
|
||||
},
|
||||
]);
|
||||
|
||||
const buttonTypeOptions = ref([
|
||||
{
|
||||
label: "表单",
|
||||
value: "form",
|
||||
},
|
||||
{
|
||||
label: "逻辑引擎",
|
||||
value: "logic-engine",
|
||||
},
|
||||
{
|
||||
label: "内部地址",
|
||||
value: "link-in",
|
||||
},
|
||||
{
|
||||
label: "外部地址",
|
||||
value: "link-out",
|
||||
},
|
||||
]);
|
||||
|
||||
const handleAddClick = () => {
|
||||
pageStore.page.buttons.push({});
|
||||
};
|
||||
|
||||
const handleDelClick = (index) => {
|
||||
pageStore.page.buttons.splice(index, 1);
|
||||
};
|
||||
|
||||
const handleDraggable = (_data) => {
|
||||
pageStore.page.buttons = _data;
|
||||
};
|
||||
|
||||
const hasShowDesignButton = (btn) => {
|
||||
return btn.type != "del";
|
||||
};
|
||||
|
||||
const hasShowOtherButton = (btn) => {
|
||||
return (
|
||||
btn.type == "form" ||
|
||||
btn.type == "logic-engine" ||
|
||||
btn.type == "link-in" ||
|
||||
btn.type == "link-out"
|
||||
);
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: "按钮名称",
|
||||
slotName: "label",
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "按钮位置",
|
||||
slotName: "place",
|
||||
width: 200,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "按钮类型",
|
||||
slotName: "type",
|
||||
width: 200,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "是否显示",
|
||||
slotName: "isShow",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slotName: "actions",
|
||||
align: "left",
|
||||
width: 120,
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toolbar {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,116 @@
|
|||
<template>
|
||||
<div class="toolbar">
|
||||
<a-button size="mini" @click="handleAddClick">新增一行</a-button>
|
||||
</div>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="pageStore.page.columns"
|
||||
:pagination="false"
|
||||
:draggable="{ type: 'handle', width: 40 }"
|
||||
@change="handleDraggable"
|
||||
>
|
||||
<template #name="{ rowIndex }">
|
||||
<a-select
|
||||
size="mini"
|
||||
placeholder="请选择字段"
|
||||
v-model="pageStore.page.columns[rowIndex].name"
|
||||
@change="(e) => handleChangeName(rowIndex, e)"
|
||||
>
|
||||
<a-option
|
||||
v-for="item of pageStore.page.models"
|
||||
:value="item.name"
|
||||
:label="item.label"
|
||||
:key="item.name"
|
||||
/>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #label="{ rowIndex }">
|
||||
<a-input
|
||||
size="mini"
|
||||
placeholder="请输入显示名称"
|
||||
v-model="pageStore.page.columns[rowIndex].label"
|
||||
/>
|
||||
</template>
|
||||
<template #isShow="{ rowIndex }">
|
||||
<a-switch
|
||||
size="mini"
|
||||
v-model="pageStore.page.columns[rowIndex].is_show"
|
||||
/>
|
||||
</template>
|
||||
<template #config>
|
||||
<a-button size="mini" type="text">配置</a-button>
|
||||
</template>
|
||||
<template #isQuery="{ rowIndex }">
|
||||
<a-switch
|
||||
size="mini"
|
||||
v-model="pageStore.page.columns[rowIndex].is_query"
|
||||
/>
|
||||
</template>
|
||||
<template #actions="{ rowIndex }">
|
||||
<a-button size="mini" type="text" @click="handleDelClick(rowIndex)"
|
||||
>删除</a-button
|
||||
>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import useAppPageStore from "../store";
|
||||
|
||||
const pageStore = useAppPageStore();
|
||||
|
||||
const handleAddClick = () => {
|
||||
pageStore.page.columns.push({
|
||||
is_show: true,
|
||||
is_query: true,
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelClick = (index) => {
|
||||
pageStore.page.columns.splice(index, 1);
|
||||
};
|
||||
|
||||
const handleChangeName = (index, name) => {
|
||||
const opt = pageStore.page.models.find((item) => item.name == name);
|
||||
pageStore.page.columns[index].label = opt ? opt.label : "";
|
||||
};
|
||||
|
||||
const handleDraggable = (_data) => {
|
||||
pageStore.page.columns = _data;
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: "字段名",
|
||||
slotName: "name",
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "显示中文名",
|
||||
slotName: "label",
|
||||
},
|
||||
{
|
||||
title: "是否显示",
|
||||
slotName: "isShow",
|
||||
},
|
||||
{
|
||||
title: "显示配置",
|
||||
slotName: "config",
|
||||
},
|
||||
{
|
||||
title: "是否查询",
|
||||
slotName: "isQuery",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slotName: "actions",
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toolbar {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,140 @@
|
|||
<template>
|
||||
<div class="toolbar">
|
||||
<a-space>
|
||||
<a-button size="mini" @click="handleAddClick">新增一行</a-button>
|
||||
<a-button size="mini">批量增加</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="pageStore.page.models"
|
||||
:pagination="false"
|
||||
:draggable="{ type: 'handle', width: 40 }"
|
||||
@change="handleDraggable"
|
||||
>
|
||||
<template #label="{ rowIndex }">
|
||||
<a-input
|
||||
size="mini"
|
||||
placeholder="请输入显示中文名"
|
||||
v-model="pageStore.page.models[rowIndex].label"
|
||||
/>
|
||||
</template>
|
||||
<template #name="{ rowIndex }">
|
||||
<a-input
|
||||
size="mini"
|
||||
placeholder="请输入显示字段名"
|
||||
v-model="pageStore.page.models[rowIndex].name"
|
||||
/>
|
||||
</template>
|
||||
<template #type="{ rowIndex }">
|
||||
<a-select
|
||||
size="mini"
|
||||
placeholder="请选择字段类型"
|
||||
v-model="pageStore.page.models[rowIndex].type"
|
||||
>
|
||||
<a-option value="string">字符</a-option>
|
||||
<a-option value="integer">数字</a-option>
|
||||
<a-option value="date">日期</a-option>
|
||||
<a-option value="price">货币</a-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #length="{ rowIndex }">
|
||||
<a-input-number
|
||||
size="mini"
|
||||
placeholder="字符长度"
|
||||
v-model="pageStore.page.models[rowIndex].length"
|
||||
/>
|
||||
</template>
|
||||
<template #digit="{ rowIndex }">
|
||||
<a-input-number
|
||||
size="mini"
|
||||
placeholder="位数"
|
||||
v-model="pageStore.page.models[rowIndex].digit"
|
||||
/>
|
||||
</template>
|
||||
<template #scale="{ rowIndex }">
|
||||
<a-input-number
|
||||
size="mini"
|
||||
placeholder="小数点"
|
||||
v-model="pageStore.page.models[rowIndex].scale"
|
||||
/>
|
||||
</template>
|
||||
<template #actions="{ rowIndex }">
|
||||
<a-button size="mini" type="text" @click="handleDelClick(rowIndex)"
|
||||
>删除</a-button
|
||||
>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import useAppPageStore from "../store";
|
||||
|
||||
const pageStore = useAppPageStore();
|
||||
|
||||
const handleAddClick = () => {
|
||||
pageStore.page.models.push({
|
||||
is_show: true,
|
||||
is_query: true,
|
||||
key: pageStore.page.models.lenth,
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelClick = (index) => {
|
||||
pageStore.page.models.splice(index, 1);
|
||||
};
|
||||
|
||||
const handleDraggable = (_data) => {
|
||||
pageStore.page.models = _data;
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: "显示中文名",
|
||||
slotName: "label",
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "字段名",
|
||||
slotName: "name",
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "字段类型",
|
||||
slotName: "type",
|
||||
width: 180,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "字段长度",
|
||||
slotName: "length",
|
||||
width: 150,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "位数",
|
||||
slotName: "digit",
|
||||
width: 150,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "小数点位数",
|
||||
slotName: "scale",
|
||||
width: 150,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slotName: "actions",
|
||||
width: 100,
|
||||
align: "center",
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toolbar {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,146 @@
|
|||
<template>
|
||||
<div class="toolbar">
|
||||
<a-button size="mini" @click="handleAddClick">新增一行</a-button>
|
||||
</div>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="pageStore.page.filters"
|
||||
:pagination="false"
|
||||
>
|
||||
<template #name="{ rowIndex }">
|
||||
<a-select
|
||||
size="mini"
|
||||
placeholder="请选择字段"
|
||||
v-model="pageStore.page.filters[rowIndex].name"
|
||||
>
|
||||
<a-option
|
||||
v-for="item of pageStore.page.models"
|
||||
:value="item.name"
|
||||
:label="item.label"
|
||||
:key="item.name"
|
||||
/>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<template #rule="{ rowIndex }">
|
||||
<a-select
|
||||
size="mini"
|
||||
placeholder="请选择规则"
|
||||
v-model="pageStore.page.filters[rowIndex].rule"
|
||||
>
|
||||
<a-option
|
||||
v-for="item of ruleOptions"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
:key="item.value"
|
||||
/>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<template #value="{ rowIndex }">
|
||||
<a-select
|
||||
size="mini"
|
||||
placeholder="请选择或者输入"
|
||||
v-model="pageStore.page.filters[rowIndex].value"
|
||||
allow-create
|
||||
>
|
||||
<a-option
|
||||
v-for="item of valueOptions"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
:key="item.value"
|
||||
/>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #isShow="{ rowIndex }">
|
||||
<a-switch
|
||||
size="mini"
|
||||
v-model="pageStore.page.filters[rowIndex].is_show"
|
||||
/>
|
||||
</template>
|
||||
<template #actions="{ rowIndex }">
|
||||
<a-button size="mini" type="text" @click="handleDelClick(rowIndex)"
|
||||
>删除</a-button
|
||||
>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import useAppPageStore from "../store";
|
||||
|
||||
const pageStore = useAppPageStore();
|
||||
|
||||
const ruleOptions = ref([
|
||||
{
|
||||
label: "等于",
|
||||
value: "eq",
|
||||
},
|
||||
{
|
||||
label: "包含",
|
||||
value: "like",
|
||||
},
|
||||
{
|
||||
label: "不包含",
|
||||
value: "not like",
|
||||
},
|
||||
]);
|
||||
|
||||
const valueOptions = ref([
|
||||
{
|
||||
label: "当前登录用户ID",
|
||||
value: "user_id",
|
||||
},
|
||||
{
|
||||
label: "当前登录用户名",
|
||||
value: "username",
|
||||
},
|
||||
{
|
||||
label: "当前登录用户所在部门",
|
||||
value: "dept",
|
||||
},
|
||||
]);
|
||||
|
||||
const handleAddClick = () => {
|
||||
pageStore.page.filters.push({
|
||||
is_show: true,
|
||||
is_edit: true,
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelClick = (index) => {
|
||||
pageStore.page.filters.splice(index, 1);
|
||||
console.log(pageStore.page.filters);
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: "字段名",
|
||||
slotName: "name",
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "规则",
|
||||
slotName: "rule",
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: "值",
|
||||
slotName: "value",
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slotName: "actions",
|
||||
width: 100,
|
||||
align: "center",
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toolbar {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
|
@ -27,8 +27,10 @@ export default defineConfig({
|
|||
host: '0.0.0.0', // 解决“vite use `--host` to expose”-- 0.0.0.0 将监听所有地址
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'https://fywz.btdit.cn/',
|
||||
target: 'http://10.0.0.29:9999',
|
||||
// target: 'https://fywz.btdit.cn/',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
// ws: true,// 开启webSocket
|
||||
}
|
||||
}
|
||||
|
|
80
yarn.lock
80
yarn.lock
|
@ -22,16 +22,6 @@
|
|||
"@codemirror/view" "^6.6.0"
|
||||
"@lezer/common" "^1.0.0"
|
||||
|
||||
"@codemirror/commands@6.x", "@codemirror/commands@^6.0.0":
|
||||
version "6.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.2.4.tgz#b8a0e5ce72448c092ba4c4b1d902e6f183948aec"
|
||||
integrity sha512-42lmDqVH0ttfilLShReLXsDfASKLXzfyC36bzwcqzox9PlHulMcsUOfHXNo2X2aFMVNUoQ7j+d4q5bnfseYoOA==
|
||||
dependencies:
|
||||
"@codemirror/language" "^6.0.0"
|
||||
"@codemirror/state" "^6.2.0"
|
||||
"@codemirror/view" "^6.0.0"
|
||||
"@lezer/common" "^1.0.0"
|
||||
|
||||
"@codemirror/lang-javascript@^6.1.9":
|
||||
version "6.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/lang-javascript/-/lang-javascript-6.1.9.tgz#19065ad32db7b3797829eca01b8d9c69da5fd0d6"
|
||||
|
@ -45,7 +35,7 @@
|
|||
"@lezer/common" "^1.0.0"
|
||||
"@lezer/javascript" "^1.0.0"
|
||||
|
||||
"@codemirror/language@6.x", "@codemirror/language@^6.0.0", "@codemirror/language@^6.6.0":
|
||||
"@codemirror/language@^6.0.0", "@codemirror/language@^6.6.0":
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.7.0.tgz#9f1c8923e3234376a40f3392e4a0451e9b4adb8f"
|
||||
integrity sha512-4SMwe6Fwn57klCUsVN0y4/h/iWT+XIXFEmop2lIHHuWO0ubjCrF3suqSZLyOQlznxkNnNbOOfKe5HQbQGCAmTg==
|
||||
|
@ -66,16 +56,7 @@
|
|||
"@codemirror/view" "^6.0.0"
|
||||
crelt "^1.0.5"
|
||||
|
||||
"@codemirror/search@^6.0.0":
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-6.5.0.tgz#308f9968434e0e6ed59c9ec36a0239eb1dfc5d92"
|
||||
integrity sha512-64/M40YeJPToKvGO6p3fijo2vwUEj4nACEAXElCaYQ50HrXSvRaK+NHEhSh73WFBGdvIdhrV+lL9PdJy2RfCYA==
|
||||
dependencies:
|
||||
"@codemirror/state" "^6.0.0"
|
||||
"@codemirror/view" "^6.0.0"
|
||||
crelt "^1.0.5"
|
||||
|
||||
"@codemirror/state@6.x", "@codemirror/state@^6.0.0", "@codemirror/state@^6.1.4", "@codemirror/state@^6.2.0":
|
||||
"@codemirror/state@^6.0.0", "@codemirror/state@^6.1.4":
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.2.1.tgz#6dc8d8e5abb26b875e3164191872d69a5e85bd73"
|
||||
integrity sha512-RupHSZ8+OjNT38zU9fKH2sv+Dnlr8Eb8sl4NOnnqz95mCFTZUaiRP8Xv5MeeaG0px2b8Bnfe7YGwCV3nsBhbuw==
|
||||
|
@ -90,7 +71,7 @@
|
|||
"@codemirror/view" "^6.0.0"
|
||||
"@lezer/highlight" "^1.0.0"
|
||||
|
||||
"@codemirror/view@6.x", "@codemirror/view@^6.0.0", "@codemirror/view@^6.6.0":
|
||||
"@codemirror/view@^6.0.0", "@codemirror/view@^6.6.0":
|
||||
version "6.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.13.0.tgz#a86c3c5e588a7e2fc0e8043c8ae9fdcc608f5eb7"
|
||||
integrity sha512-oXTfJzHJ5Tl7f6T8ZO0HKf981zubxgKohjddLobbntbNZHlOZGMRL+pPZGtclDWFaFJWtGBYRGyNdjQ6Xsx5yA==
|
||||
|
@ -518,18 +499,18 @@ braces@^3.0.2, braces@~3.0.2:
|
|||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
codemirror@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-6.0.1.tgz#62b91142d45904547ee3e0e0e4c1a79158035a29"
|
||||
integrity sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==
|
||||
codemirror-editor-vue3@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/codemirror-editor-vue3/-/codemirror-editor-vue3-2.3.0.tgz#e6c97aba62eee8bc1d980ea78e112179777d5a32"
|
||||
integrity sha512-e6y/2wBL4Xb4SD10e/jq/lcoIeiWPMw2XnF6KePLlbmOphZ830XGU3kSz52qkoa9RUjaY6zHuSlwd09o13O/oQ==
|
||||
dependencies:
|
||||
"@codemirror/autocomplete" "^6.0.0"
|
||||
"@codemirror/commands" "^6.0.0"
|
||||
"@codemirror/language" "^6.0.0"
|
||||
"@codemirror/lint" "^6.0.0"
|
||||
"@codemirror/search" "^6.0.0"
|
||||
"@codemirror/state" "^6.0.0"
|
||||
"@codemirror/view" "^6.0.0"
|
||||
codemirror "^5.64.0"
|
||||
diff-match-patch "^1.0.5"
|
||||
|
||||
codemirror@^5.64.0:
|
||||
version "5.65.13"
|
||||
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.13.tgz#c098a6f409db8b5a7c5722788bd9fa3bb2367f2e"
|
||||
integrity sha512-SVWEzKXmbHmTQQWaz03Shrh4nybG0wXx2MEu3FO4ezbPW8IbnZEd5iGHGEffSUaitKYa3i+pHpBsSvw8sPHtzg==
|
||||
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
|
@ -565,6 +546,11 @@ delayed-stream@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||
|
||||
diff-match-patch@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
|
||||
integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==
|
||||
|
||||
element-plus@^2.3.5:
|
||||
version "2.3.5"
|
||||
resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-2.3.5.tgz#5b04de44fd0ee1bd29ad6ed971d9155982cc1295"
|
||||
|
@ -954,10 +940,10 @@ scule@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/scule/-/scule-1.0.0.tgz#895e6f4ba887e78d8b9b4111e23ae84fef82376d"
|
||||
integrity sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==
|
||||
|
||||
sortablejs@1.10.2:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290"
|
||||
integrity sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==
|
||||
sortablejs@1.14.0:
|
||||
version "1.14.0"
|
||||
resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.14.0.tgz#6d2e17ccbdb25f464734df621d4f35d4ab35b3d8"
|
||||
integrity sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==
|
||||
|
||||
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
|
||||
version "1.0.2"
|
||||
|
@ -1065,16 +1051,6 @@ vite@^4.3.9:
|
|||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
vue-codemirror@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-codemirror/-/vue-codemirror-6.1.1.tgz#246697ef4cfa6b2448dd592ade214bb7ff86611f"
|
||||
integrity sha512-rTAYo44owd282yVxKtJtnOi7ERAcXTeviwoPXjIc6K/IQYUsoDkzPvw/JDFtSP6T7Cz/2g3EHaEyeyaQCKoDMg==
|
||||
dependencies:
|
||||
"@codemirror/commands" "6.x"
|
||||
"@codemirror/language" "6.x"
|
||||
"@codemirror/state" "6.x"
|
||||
"@codemirror/view" "6.x"
|
||||
|
||||
vue-demi@*, vue-demi@>=0.14.5:
|
||||
version "0.14.5"
|
||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.5.tgz#676d0463d1a1266d5ab5cba932e043d8f5f2fbd9"
|
||||
|
@ -1098,12 +1074,12 @@ vue@^3.2.47:
|
|||
"@vue/server-renderer" "3.3.4"
|
||||
"@vue/shared" "3.3.4"
|
||||
|
||||
vuedraggable@^2.24.3:
|
||||
version "2.24.3"
|
||||
resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19"
|
||||
integrity sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==
|
||||
vuedraggable@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-4.1.0.tgz#edece68adb8a4d9e06accff9dfc9040e66852270"
|
||||
integrity sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==
|
||||
dependencies:
|
||||
sortablejs "1.10.2"
|
||||
sortablejs "1.14.0"
|
||||
|
||||
w3c-keyname@^2.2.4:
|
||||
version "2.2.7"
|
||||
|
|
Loading…
Reference in New Issue