开始魔改

This commit is contained in:
Binlin B Wang 2022-08-14 15:09:37 +08:00
parent 284263e3e7
commit 1431a586ab
4 changed files with 499 additions and 4 deletions

View File

@ -35,7 +35,7 @@ public class CorsConfig extends OncePerRequestFilter implements WebMvcConfigurer
WebMvcConfigurer.super.addCorsMappings(registry); WebMvcConfigurer.super.addCorsMappings(registry);
registry.addMapping("/**") registry.addMapping("/**")
.allowedHeaders("*") .allowedHeaders("*")
.allowedMethods("POST", "GET") .allowedMethods("POST", "GET","PUT","DELETE")
.allowedOrigins("*"); .allowedOrigins("*");
} }
@ -72,7 +72,8 @@ public class CorsConfig extends OncePerRequestFilter implements WebMvcConfigurer
//自定义跨域域名检查 //自定义跨域域名检查
response.setHeader("Access-Control-Allow-Origin", originUrl); response.setHeader("Access-Control-Allow-Origin", originUrl);
response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
//response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "1800");//30分钟 response.setHeader("Access-Control-Max-Age", "1800");//30分钟
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, content-type"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with, content-type");
} }

View File

@ -31,7 +31,7 @@
<script> <script>
import ProcessTree from './process/ProcessTree.vue' import ProcessTree from './process/ProcessTree.vue'
import NodeConfig from '../../common/process/config/NodeConfig' import NodeConfig from '../../common/process/config/NodeConfig'
//
export default { export default {
name: "ProcessDesign", name: "ProcessDesign",
components: {ProcessTree, NodeConfig}, components: {ProcessTree, NodeConfig},

View File

@ -36,9 +36,11 @@ export default {
processTrees.push(h('div', {style:{'text-align': 'center'}}, [ processTrees.push(h('div', {style:{'text-align': 'center'}}, [
h('div', {class:{'process-end': true}, domProps: {innerHTML:'流程结束'}}) h('div', {class:{'process-end': true}, domProps: {innerHTML:'流程结束'}})
])) ]))
console.log(processTrees)
return h('div', {class:{'_root': true}, ref:'_root'}, processTrees) return h('div', {class:{'_root': true}, ref:'_root'}, processTrees)
}, },
methods: { methods: {
// demo
getDomTree(h, node) { getDomTree(h, node) {
this.toMapping(node); this.toMapping(node);
if (this.isPrimaryNode(node)){ if (this.isPrimaryNode(node)){
@ -105,8 +107,13 @@ export default {
toMapping(node){ toMapping(node){
if (node && node.id){ if (node && node.id){
//console.log("node=> " + node.id + " name:" + node.name + " type:" + node.type) //console.log("node=> " + node.id + " name:" + node.name + " type:" + node.type)
this.nodeMap.set(node.id, node) let newNode = {
...node
}
newNode.children = []
this.nodeMap.set(newNode.id, newNode)
} }
console.log(this.nodeMap)
}, },
insertCoverLine(h, index, doms, branchs){ insertCoverLine(h, index, doms, branchs){
if (index === 0){ if (index === 0){

View File

@ -0,0 +1,487 @@
<script>
//
import Approval from '@/views/common/process/nodes/ApprovalNode.vue'
import Cc from '@/views/common/process/nodes/CcNode.vue'
import Concurrent from '@/views/common/process/nodes/ConcurrentNode.vue'
import Condition from '@/views/common/process/nodes/ConditionNode.vue'
import Trigger from '@/views/common/process/nodes/TriggerNode.vue'
import Delay from '@/views/common/process/nodes/DelayNode.vue'
import Empty from '@/views/common/process/nodes/EmptyNode.vue'
import Root from '@/views/common/process/nodes/RootNode.vue'
import Node from '@/views/common/process/nodes/Node.vue'
import DefaultProps from "./DefaultNodeProps"
export default {
name: "ProcessTree",
components: {Node, Root, Approval, Cc, Trigger, Concurrent, Condition, Delay, Empty},
data() {
return {
valid: true
}
},
computed:{
nodeMap(){
return this.$store.state.nodeMap;
},
dom(){
return this.$store.state.design.process;
}
},
render(h, ctx) {
console.log("渲染流程树")
this.nodeMap.clear()
let processTrees = this.getDomTree(h, this.dom)
//
processTrees.push(h('div', {style:{'text-align': 'center'}}, [
h('div', {class:{'process-end': true}, domProps: {innerHTML:'流程结束'}})
]))
console.log(processTrees)
return h('div', {class:{'_root': true}, ref:'_root'}, processTrees)
},
methods: {
// demo
getDomTree(h, node) {
this.toMapping(node);
if (this.isPrimaryNode(node)){
//
let childDoms = this.getDomTree(h, node.children)
this.decodeAppendDom(h, node, childDoms)
return [h('div', {'class':{'primary-node': true}}, childDoms)];
}else if (this.isBranchNode(node)){
let index = 0;
//
let branchItems = node.branchs.map(branchNode => {
//
this.toMapping(branchNode);
let childDoms = this.getDomTree(h, branchNode.children)
this.decodeAppendDom(h, branchNode, childDoms, {level: index + 1, size: node.branchs.length})
//4线线
this.insertCoverLine(h, index, childDoms, node.branchs)
//
index++;
return h('div', {'class':{'branch-node-item': true}}, childDoms);
})
///
branchItems.unshift(h('div',{'class':{'add-branch-btn': true}}, [
h('el-button', {
'class':{'add-branch-btn-el': true},
props: {size: 'small', round: true},
on:{click: () => this.addBranchNode(node)},
domProps: {innerHTML: `添加${this.isConditionNode(node)?'条件':'分支'}`},
}, [])
]));
let bchDom = [h('div', {'class':{'branch-node': true}}, branchItems)]
//
let afterChildDoms = this.getDomTree(h, node.children)
return [h('div', {}, [bchDom, afterChildDoms])]
}else if (this.isEmptyNode(node)){
//
let childDoms = this.getDomTree(h, node.children)
this.decodeAppendDom(h, node, childDoms)
return [h('div', {'class':{'empty-node': true}}, childDoms)];
}else {
//
return [];
}
},
//dom
decodeAppendDom(h, node, dom, props = {}){
props.config = node
dom.unshift(h(node.type.toLowerCase(), {
props: props,
ref: node.id,
key: node.id,
///
on:{
insertNode: type => this.insertNode(type, node),
delNode: () => this.delNode(node),
selected: () => this.selectNode(node),
copy:() => this.copyBranch(node),
leftMove: () => this.branchMove(node, -1),
rightMove: () => this.branchMove(node, 1)
}
}, []))
},
//idmap
toMapping(node){
if (node && node.id){
//console.log("node=> " + node.id + " name:" + node.name + " type:" + node.type)
let newNode = {
...node
}
newNode.children = []
this.nodeMap.set(newNode.id, newNode)
}
console.log(this.nodeMap)
},
insertCoverLine(h, index, doms, branchs){
if (index === 0){
//
doms.unshift(h('div', {'class':{'line-top-left': true}}, []))
doms.unshift(h('div', {'class':{'line-bot-left': true}}, []))
}else if (index === branchs.length - 1){
//
doms.unshift(h('div', {'class':{'line-top-right': true}}, []))
doms.unshift(h('div', {'class':{'line-bot-right': true}}, []))
}
},
copyBranch(node){
let parentNode = this.nodeMap.get(node.parentId)
let branchNode = this.$deepCopy(node)
branchNode.name = branchNode.name + '-copy'
this.forEachNode(parentNode, branchNode, (parent, node) => {
let id = this.getRandomId()
console.log(node, '新id =>'+ id, '老nodeId:' + node.id )
node.id = id
node.parentId = parent.id
})
parentNode.branchs.splice(parentNode.branchs.indexOf(node), 0, branchNode)
this.$forceUpdate()
},
branchMove(node, offset){
let parentNode = this.nodeMap.get(node.parentId)
let index = parentNode.branchs.indexOf(node)
let branch = parentNode.branchs[index + offset]
parentNode.branchs[index + offset] = parentNode.branchs[index]
parentNode.branchs[index] = branch
this.$forceUpdate()
},
//
isPrimaryNode(node){
return node &&
(node.type === 'ROOT' || node.type === 'APPROVAL'
|| node.type === 'CC' || node.type === 'DELAY'
|| node.type === 'TRIGGER');
},
isBranchNode(node){
return node && (node.type === 'CONDITIONS' || node.type === 'CONCURRENTS');
},
isEmptyNode(node){
return node && (node.type === 'EMPTY')
},
//
isConditionNode(node){
return node.type === 'CONDITIONS';
},
//
isBranchSubNode(node){
return node && (node.type === 'CONDITION' || node.type === 'CONCURRENT');
},
isConcurrentNode(node){
return node.type === 'CONCURRENTS'
},
getRandomId(){
return `node_${new Date().getTime().toString().substring(5)}${Math.round(Math.random()*9000+1000)}`
},
//
selectNode(node){
this.$store.commit('selectedNode', node)
this.$emit('selectedNode', node)
},
//
insertNode(type, parentNode){
this.$refs['_root'].click()
//
let afterNode = parentNode.children
//
parentNode.children = {
id: this.getRandomId(),
parentId: parentNode.id,
props: {},
type: type,
}
switch (type){
case 'APPROVAL': this.insertApprovalNode(parentNode, afterNode); break;
case 'CC': this.insertCcNode(parentNode); break;
case 'DELAY': this.insertDelayNode(parentNode); break;
case 'TRIGGER': this.insertTriggerNode(parentNode); break;
case 'CONDITIONS': this.insertConditionsNode(parentNode); break;
case 'CONCURRENTS': this.insertConcurrentsNode(parentNode); break;
default: break;
}
//
if (this.isBranchNode({type: type})){
if (afterNode && afterNode.id){
afterNode.parentId = parentNode.children.children.id
}
this.$set(parentNode.children.children, 'children', afterNode)
}else {
if (afterNode && afterNode.id){
afterNode.parentId = parentNode.children.id
}
this.$set(parentNode.children, 'children', afterNode)
}
this.$forceUpdate()
},
insertApprovalNode(parentNode){
this.$set(parentNode.children, "name", "审批人")
this.$set(parentNode.children, "props", this.$deepCopy(DefaultProps.APPROVAL_PROPS))
},
insertCcNode(parentNode){
this.$set(parentNode.children, "name", "抄送人")
this.$set(parentNode.children, "props", this.$deepCopy(DefaultProps.CC_PROPS))
},
insertDelayNode(parentNode){
this.$set(parentNode.children, "name", "延时处理")
this.$set(parentNode.children, "props", this.$deepCopy(DefaultProps.DELAY_PROPS))
},
insertTriggerNode(parentNode){
this.$set(parentNode.children, "name", "触发器")
this.$set(parentNode.children, "props", this.$deepCopy(DefaultProps.TRIGGER_PROPS))
},
insertConditionsNode(parentNode){
this.$set(parentNode.children, "name", "条件分支")
this.$set(parentNode.children, 'children', {
id: this.getRandomId(),
parentId: parentNode.children.id,
type: "EMPTY"
})
this.$set(parentNode.children, "branchs", [
{
id: this.getRandomId(),
parentId: parentNode.children.id,
type: "CONDITION",
props: this.$deepCopy(DefaultProps.CONDITION_PROPS),
name: "条件1",
children:{}
},{
id: this.getRandomId(),
parentId: parentNode.children.id,
type: "CONDITION",
props: this.$deepCopy(DefaultProps.CONDITION_PROPS),
name: "条件2",
children:{}
}
])
},
insertConcurrentsNode(parentNode){
this.$set(parentNode.children, "name", "并行分支")
this.$set(parentNode.children, 'children',{
id: this.getRandomId(),
parentId: parentNode.children.id,
type: "EMPTY"
})
this.$set(parentNode.children, "branchs", [
{
id: this.getRandomId(),
name: "分支1",
parentId: parentNode.children.id,
type: "CONCURRENT",
props: {},
children:{}
},{
id: this.getRandomId(),
name: "分支2",
parentId: parentNode.children.id,
type: "CONCURRENT",
props: {},
children:{}
}
])
},
getBranchEndNode(conditionNode){
if (!conditionNode.children || !conditionNode.children.id){
return conditionNode;
}
return this.getBranchEndNode(conditionNode.children);
},
addBranchNode(node){
if (node.branchs.length < 8){
node.branchs.push({
id: this.getRandomId(),
parentId: node.id,
name: (this.isConditionNode(node) ? '条件':'分支') + (node.branchs.length + 1),
props: this.isConditionNode(node) ? this.$deepCopy(DefaultProps.CONDITION_PROPS):{},
type: this.isConditionNode(node) ? "CONDITION":"CONCURRENT",
children:{}
})
}else {
this.$message.warning("最多只能添加 8 项😥")
}
},
//
delNode(node){
console.log("删除节点", node)
//
let parentNode = this.nodeMap.get(node.parentId)
if (parentNode){
//
if (this.isBranchNode(parentNode)){
//
parentNode.branchs.splice(parentNode.branchs.indexOf(node), 1)
//1
if (parentNode.branchs.length < 2){
//
let ppNode = this.nodeMap.get(parentNode.parentId)
//
if (parentNode.branchs[0].children && parentNode.branchs[0].children.id){
//
ppNode.children = parentNode.branchs[0].children
ppNode.children.parentId = ppNode.id
//
let endNode = this.getBranchEndNode(parentNode.branchs[0])
//, EMPTY
endNode.children = parentNode.children.children
if (endNode.children && endNode.children.id){
endNode.children.parentId = endNode.id
}
}else {
//EMPTY
ppNode.children = parentNode.children.children
if (ppNode.children && ppNode.children.id){
ppNode.children.parentId = ppNode.id
}
}
}
}else {
//
if (node.children && node.children.id) {
node.children.parentId = parentNode.id
}
parentNode.children = node.children
}
this.$forceUpdate()
}else {
this.$message.warning("出现错误,找不到上级节点😥")
}
},
validateProcess(){
this.valid = true
let err = []
this.validate(err, this.dom)
return err
},
validateNode(err, node){
if (this.$refs[node.id].validate){
this.valid = this.$refs[node.id].validate(err)
}
},
//dom
nodeDomUpdate(node){
this.$refs[node.id].$forceUpdate()
},
//
forEachNode(parent, node, callback){
if (this.isBranchNode(node)){
callback(parent, node)
this.forEachNode(node, node.children, callback)
node.branchs.map(branchNode => {
callback(node, branchNode)
this.forEachNode(branchNode, branchNode.children, callback)
})
}else if (this.isPrimaryNode(node) || this.isEmptyNode(node) || this.isBranchSubNode(node)){
callback(parent, node)
this.forEachNode(node, node.children, callback)
}
},
//
validate(err, node){
if (this.isPrimaryNode(node)){
this.validateNode(err, node)
this.validate(err, node.children)
}else if (this.isBranchNode(node)){
//
node.branchs.map(branchNode => {
//
this.validateNode(err, branchNode)
//
this.validate(err, branchNode.children)
})
this.validate(err, node.children)
}else if (this.isEmptyNode(node)){
this.validate(err, node.children)
}
}
},
watch:{
}
}
</script>
<style lang="less" scoped>
._root{
margin: 0 auto;
}
.process-end{
width: 60px;
margin: 0 auto;
margin-bottom: 20px;
border-radius: 15px;
padding: 5px 10px;
font-size: small;
color: #747474;
background-color: #f2f2f2;
box-shadow: 0 0 10px 0 #bcbcbc;
}
.primary-node{
display: flex;
align-items: center;
flex-direction: column;
}
.branch-node{
display: flex;
justify-content: center;
/*border-top: 2px solid #cccccc;
border-bottom: 2px solid #cccccc;*/
}
.branch-node-item{
position: relative;
display: flex;
background: #f5f6f6;
flex-direction: column;
align-items: center;
border-top: 2px solid #cccccc;
border-bottom: 2px solid #cccccc;
&:before{
content: "";
position: absolute;
top: 0;
left: calc(50% - 1px);
margin: auto;
width: 2px;
height: 100%;
background-color: #CACACA;
}
.line-top-left, .line-top-right, .line-bot-left, .line-bot-right{
position: absolute;
width: 50%;
height: 4px;
background-color: #f5f6f6;
}
.line-top-left{
top: -2px;
left: -1px;
}
.line-top-right{
top: -2px;
right: -1px;
}
.line-bot-left{
bottom: -2px;
left: -1px;
}
.line-bot-right{
bottom: -2px;
right: -1px;
}
}
.add-branch-btn{
position: absolute;
width: 80px;
.add-branch-btn-el{
z-index: 999;
position: absolute;
top: -15px;
}
}
.empty-node{
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
</style>