Commit 47731e9f authored by renjintao's avatar renjintao

Merge branch 'product' of git.mes123.com:zhouyx/mes-ui into product-rjt

parents 252a8c26 0fbdb113
......@@ -8305,9 +8305,9 @@
}
},
"gojs": {
"version": "2.1.15",
"resolved": "http://r.cnpmjs.org/gojs/download/gojs-2.1.15.tgz",
"integrity": "sha1-r56WmFimOOa4EnYEKCYO1SRM94M="
"version": "2.1.19",
"resolved": "https://registry.npmjs.org/gojs/-/gojs-2.1.19.tgz",
"integrity": "sha512-K2sJlmNdU5PacFQTPK4QMMaxjl+MSNlM3Nr5Okh7cI37EAFHZ/XVccNojYOV6v7Q9RSDDGFZbExfgniqS5kTww=="
},
"good-listener": {
"version": "1.2.2",
......
......@@ -23,7 +23,7 @@
"echarts-liquidfill": "^2.0.5",
"gantt-elastic": "^1.0.11",
"gantt-elastic-header": "^0.1.11",
"gojs": "^2.1.10",
"gojs": "^2.1.19",
"iview-loader": "^1.3.0",
"iview-pro": "file:./iview-pro",
"js-cookie": "^2.2.1",
......
import Api from '@/plugins/request'
export default {
index: `${workflowUrl}/schema/getpaged`,
paged(params) {
return Api.post(`${workflowUrl}/schema/getpaged`, params);
},
get(params) {
return Api.get(`${workflowUrl}/schema/get`, params);
},
create(params) {
return Api.post(`${workflowUrl}/schema/create`, params);
},
update(params) {
return Api.post(`${workflowUrl}/schema/update`, params);
},
disable(params) { //禁用
return Api.post(`${workflowUrl}/schema/disable`, params);
},
enable(params) { //启用
return Api.post(`${workflowUrl}/schema/enable`, params);
},
delete(params) { //删除:
return Api.delete(`${workflowUrl}/schema/delete`, {
params: params
});
},
detail(params) { //流程设计
return Api.get(`${workflowUrl}/schema/detail`, params);
},
getNode(params) { //流程设计编辑回显
return Api.get(`${workflowUrl}/node/get`, params);
},
updateNode(params) { //流程设计编辑保存
return Api.post(`${workflowUrl}/node/update`, params);
},
}
\ No newline at end of file
<template>
<Form ref="form" :model="entity" :rules="rules" :label-width="90">
<Row>
<!-- <Col :span="12">
<FormItem :label="l('formId')" prop="formId">
<InputNumber v-model="entity.formId"></InputNumber>
</FormItem>
</Col> -->
<Col :span="24">
<FormItem :label="l('name')" prop="name">
<Input v-model="entity.name"></Input>
</FormItem>
</Col>
<Col :span="24">
<FormItem :label="l('operation')" prop="operation">
<Dictionary code="workflow.form.audit.type" v-model="entity.operation" type="radio"></Dictionary>
</FormItem>
</Col>
<Col :span="24">
<FormItem :label="l('rejectOption')" prop="rejectOption">
<Dictionary code="workflow.schema.rejectType" v-model="entity.rejectOption" type="radio"></Dictionary>
</FormItem>
</Col>
<Col :span="24">
<FormItem :label="l('category')" prop="category">
<Dictionary code="workflow.schema.nodeCategory" v-model="entity.category" type="radio"></Dictionary>
</FormItem>
</Col>
<Col :span="24">
<FormItem :label="l('roleIdList')" prop="roleIdList">
<RoleSelect v-model="entity.roleIdList" multiple />
</FormItem>
</Col>
<Col :span="24">
<FormItem :label="l('userIdList')" prop="userIdList">
<UserSelect v-model="entity.userIdList" multiple />
</FormItem>
</Col>
<Col :span="24">
<FormItem :label="l('isFixed')" prop="category">
<Checkbox v-model="entity.isFixed">固定</Checkbox>(固定后,审批人员不能修改。)
</FormItem>
</Col>
</Row>
<FormItem>
<Button type="primary" @click="handleSubmit" :disabled="disabled">保存</Button>
<Button @click="handleClose" class="ml20">取消</Button>
</FormItem>
</Form>
</template>
<script>
import Api from './api'
export default {
name: 'Edit',
data() {
return {
disabled: false,
entity: {name:''},
rules: {
// formId: [{ required: true, message: '必填', trigger: 'change' }],
name: [{ required: true, message: '必填', trigger: 'blur' }]
// rejectOption: [{ required: true, message: '必填', trigger: 'change' }],
// category: [{ required: true, message: '必填', trigger: 'change' }],
// nodeCategory: [{ required: true, message: '必填', trigger: 'change' }]
}
}
},
props: {
eid: Number
},
created(){
if(this.eid>0){
this.load(this.eid);
}
},
methods: {
load(v) {
Api.getNode({ id: v }).then((r) => {
this.entity = r.result
this.entity.userIdList=r.result.userIds||[]
var roleIds=[];
if(r.result.roleList){
r.result.roleList.map(u=>{
roleIds.push(u.id);
})
}
this.entity.roleIdList=roleIds;
// this.$set(this.entity,r.result)
// this.$emit('on-load')
})
},
handleSubmit() {
this.$refs.form.validate((v) => {
if (v) {
console.warn(this.entity);
if(this.entity.userIdList.length+this.entity.roleIdList.length==0){
this.$Message.error('审批人或者审批角色至少选择一个。')
return;
}
this.disabled = true
Api.updateNode(this.entity)
.then((r) => {
this.disabled = false
if (r.success) {
this.$Message.success('保存成功')
this.$emit('on-ok',this.entity)
} else {
this.$Message.error('保存失败')
}
})
.catch((err) => {
this.disabled = false
this.$Message.error('保存失败')
})
}else{
debugger;
this.$Message.error('异常')
}
})
},
handleClose() {
this.$emit('on-close')
},
l(key) {
key = 'node' + '.' + key
return this.$t(key)
}
},
watch: {
eid(v) {
if (v >0) {
this.load(v)
console.log(v)
}
}
}
}
</script>
<template>
<div id="flow">
<div id="myDiagramDiv" class="flex fd">
<div v-height="100" class="flex">
<div id="palette" class="fg"></div>
<div v-width="200" class="tr lh50">
<Button type="primary" class="mr10" @click="save">保存</Button>
</div>
</div>
<div id="draw" class="fg"></div>
</div>
<Modal v-model="detailModal" title="节点属性设置" :width="800" footer-hide>
<component :is="detail" :eid="curId" :data="node" @on-ok="ok" />
</Modal>
</div>
</template>
<script>
import Api from "@/plugins/request";
import go from "gojs";
let $ = go.GraphObject.make;
export default {
name: "",
data() {
return {
detailModal: false,
detail: null,
curId: -1,
node: null,
myDiagram: null
};
},
props: {
eid: String,
default: null
},
mounted() {
this.init();
this.load();
},
methods: {
init() {
// let theme = "black";
let theme = "#2d8cf0";
// fill: "#D1DEDC",
// stroke: "#DC3C00",
let select = $(
go.Adornment,
go.Panel.Auto,
// [2]
$(go.Shape, {
fill: null,
stroke: "black",
strokeWidth: 2,
strokeDashArray: [8, 2, 8, 2],
margin: 0
// padding:4
}),
// [3]
// { width: 500, height: 200 }
$(go.Placeholder)
);
this.myDiagram = $(
go.Diagram,
"draw", // must name or refer to the DIV HTML element
{
LinkDrawn: showLinkLabel, // this DiagramEvent listener is defined below
LinkRelinked: showLinkLabel,
"undoManager.isEnabled": true, // enable undo & redo,
nodeSelectionAdornmentTemplate: select
}
);
function nodeStyle() {
return [
// The Node.location comes from the "loc" property of the node data,
// converted by the Point.parse static method.
// If the Node.location is changed, it updates the "loc" property of the node data,
// converting back using the Point.stringify static method.
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(
go.Point.stringify
),
{
// the Node.location is at the center of each node
locationSpot: go.Spot.Center
}
];
}
// Define a function for creating a "port" that is normally transparent.
// The "name" is used as the GraphObject.portId,
// the "align" is used to determine where to position the port relative to the body of the node,
// the "spot" is used to control how links connect with the port and whether the port
// stretches along the side of the node,
// and the boolean "output" and "input" arguments control whether the user can draw links from or to the port.
function makePort(name, align, spot, output, input) {
var horizontal =
align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);
// the port is basically just a transparent rectangle that stretches along the side of the node,
// and becomes colored when the mouse passes over it
return $(go.Shape, {
fill: "transparent", // changed to a color in the mouseEnter event handler
strokeWidth: 0, // no stroke
width: horizontal ? NaN : 8, // if not stretching horizontally, just 8 wide
height: !horizontal ? NaN : 8, // if not stretching vertically, just 8 tall
alignment: align, // align the port on the main Shape
stretch: horizontal
? go.GraphObject.Horizontal
: go.GraphObject.Vertical,
portId: name, // declare this object to be a "port"
fromSpot: spot, // declare where links may connect at this port
fromLinkable: output, // declare whether the user may draw links from here
toSpot: spot, // declare where links may connect at this port
toLinkable: input, // declare whether the user may draw links to here
cursor: "pointer", // show a different cursor to indicate potential link point
mouseEnter: function(e, port) {
// the PORT argument will be this Shape
if (!e.diagram.isReadOnly) port.fill = "rgba(15,0,25,0.5)";
},
mouseLeave: function(e, port) {
port.fill = "transparent";
// port.fill = "white";
}
});
}
function textStyle(c) {
let color = c || "#f8f8f8";
return {
font: "14px Microsoft YaHei",
stroke: color
};
}
/*添加模版*/
this.myDiagram.nodeTemplateMap.add(
"", // the default category
$(
go.Node,
"Table",
nodeStyle(),
// the main object is a Panel that surrounds a TextBlock with a rectangular Shape
$(
go.Panel,
"Auto",
{
// resizable: true,
doubleClick: (e, obj) => {
this.show(obj.part.data);
}
},
$(
go.Shape,
"Rectangle",
{
fill: "white",
stroke: theme,
strokeWidth: 2,
minSize: new go.Size(80, 50)
},
new go.Binding("figure", "figure"),
new go.Binding("data")
),
$(
go.TextBlock,
textStyle(theme),
{
margin: 8,
maxSize: new go.Size(300, NaN),
wrap: go.TextBlock.WrapFit,
editable: true
},
new go.Binding("text").makeTwoWay()
)
),
// four named ports, one on each side:
makePort("T", go.Spot.Top, go.Spot.TopSide, false, true),
makePort("L", go.Spot.Left, go.Spot.LeftSide, true, true),
makePort("R", go.Spot.Right, go.Spot.RightSide, true, true),
makePort("B", go.Spot.Bottom, go.Spot.BottomSide, true, false)
)
);
this.myDiagram.nodeTemplateMap.add(
"Conditional",
$(
go.Node,
"Table",
nodeStyle(),
// the main object is a Panel that surrounds a TextBlock with a rectangular Shape
$(
go.Panel,
"Auto",
$(
go.Shape,
"Diamond",
{ fill: "#fff", stroke: theme, strokeWidth: 2 },
new go.Binding("figure", "figure")
),
$(
go.TextBlock,
textStyle(theme),
{
margin: 8,
maxSize: new go.Size(60, NaN),
wrap: go.TextBlock.WrapFit,
editable: true
},
new go.Binding("text").makeTwoWay()
)
),
// four named ports, one on each side:
makePort("T", go.Spot.Top, go.Spot.Top, false, true),
makePort("L", go.Spot.Left, go.Spot.Left, true, true),
makePort("R", go.Spot.Right, go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
)
);
this.myDiagram.nodeTemplateMap.add(
"Start",
$(
go.Node,
"Table",
nodeStyle(),
$(
go.Panel,
"Spot",
$(go.Shape, "Circle", {
desiredSize: new go.Size(60, 60),
fill: theme,
stroke: "#09d3ac",
strokeWidth: 0
}),
$(go.TextBlock, "开始", textStyle())
),
// three named ports, one on each side except the top, all output only:
makePort("L", go.Spot.Left, go.Spot.Left, true, false),
makePort("R", go.Spot.Right, go.Spot.Right, true, false),
makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
)
);
this.myDiagram.nodeTemplateMap.add(
"End",
$(
go.Node,
"Table",
nodeStyle(),
$(
go.Panel,
"Spot",
$(go.Shape, "Circle", {
desiredSize: new go.Size(60, 60),
fill: "#D1DEDC",
stroke: "#DC3C00",
strokeWidth: 0
}),
$(go.TextBlock, "结束", textStyle("#909B9A"))
),
// three named ports, one on each side except the bottom, all input only:
makePort("T", go.Spot.Top, go.Spot.Top, false, true),
makePort("L", go.Spot.Left, go.Spot.Left, false, true),
makePort("R", go.Spot.Right, go.Spot.Right, false, true)
)
);
go.Shape.defineFigureGenerator("File", function(shape, w, h) {
var geo = new go.Geometry();
var fig = new go.PathFigure(0, 0, true); // starting point
geo.add(fig);
fig.add(new go.PathSegment(go.PathSegment.Line, 0.75 * w, 0));
fig.add(new go.PathSegment(go.PathSegment.Line, w, 0.25 * h));
fig.add(new go.PathSegment(go.PathSegment.Line, w, h));
fig.add(new go.PathSegment(go.PathSegment.Line, 0, h).close());
var fig2 = new go.PathFigure(0.75 * w, 0, false);
geo.add(fig2);
// The Fold
fig2.add(new go.PathSegment(go.PathSegment.Line, 0.75 * w, 0.25 * h));
fig2.add(new go.PathSegment(go.PathSegment.Line, w, 0.25 * h));
geo.spot1 = new go.Spot(0, 0.25);
geo.spot2 = go.Spot.BottomRight;
return geo;
});
this.myDiagram.nodeTemplateMap.add(
"Comment",
$(
go.Node,
"Auto",
nodeStyle(),
$(go.Shape, "File", {
fill: "#fff",
stroke: theme,
strokeWidth: 2
}),
$(
go.TextBlock,
textStyle(theme),
{
margin: 8,
maxSize: new go.Size(200, NaN),
wrap: go.TextBlock.WrapFit,
textAlign: "center",
editable: true
},
new go.Binding("text").makeTwoWay()
)
// no ports, because no links are allowed to connect with a comment
)
);
// replace the default Link template in the linkTemplateMap
this.myDiagram.linkTemplate = $(
go.Link, // the whole link panel
{
routing: go.Link.AvoidsNodes,
curve: go.Link.JumpOver,
corner: 5,
toShortLength: 4,
relinkableFrom: true,
relinkableTo: true,
reshapable: true,
resegmentable: true,
// mouse-overs subtly highlight links:
mouseEnter: function(e, link) {
link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.2)";
},
mouseLeave: function(e, link) {
link.findObject("HIGHLIGHT").stroke = "transparent";
},
selectionAdorned: false
},
new go.Binding("points").makeTwoWay(),
$(
go.Shape, // the highlight shape, normally transparent
{
isPanelMain: true,
strokeWidth: 8,
stroke: "transparent",
fill: theme,
name: "HIGHLIGHT"
}
),
$(
go.Shape, // the link path shape
{ isPanelMain: true, stroke: theme, strokeWidth: 2 },
new go.Binding("stroke", "isSelected", function(sel) {
return sel ? "dodgerblue" : theme;
}).ofObject()
),
$(
go.Shape, // the "from" end arrowhead
{ fromArrow: "Circle", fill: "#fff", strokeWidth: 2, stroke: theme }
),
$(
go.Shape, // the arrowhead
{ toArrow: "standard", strokeWidth: 2, fill: theme, stroke: theme }
),
$(
go.Panel,
"Auto", // the link label, normally not visible
{
visible: false,
name: "LABEL",
segmentIndex: 2,
segmentFraction: 0.5
},
new go.Binding("visible", "visible").makeTwoWay(),
$(
go.Shape,
"RoundedRectangle", // the label shape
{ fill: "#F8F8F8", strokeWidth: 0 }
),
$(
go.TextBlock,
"Yes", // the label
{
textAlign: "center",
font: "10pt helvetica, arial, sans-serif",
stroke: "#333333",
editable: true
},
new go.Binding("text").makeTwoWay()
)
)
);
function showLinkLabel(e) {
var label = e.subject.findObject("LABEL");
if (label !== null)
label.visible = e.subject.fromNode.data.category === "Conditional";
}
this.myDiagram.toolManager.linkingTool.temporaryLink.routing =
go.Link.Orthogonal;
this.myDiagram.toolManager.relinkingTool.temporaryLink.routing =
go.Link.Orthogonal;
this.myPalette = $(
go.Palette,
"palette", // must name or refer to the DIV HTML element
{
// Instead of the default animation, use a custom fade-down
"animationManager.initialAnimationStyle": go.AnimationManager.None,
InitialAnimationStarting: animateFadeDown, // Instead, animate with this function
nodeTemplateMap: this.myDiagram.nodeTemplateMap, // share the templates used by myDiagram
nodeSelectionAdornmentTemplate: select,
model: new go.GraphLinksModel([
// specify the contents of the Palette
{ category: "Start", text: "开始" },
{ text: "节点" },
{ category: "Conditional", text: "条件" },
{ category: "End", text: "结束" },
{ category: "Comment", text: "备注" }
])
}
);
this.myDiagram.addModelChangedListener(evt => {
if (!evt.isTransactionFinished) return;
var txn = evt.object; // a Transaction
if (txn === null) return;
// iterate over all of the actual ChangedEvents of the Transaction
txn.changes.each(function(e) {
// ignore any kind of change other than adding/removing a node
if (e.modelChange !== "nodeDataArray") return;
// record node insertions and removals
if (e.change === go.ChangedEvent.Insert) {
console.log(
evt.propertyName + " added node with key: " + e.newValue.key
);
} else if (e.change === go.ChangedEvent.Remove) {
console.log(
evt.propertyName + " removed node with key: " + e.oldValue.key
);
}
});
});
function animateFadeDown(e) {
var diagram = e.diagram;
var animation = new go.Animation();
animation.isViewportUnconstrained = true; // So Diagram positioning rules let the animation start off-screen
animation.easing = go.Animation.EaseOutExpo;
animation.duration = 900;
// Fade "down", in other words, fade in from above
animation.add(
diagram,
"position",
diagram.position.copy().offset(0, 200),
diagram.position
);
animation.add(diagram, "opacity", 0, 1);
animation.start();
}
// this.load();
},
load() {
Api.get(`${workflowUrl}/schema/get`, { id: this.eid }).then(r => {
console.warn(r);
// this.myDiagram.model=go.Model.fromJson(r.content);
var data = r.result.content || `{}`;
// this.init(data)
// this.init(data)
this.myDiagram.model = go.Model.fromJson(data);
});
},
save() {
let content = this.myDiagram.model.toJson();
Api.post(`${workflowUrl}/schema/design`, {
id: this.eid,
name: "",
content
}).then(r => {
if (r.success) {
this.$Message.success("保存成功!");
this.load();
}
});
},
show(data) {
if (data.id) {
this.detailModal = true;
this.node = data;
this.curId = data.id;
this.detail = () => import("./edit");
} else {
this.$Message.warning("请先保存流程设计!");
}
},
ok(node) {
if (node.name != this.node.text) {
this.node.text = node.name;
var nodeData = this.myDiagram.model.findNodeDataForKey(this.node.key);
nodeData.text = node.name;
this.myDiagram.model.updateTargetBindings(nodeData);
}
this.detailModal = false;
this.detail = null;
this.curId = -1;
}
}
};
</script>
<style lang="less">
#flow {
// background:#a7a7a7;
margin: -16px;
padding: 0 10px;
canvas:focus {
outline: 0;
}
#myDiagramDiv {
height: calc(100vh - 51px);
display: flex;
}
}
</style>
\ No newline at end of file
......@@ -61,8 +61,12 @@ export default {
async fetch({ store, params }) {
await store.dispatch('loadDictionary') // 加载数据字典
},
mounted(){
this.load(this.eid)
},
methods: {
load(v) {
alert(v)
Api.detail({ id: v }).then((r) => {
this.nodes = r.result.nodes
// this.$emit('on-load')
......
......@@ -24,8 +24,11 @@
<Modal v-model="editModal" title="编辑" footer-hide :mask-closable="false">
<Edit :eid="curId" @on-close="cancel" @on-ok="addOk" />
</Modal>
<Modal v-model="designModal" title="流程设计" :mask-closable="false" fullscreen footer-hide>
<!-- <Modal v-model="designModal" title="流程设计" :mask-closable="false" fullscreen footer-hide>
<Design :eid="curId" />
</Modal> -->
<Modal v-model="designModal" title="流程设计" :mask-closable="false" fullscreen footer-hide>
<component :is="flowDesign" :eid="curId" />
</Modal>
<!-- <Modal
v-model="deletelModal"
......@@ -60,14 +63,14 @@
import Api from './api'
import Add from './add'
import Edit from './edit'
import Design from './design'
// import Design from './design'
import Search from './search'
export default {
name: 'list',
components: {
Add,
Edit,
Design,
// Design,
Search
},
data() {
......@@ -81,6 +84,8 @@ export default {
// value: userInfo.userId
// }
},
flowModal:false,
flowDesign:null,
addModal: false,
editModal: false,
designModal: false,
......@@ -174,6 +179,14 @@ export default {
on: { click: () => this.design(params.row.id) }
},
'流程'
),
h(
'op',
{
attrs: { oprate: 'add' },
on: { click: () => this.flow(params.row.id) }
},
'流程2'
),
h(
'op',
......@@ -217,6 +230,12 @@ export default {
design(id) {
this.designModal = true
this.curId = id
this.flowDesign=()=>import('./design')
},
flow(id) {
this.designModal = true
this.curId = id
this.flowDesign=()=>import('../flow')
},
edit(id) {
this.editModal = true
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment