feat: 后端全量更新 - 含所有本次需求
- Contract.php: 返回合约账户余额(balance_contract) - My.php: 地址管理增加BTC/ETH - AppContract.php: 一键平仓(closeall) - AppProxy.php: 代理专属注册链接 + 分级权限(L1/L2) - site.php: 手续费减半(0.018→0.009) - agent_permission_setup.sql: 代理权限SQL - crypto_news_crawler.py: 新闻自动采集脚本
This commit is contained in:
+222
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (C) 1998-2020 by Northwoods Software Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
import * as go from '../../release/go.js';
|
||||
|
||||
// Contains PoolLink and BPMNLinkingTool classes for the BPMN sample
|
||||
|
||||
/**
|
||||
* PoolLink, a special Link class for message flows from edges of pools
|
||||
*
|
||||
* Used in the <a href="../../projects/bpmn/BPMN.html">BPMN extension</a>.
|
||||
*/
|
||||
export class PoolLink extends go.Link {
|
||||
/**
|
||||
* @hidden @internal
|
||||
*/
|
||||
public getLinkPoint(node: go.Node, port: go.GraphObject, spot: go.Spot, from: boolean, ortho: boolean, othernode: go.Node, otherport: go.GraphObject): go.Point {
|
||||
const r = new go.Rect(port.getDocumentPoint(go.Spot.TopLeft), port.getDocumentPoint(go.Spot.BottomRight));
|
||||
const op = super.getLinkPoint(othernode, otherport, spot, from, ortho, node, port);
|
||||
|
||||
const below = op.y > r.centerY;
|
||||
const y = below ? r.bottom : r.top;
|
||||
if (node.category === 'privateProcess') {
|
||||
if (op.x < r.left) return new go.Point(r.left, y);
|
||||
if (op.x > r.right) return new go.Point(r.right, y);
|
||||
return new go.Point(op.x, y);
|
||||
} else { // otherwise get the standard link point by calling the base class method
|
||||
return super.getLinkPoint(node, port, spot, from, ortho, othernode, otherport);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden @internal
|
||||
* If there are two links from & to same node... and pool is offset in X from node... the link toPoints collide on pool
|
||||
*/
|
||||
public computeOtherPoint(othernode: go.Node, otherport: go.GraphObject): go.Point {
|
||||
const op = super.computeOtherPoint(othernode, otherport);
|
||||
let node = this.toNode;
|
||||
if (node === othernode) node = this.fromNode;
|
||||
if (node !== null) {
|
||||
if (othernode.category === 'privateProcess') {
|
||||
op.x = node.getDocumentPoint(go.Spot.MiddleBottom).x;
|
||||
} else {
|
||||
if ((node === this.fromNode) !== (node.actualBounds.centerY < othernode.actualBounds.centerY)) {
|
||||
op.x -= 1;
|
||||
} else {
|
||||
op.x += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden @internal
|
||||
*/
|
||||
public getLinkDirection(node: go.Node, port: go.GraphObject, linkpoint: go.Point, spot: go.Spot,
|
||||
from: boolean, ortho: boolean, othernode: go.Node, otherport: go.GraphObject): number {
|
||||
if (node.category === 'privateProcess') {
|
||||
const p = port.getDocumentPoint(go.Spot.Center);
|
||||
const op = otherport.getDocumentPoint(go.Spot.Center);
|
||||
const below = op.y > p.y;
|
||||
return below ? 90 : 270;
|
||||
} else {
|
||||
return super.getLinkDirection.call(this, node, port, linkpoint, spot, from, ortho, othernode, otherport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BPMNLinkingTool, a custom linking tool to switch the class of the link created.
|
||||
*
|
||||
* Used in the <a href="../../projects/bpmn/BPMN.html">BPMN extension</a>.
|
||||
* @category Extension
|
||||
*/
|
||||
export class BPMNLinkingTool extends go.LinkingTool {
|
||||
constructor() {
|
||||
super();
|
||||
// don't allow user to create link starting on the To node
|
||||
this.direction = go.LinkingTool.ForwardsOnly;
|
||||
// orthogonal routing during linking
|
||||
this.temporaryLink.routing = go.Link.Orthogonal;
|
||||
// link validation using the validate methods defined below
|
||||
this.linkValidation = (fromnode: go.Node, fromport: go.GraphObject, tonode: go.Node, toport: go.GraphObject) => {
|
||||
return BPMNLinkingTool.validateSequenceLinkConnection(fromnode, fromport, tonode, toport) ||
|
||||
BPMNLinkingTool.validateMessageLinkConnection(fromnode, fromport, tonode, toport);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Override {@link LinkingTool#insertLink} to do some extra BPMN-specific processing.
|
||||
*/
|
||||
public insertLink(fromnode: go.Node, fromport: go.GraphObject, tonode: go.Node, toport: go.GraphObject): go.Link | null {
|
||||
let lsave = null;
|
||||
// maybe temporarily change the link data that is copied to create the new link
|
||||
if (BPMNLinkingTool.validateMessageLinkConnection(fromnode, fromport, tonode, toport)) {
|
||||
lsave = this.archetypeLinkData;
|
||||
this.archetypeLinkData = { category: 'msg' };
|
||||
}
|
||||
|
||||
// create the link in the standard manner by calling the base method
|
||||
const newlink = super.insertLink(fromnode, fromport, tonode, toport);
|
||||
|
||||
// maybe make the label visible
|
||||
if (newlink !== null && fromnode.category === 'gateway') {
|
||||
const label = newlink.findObject('Label');
|
||||
if (label !== null) label.visible = true;
|
||||
}
|
||||
|
||||
// maybe restore the original archetype link data
|
||||
if (lsave !== null) this.archetypeLinkData = lsave;
|
||||
return newlink;
|
||||
}
|
||||
|
||||
// static utility validation routines for linking & relinking as well as insert link logic
|
||||
|
||||
/**
|
||||
* Validate that sequence links don't cross subprocess or pool boundaries.
|
||||
*/
|
||||
public static validateSequenceLinkConnection(fromnode: go.Node, fromport: go.GraphObject, tonode: go.Node, toport: go.GraphObject): boolean {
|
||||
if (fromnode.category === null || tonode.category === null) return true;
|
||||
|
||||
// if either node is in a subprocess, both nodes must be in same subprocess (even for Message Flows)
|
||||
if ((fromnode.containingGroup !== null && fromnode.containingGroup.category === 'subprocess') ||
|
||||
(tonode.containingGroup !== null && tonode.containingGroup.category === 'subprocess')) {
|
||||
if (fromnode.containingGroup !== tonode.containingGroup) return false;
|
||||
}
|
||||
|
||||
if (fromnode.containingGroup === tonode.containingGroup) return true; // a valid Sequence Flow
|
||||
// also check for children in common pool
|
||||
const common = fromnode.findCommonContainingGroup(tonode);
|
||||
return common != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that message links cross pool boundaries.
|
||||
*/
|
||||
public static validateMessageLinkConnection(fromnode: go.Node, fromport: go.GraphObject, tonode: go.Node, toport: go.GraphObject): boolean {
|
||||
if (fromnode.category === null || tonode.category === null) return true;
|
||||
|
||||
if (fromnode.category === 'privateProcess' || tonode.category === 'privateProcess') return true;
|
||||
|
||||
// if either node is in a subprocess, both nodes must be in same subprocess (even for Message Flows)
|
||||
if ((fromnode.containingGroup !== null && fromnode.containingGroup.category === 'subprocess') ||
|
||||
(tonode.containingGroup !== null && tonode.containingGroup.category === 'subprocess')) {
|
||||
if (fromnode.containingGroup !== tonode.containingGroup) return false;
|
||||
}
|
||||
|
||||
if (fromnode.containingGroup === tonode.containingGroup) return false; // an invalid Message Flow
|
||||
|
||||
// also check if fromnode and tonode are in same pool
|
||||
const common = fromnode.findCommonContainingGroup(tonode);
|
||||
return common === null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BPMNRelinkingTool, a custom relinking tool to switch the class of the link reconnected.
|
||||
*
|
||||
* Used in the <a href="../../projects/bpmn/BPMN.html">BPMN extension</a>.
|
||||
*/
|
||||
export class BPMNRelinkingTool extends go.RelinkingTool {
|
||||
constructor() {
|
||||
super();
|
||||
// orthogonal routing during linking
|
||||
this.temporaryLink.routing = go.Link.Orthogonal;
|
||||
// link validation using the validate methods defined below
|
||||
this.linkValidation = (fromnode: go.Node, fromport: go.GraphObject, tonode: go.Node, toport: go.GraphObject) => {
|
||||
return BPMNLinkingTool.validateSequenceLinkConnection(fromnode, fromport, tonode, toport) ||
|
||||
BPMNLinkingTool.validateMessageLinkConnection(fromnode, fromport, tonode, toport);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Override {@link RelinkingTool#reconnectLink} to do some extra BPMN-specific processing.
|
||||
*/
|
||||
public reconnectLink(existinglink: go.Link, newnode: go.Node | null, newport: go.GraphObject | null, toend: boolean): boolean {
|
||||
const diagram = existinglink.diagram;
|
||||
if (diagram === null) return false;
|
||||
const model = diagram.model as go.GraphLinksModel;
|
||||
if (model === null) return false;
|
||||
|
||||
function recreateLinkData(data: any, cat: string) {
|
||||
// Copy existing data, then set from, to, and category
|
||||
const copy = model.copyLinkData(data) as any;
|
||||
copy.from = data.from;
|
||||
copy.to = data.to;
|
||||
copy.category = cat;
|
||||
copy.points = undefined; // don't keep points from existing link
|
||||
model.removeLinkData(data);
|
||||
model.addLinkData(copy);
|
||||
}
|
||||
|
||||
if (super.reconnectLink(existinglink, newnode, newport, toend)) {
|
||||
const data = existinglink.data;
|
||||
const fromnode = existinglink.fromNode;
|
||||
const fromport = existinglink.fromPort;
|
||||
const tonode = existinglink.toNode;
|
||||
const toport = existinglink.toPort;
|
||||
if (fromnode !== null && fromport !== null && tonode !== null && toport !== null) {
|
||||
diagram.startTransaction('Relink updates');
|
||||
if (BPMNLinkingTool.validateMessageLinkConnection(fromnode, fromport, tonode, toport)) {
|
||||
// Recreate the link if the category changed, since it is a different class
|
||||
if (existinglink.category !== 'msg') {
|
||||
recreateLinkData(data, 'msg');
|
||||
}
|
||||
}
|
||||
|
||||
// maybe make the label visible
|
||||
if (fromnode.category === 'gateway') {
|
||||
const label = existinglink.findObject('Label');
|
||||
if (label !== null) label.visible = true;
|
||||
}
|
||||
diagram.commitTransaction('Relink updates');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user