sh4wmoo 2 лет назад
Родитель
Сommit
3f7141646a

+ 1 - 1
package.json

@@ -14,7 +14,7 @@
     "test:e2e": "vue-cli-service test:e2e"
   },
   "dependencies": {
-    "@antv/x6": "2.1.4",
+    "@antv/x6": "2.2.1",
     "@antv/x6-plugin-clipboard": "^2.1.3",
     "@antv/x6-plugin-dnd": "^2.0.3",
     "@antv/x6-plugin-export": "^2.1.5",

+ 3 - 7
src/components/business/process/node-modal/node-modal.vue

@@ -802,12 +802,6 @@ export default {
       this.removeInvalidEdge(cell)
       //设置节点数据
       cell.setData(this.nodeData, { overwrite: true })
-      //设置节点样式
-      cell.setAttrs({
-        label: { text: this.nodeData.nodeName },
-        text: { text: this.nodeData.nodeName },
-        body: { stroke: '#5F95FF' }
-      })
       // endregion
 
       //region 如果是一览页面的编辑,直接提交保存
@@ -880,6 +874,8 @@ export default {
       // }
       // 销毁提示弹窗
       this.$Message.destroy()
+      // 通过校验标识
+      this.nodeData.isValid=true
       return true
     },
     /**
@@ -985,7 +981,7 @@ export default {
     // //处理无线路由类别
     this.handleRouterType()
     // //过滤调节点组并将json解构成新结构数组
-    this.allNodes = this.graph.getNodes().filter(it => it.shape == 'custom-image').map((it) => {
+    this.allNodes = this.graph.getNodes().filter(it => it.shape == 'custom-html').map((it) => {
       return { id: it.id, name: it.data.nodeName, flowKind:it.data.flowKind, nodeKind:it.data.nodeKind, flgAloneJudge: it.data.flgAloneJudge}
     })
     //设置初始值

+ 9 - 0
src/config/index.js

@@ -1872,6 +1872,15 @@ export default {
     finishCheck: '工艺节点-成检',
     recover: '工艺节点-回收',
     shaping: '工艺节点-成型',
+    registerName: '标准计件',
+    climbKilnName: '装窑车',
+    inKilnName: '窑车入窑',
+    outKilnName: '窑车出窑',
+    uninstallKilnName: '卸窑车',
+    halfCheckName: '半成品检验',
+    finishCheckName: '成品检验',
+    recoverName: '废品回收',
+    shapingName: '成型绑码',
   },
 
   /**

+ 142 - 185
src/view/process/process-flow/config/ProcessConfig.js

@@ -205,8 +205,8 @@ export default class Process {
       .use(new Transform({//图形变换
         resizing: {
           enabled:true,
-          minWidth:64,
-          minHeight:64,
+          minWidth:130,
+          minHeight:60,
         },
         rotating: true,
       }))
@@ -241,55 +241,48 @@ export default class Process {
     const stencil = new Stencil({
       title: '工艺模型',
       target: this.graph,
-      stencilGraphWidth: 200,
-      stencilGraphHeight: 180,
+      stencilGraphWidth: 180,
+      stencilGraphHeight: 800,
       collapsable: true,
+      layoutOptions: {
+        columns: 1,
+        dx: 45,
+        rowHeight:70,
+        dy: 0,
+      },
+      placeholder:'搜索...',
+      notFoundText:'未搜索到结果',
       groups: [
         {
           title: '节点组',
           name: 'group',
-          graphHeight: 80,
+          graphHeight: 60,
           layoutOptions: {
-            columns: 1,
-            marginX: 35,
+            dy: -5,
           },
+          collapsed:true
         },
         {
           title: '计件模型',
           name: 'count',
-          graphHeight: 260,
-          layoutOptions: {
-            rowHeight: 80,
-          },
+          graphHeight: 350,
         },
         {
           title: '检验模型',
           name: 'test',
-          graphHeight: 100,
-          layoutOptions: {
-            rowHeight: 80,
-          },
+          graphHeight: 140,
         },
         {
           title: '特殊模型',
           name: 'special',
-          graphHeight: 100,
-          layoutOptions: {
-            rowHeight: 80,
-          },
+          graphHeight: 140,
         },
       ],
-      layoutOptions: {
-        columns: 2,
-        columnWidth: 80,
-        rowHeight: 55,
-      },
-      placeholder:'搜索...',
-      notFoundText:'未搜索到结果',
+
       //搜索方法
       search: (cell, keyword, groupName, stencil) => {
         if (keyword) {
-          return cell.attr("text/text").includes(keyword);
+          return cell.getData()?.nodeName?.includes(keyword);
         }
         return true;
       },
@@ -702,9 +695,7 @@ export default class Process {
       //节点
       if(cell.shape=='custom-image'){
         //添加节点设置业务数据id
-        cell.setData({'nodeId':cell.id,'ftyId': store.state.user.ftyId,'flowId':parseInt(router.app._route.params.id)})
-        //设置初始未校验样式
-        cell.setAttrs({body: {stroke: 'red',}})
+        cell.setData({'nodeId':cell.id,'ftyId': store.state.user.ftyId,'flowId':parseInt(router.app._route.params.id),"isValid":false})
       }
       //连接线
       if(cell.shape=='edge'){
@@ -798,132 +789,97 @@ export default class Process {
     // endregion
 
     // region 注册自定义节点
-    Graph.registerNode(
-      'custom-rect',
-      {
-        inherit: 'rect',
-        width: 66,
-        height: 36,
-        attrs: {
-          body: {
-            strokeWidth: 1,
-            stroke: '#5F95FF',
-            fill: '#EFF4FF',
-          },
-          text: {
-            fontSize: 12,
-            fill: '#262626',
-          },
-        },
-        ports: { ...ports },
-      },
-      true,
-    )
-
-    Graph.registerNode(
-      'custom-polygon',
-      {
-        inherit: 'polygon',
-        width: 66,
-        height: 36,
-        attrs: {
-          body: {
-            strokeWidth: 1,
-            stroke: '#5F95FF',
-            fill: '#EFF4FF',
-          },
-          text: {
-            fontSize: 12,
-            fill: '#262626',
-          },
-        },
-        ports: {
-          ...ports,
-          items: [
-            {
-              group: 'top',
-            },
-            {
-              group: 'bottom',
-            },
-          ],
-        },
-      },
-      true,
-    )
-
-    Graph.registerNode(
-      'custom-circle',
-      {
-        inherit: 'circle',
-        width: 45,
-        height: 45,
-        attrs: {
-          body: {
-            strokeWidth: 1,
-            stroke: '#5F95FF',
-            fill: '#EFF4FF',
-          },
-          text: {
-            fontSize: 12,
-            fill: '#262626',
-          },
-        },
-        ports: { ...ports },
-      },
-      true,
-    )
-
-    Graph.registerNode(
-      'custom-image',
-      {
-        inherit: 'rect',
-        width: 64,
-        height: 64,
-        markup: [
-          {
-            tagName: 'rect',
-            selector: 'body',
-          },
-          {
-            tagName: 'image',
-          },
-          {
-            tagName: 'text',
-            selector: 'label',
-          },
-        ],
-        attrs: {
-          body: {
-            stroke: '#5F95FF',
-            strokeWidth: 1,
-            fill: '#FFFFFF',
-          },
-          image: {
-            width: 32,
-            height: 32,
-            refX: 22,
-            refY: 22,
-          },
-          label: {
-            refX:6,
-            refY:6,
-            textAnchor: 'left',
-            textVerticalAnchor: 'top',
-            fontSize: 12,
-            fill: 'black',
-            textWrap:{
-              height: '50%',   // 高度为参照元素高度的一半
-              ellipsis: true,  // 文本超出显示范围时,自动添加省略号
-              breakWord: true, // 是否截断单词
-            }
-          },
-        },
-        ports: { ...ports },
-      },
-      true,
-    )
 
+    // region 原节点
+    // Graph.registerNode(
+    //   'custom-image',
+    //   {
+    //     inherit: 'rect',
+    //     width: 64,
+    //     height: 64,
+    //     markup: [
+    //       {
+    //         tagName: 'rect',
+    //         selector: 'body',
+    //       },
+    //       {
+    //         tagName: 'image',
+    //       },
+    //       {
+    //         tagName: 'text',
+    //         selector: 'label',
+    //       },
+    //     ],
+    //     attrs: {
+    //       body: {
+    //         stroke: '#5F95FF',
+    //         strokeWidth: 1,
+    //         fill: '#FFFFFF',
+    //       },
+    //       image: {
+    //         width: 32,
+    //         height: 32,
+    //         refX: 22,
+    //         refY: 22,
+    //       },
+    //       label: {
+    //         refX:6,
+    //         refY:6,
+    //         textAnchor: 'left',
+    //         textVerticalAnchor: 'top',
+    //         fontSize: 12,
+    //         fill: 'black',
+    //         textWrap:{
+    //           height: '50%',   // 高度为参照元素高度的一半
+    //           ellipsis: true,  // 文本超出显示范围时,自动添加省略号
+    //           breakWord: true, // 是否截断单词
+    //         }
+    //       },
+    //     },
+    //     ports: { ...ports },
+    //   },
+    //   true,
+    // )
+    // endregion
+
+    // region 新UI节点
+    Shape.HTML.register({
+      shape: "custom-image",
+      width: 130,
+      height: 60,
+      html(cell) {
+        let div = document.createElement("div");
+        let left = document.createElement("div");
+        let right = document.createElement("div");
+        div.className = "custom-html";
+        left.className = "custom-html-left";
+        right.className = "custom-html-right";
+        let img=document.createElement("img")
+        img.src=cell.getData().image
+        img.width=32
+        img.height=32
+        let title = document.createElement("div");
+        let text = document.createElement("div");
+        title.className = "custom-html-right-title";
+        text.className = "custom-html-right-text";
+        title.innerHTML=cell.getData().nodeName
+        text.innerHTML=cell.getData().nodeKindName
+        left.appendChild(img)
+        right.appendChild(title)
+        right.appendChild(text)
+        div.appendChild(left)
+        div.appendChild(right)
+
+        if(cell.getData().isValid===false){
+          left.style.borderColor='#ed4014'
+          right.style.borderColor='#ed4014'
+        }
+
+        return div;
+      },
+      ports: { ...ports },
+    });
+    // endregion 新UI节点
 
     // region 节点组
     const g1 = this.graph.createNode({
@@ -950,42 +906,44 @@ export default class Process {
         {
           label: '计件',
           image:getImg('登记.png'),
-          nodeKind:'工艺节点-计件',
+          nodeKind:config.nodeKind.register,
+          nodeKindName:config.nodeKind.registerName
         },
         {
           label: '登窑',
           image:getImg('装卸.png'),
-          nodeKind:'工艺节点-登窑',
+          nodeKind:config.nodeKind.climbKiln,
+          nodeKindName:config.nodeKind.climbKilnName
         },
         {
           label: '入窑',
           image:getImg('火炉.png'),
-          nodeKind:'工艺节点-入窑',
+          nodeKind:config.nodeKind.inKiln,
+          nodeKindName:config.nodeKind.inKilnName
         },
         {
           label: '出窑',
           image:getImg('火炉.png'),
-          nodeKind:'工艺节点-出窑',
+          nodeKind:config.nodeKind.outKiln,
+          nodeKindName:config.nodeKind.outKilnName
         },
         {
           label: '卸窑',
           image:getImg('装卸.png'),
-          nodeKind:'工艺节点-卸窑',
+          nodeKind:config.nodeKind.uninstallKiln,
+          nodeKindName:config.nodeKind.uninstallKilnName
         },
       ]
       const countNodes = countImages.map((item) =>
         this.graph.createNode({
           shape: 'custom-image',
-          label: item.label,
-          attrs: { image: { 'xlink:href': item.image, }, },
+          // label: item.label,
           data:{
             nodeName:item.label,
             nodeKind:item.nodeKind,
-          }
-          // shape: 'image', //可选值:Rect Circle Ellipse Polygon Polyline Path Image HTML TextBlock BorderedImage EmbeddedImage InscribedImage Cylinder
-          // imageUrl: item.image,
-          // width: 52,
-          // height: 52,
+            image:item.image,
+            nodeKindName:item.nodeKindName,
+          },
         }),
       )
       //endregion
@@ -995,27 +953,26 @@ export default class Process {
           {
             label: '半检',
             image:getImg('检查.png'),
-            nodeKind:'工艺节点-半检',
+            nodeKind:config.nodeKind.halfCheck,
+            nodeKindName:config.nodeKind.halfCheckName
           },
           {
             label: '成检',
             image:getImg('检查.png'),
-            nodeKind:'工艺节点-成检',
+            nodeKind:config.nodeKind.finishCheck,
+            nodeKindName:config.nodeKind.finishCheckName
           },
         ]
       const testNodes = testImages.map((item) =>
         this.graph.createNode({
           shape: 'custom-image',
-          label: item.label,
-          attrs: { image: { 'xlink:href': item.image, }, },
+          // label: item.label,
           data:{
             nodeName:item.label,
             nodeKind:item.nodeKind,
-          }
-          // shape: 'image', //可选值:Rect Circle Ellipse Polygon Polyline Path Image HTML TextBlock BorderedImage EmbeddedImage InscribedImage Cylinder
-          // imageUrl: item.image,
-          // width: 52,
-          // height: 52,
+            image:item.image,
+            nodeKindName:item.nodeKindName,
+          },
         }),
       )
       //endregion
@@ -1025,31 +982,31 @@ export default class Process {
         {
           label: '回收',
           image:getImg('回收.png'),
-          nodeKind:'工艺节点-回收',
+          nodeKind:config.nodeKind.recover,
+          nodeKindName:config.nodeKind.recoverName
         },
         {
           label: '成型',
           image:getImg('马桶.png'),
-          nodeKind:'工艺节点-成型',
+          nodeKind:config.nodeKind.shaping,
+          nodeKindName:config.nodeKind.shapingName
         },
       ]
       const specialNodes = specialImages.map((item) =>
         this.graph.createNode({
           shape: 'custom-image',
-          label: item.label,
-          attrs: { image: { 'xlink:href': item.image, }, },
+          // label: item.label,
           data:{
             nodeName:item.label,
             nodeKind:item.nodeKind,
-          }
-          // shape: 'image', //可选值:Rect Circle Ellipse Polygon Polyline Path Image HTML TextBlock BorderedImage EmbeddedImage InscribedImage Cylinder
-          // imageUrl: item.image,
-          // width: 52,
-          // height: 52,
+            image:item.image,
+            nodeKindName:item.nodeKindName,
+          },
         }),
       )
       //endregion
 
+
       //region 加载元素节点
       stencil.load(countNodes, 'count')
       stencil.load(testNodes, 'test')

+ 188 - 27
src/view/process/process-flow/process-setting.vue

@@ -6,35 +6,104 @@
         <div id="stencil"></div>
       </Sider>
       <Layout>
-        <!-- 顶部工具栏 -->
-        <Header class="header">
-          <div style="display: flex;align-items: center;margin-right: 50px">
-            <Button @click="()=>{this.graph.exportPNG('',{padding:50})}">导出PNG</Button>
-            <Button @click="exportJson" style="margin-left:10px;">导出JSON</Button>
-            <Upload action="" accept=".json" :before-upload="uploadJson">
-              <Button style="margin:7px 0 0 10px;">导入JSON</Button>
-            </Upload>
-          </div>
-          <div style="min-width: 800px">
-            <Tag color="blue">方向键移动</Tag>
-            <Tag color="blue">右键画布拖动</Tag>
-            <Tag color="blue">ctrl+C 复制</Tag>
-            <Tag color="blue">ctrl+X 剪切</Tag>
-            <Tag color="blue">ctrl+V 粘贴</Tag>
-            <Tag color="blue">ctrl+X 撤销</Tag>
-            <Tag color="blue">ctrl+shift+Z 撤回撤销</Tag>
-            <Tag color="blue">ctrl+alt+A 全选</Tag>
-            <Tag color="blue">del 删除</Tag>
-          </div>
-        </Header>
         <!--   中间流程图  -->
         <Content>
           <div id="container" ref="container" style="width:100%;height:100%"/>
         </Content>
         <!--   底部按钮   -->
         <Footer class="footer">
-          <DkButton style="margin-right: 10px;" ref="save" type="primary" @click="save">{{ $t('save') }}</DkButton>
-          <DkButton ref="close" @click="close('/process/process-flow/index')">{{ $t('close') }}</DkButton>
+          <div class="tools">
+            <Poptip trigger="hover" >
+              <Button icon="ios-bulb"></Button>
+              <div slot="content" style="background: #f8f8f9">
+                <Card title="快捷键说明" icon="ios-options" :padding="0" shadow style="width: 300px;">
+                  <CellGroup>
+                    <Cell title="整体移动画布" extra="右键按住空白处拖动" />
+                    <Cell title="多选" extra="左键按住空白处拖动" />
+                    <Cell title="放大">
+                      <div slot="extra" style="display: flex;align-items: center">
+                        <div class="key">Ctrl</div>
+                        <div class="key">Alt</div>
+                        <div class="key">+</div>
+                        <div style="padding-left:3px">或</div>
+                        <div class="key">Ctrl</div>
+                        <div style="padding-left:3px">+ 鼠标滚轮</div>
+                      </div>
+                    </Cell>
+                    <Cell title="缩小">
+                      <div slot="extra" style="display: flex">
+                        <div class="key">Ctrl</div>
+                        <div class="key">Alt</div>
+                        <div class="key">-</div>
+                        <div style="padding-left:3px">或</div>
+                        <div class="key">Ctrl</div>
+                        <div style="padding-left:3px">+ 鼠标滚轮</div>
+                      </div>
+                    </Cell>
+                    <Cell title="复制">
+                      <div slot="extra" style="display: flex">
+                        <div class="key">Ctrl</div>
+                        <div class="key">C</div>
+                      </div>
+                    </Cell>
+                    <Cell title="剪切">
+                      <div slot="extra" style="display: flex">
+                        <div class="key">Ctrl</div>
+                        <div class="key">X</div>
+                      </div>
+                    </Cell>
+                    <Cell title="粘贴">
+                      <div slot="extra" style="display: flex">
+                        <div class="key">Ctrl</div>
+                        <div class="key">V</div>
+                      </div>
+                    </Cell>
+                    <Cell title="撤销">
+                      <div slot="extra" style="display: flex">
+                        <div class="key">Ctrl</div>
+                        <div class="key">Z</div>
+                      </div>
+                    </Cell>
+                    <Cell title="撤回撤销">
+                      <div slot="extra" style="display: flex">
+                        <div class="key">Ctrl</div>
+                        <div class="key">Shift</div>
+                        <div class="key">Z</div>
+                      </div>
+                    </Cell>
+                    <Cell title="全选">
+                      <div slot="extra" style="display: flex">
+                        <div class="key">Ctrl</div>
+                        <div class="key">Alt</div>
+                        <div class="key">A</div>
+                      </div>
+                    </Cell>
+                    <Cell title="删除">
+                      <div slot="extra" style="display: flex">
+                        <div class="key">Del</div>
+                      </div>
+                    </Cell>
+
+                  </CellGroup>
+                </Card>
+              </div>
+            </Poptip>
+            <Tooltip content="导出PNG">
+              <Button icon="ios-camera" @click="()=>{this.graph.exportPNG('',{padding:50})}"></Button>
+            </Tooltip>
+            <Tooltip content="导出JSON">
+              <Button icon="ios-cloud-download" @click="exportJson"></Button>
+            </Tooltip>
+            <Tooltip content="导入JSON">
+              <Upload action="" accept=".json" :before-upload="uploadJson">
+                <Button icon="ios-cloud-upload"></Button>
+              </Upload>
+            </Tooltip>
+          </div>
+          <div>
+            <DkButton style="margin-right: 10px;" ref="save" type="primary" @click="save">{{ $t('save') }}</DkButton>
+            <DkButton ref="close" @click="close('/process/process-flow/index')">{{ $t('close') }}</DkButton>
+          </div>
         </Footer>
       </Layout>
     </Layout>
@@ -288,7 +357,7 @@ export default {
 
       //节点的单个校验未通过
       let invalidNodes =allNodes.filter(it => {
-        if (it.getAttrs()?.body?.stroke === 'red') {
+        if (!it.getData().isValid) {
           this.$Message.warning('[' + it.getData()?.nodeName + '] 节点设置有误,请检查')
           return true
         }
@@ -445,11 +514,103 @@ export default {
 }
 
 .footer {
-  background: #ededed;
+  /*background: #fff;*/
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 10px 30px;
+}
+.key{
+  align-items: center;
+  background-image: linear-gradient(180deg,#f2f4f5,#fff);
+  border: 1px solid #d1d5d9;
+  border-radius: 4px;
+  box-shadow: 0 1px 0 0 #b8bfc4, inset 0 2px 0 0 #fff;
+  color: #666;
   display: flex;
-  justify-content: right;
-  padding: 10px 50px;
+  font-size: 12px;
+  font-weight: 500;
+  height: 20px;
+  justify-content: center;
+  margin-left: 5px;
+  min-width: 20px;
+  padding: 0 5px;
+}
+/deep/ .ivu-card-head{
+  padding: 7px 8px!important;
+}
+/deep/ .ivu-cell{
+  padding: 3px 8px!important;
+}
+/deep/ .ivu-cell-group{
+  padding: 2px 0 !important;
+}
+/deep/ .ivu-btn-icon-only{
+  padding: 0 !important;
+  font-size: 28px!important;
+  width: 48px!important;
+  height: 48px!important;
+  /*border: none!important;*/
+  /*border-radius:0px!important;*/
+}
+/deep/ .ivu-tooltip{
+  height: 48px!important;
 }
+/deep/ .custom-html{
+  height: 100%;
+  width: 100%;
+  display: flex;
+  border:solid 1px #E9F1FF;
+}
+/deep/ .custom-html-left{
+  background: #E9F1FF;
+  height: 100%;
+  width: 40%;
+  border: solid 2px #E9F1FF;
+  border-right: none;
+  border-top-left-radius: 10px;
+  border-bottom-left-radius: 10px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);
+
+}
+/deep/ .custom-html-right{
+  background: #fff;
+  height: 100%;
+  /*width: 60%;*/
+  border: solid 2px #fff;
+  border-left: none;
+  border-top-right-radius: 10px;
+  border-bottom-right-radius: 10px;
+  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);
+  overflow: hidden;
+  flex: 1;
+}
+/deep/ .custom-html-right-title{
+  font-size: 14px;
+  font-weight: bold;
+  padding-left: 10px;
+  width:  100%;
+  height: 50%;
+  padding-top: 6px;
+  align-items: center;
+  color: #4C4C4C;
+  overflow: hidden;
+  text-overflow:ellipsis;
+  white-space: nowrap;
+}
+/deep/ .custom-html-right-text{
+  padding: 3px 0 0 10px ;
+  width:  100%;
+  height: 50%;
+  font-size: 10px;
+  display: flex;
+  align-items: self-start;
+  color: #B6B6B6;
+}
+
 </style>