695593266@qq.com 7 miesięcy temu
rodzic
commit
e105cfc7a3

+ 282 - 0
src/views/pick/pickApply/components/flow.vue

@@ -0,0 +1,282 @@
+<template>
+  <el-dialog
+    title="流程"
+    :before-close="handleClose"
+    :visible.sync="dialogVisible"
+    :close-on-click-modal="false"
+    :append-to-body="true"
+    width="80%"
+  >
+    <div class="app-container" style="padding: 15px">
+      <!-- 审批记录 -->
+      <el-card class="box-card" v-loading="tasksLoad">
+        <div slot="header" class="clearfix">
+          <span class="el-icon-picture-outline">审批记录</span>
+        </div>
+        <el-col :span="16" :offset="4">
+          <div class="block">
+            <el-timeline>
+              <el-timeline-item
+                v-for="(item, index) in tasks"
+                :key="index"
+                :icon="getTimelineItemIcon(item)"
+                :type="getTimelineItemType(item)"
+              >
+                <p style="font-weight: 700">任务:{{ item.name }}</p>
+                <el-card :body-style="{ padding: '10px' }">
+                  <label
+                    v-if="item.assigneeUser"
+                    style="font-weight: normal; margin-right: 30px"
+                  >
+                    审批人:{{ item.assigneeUser.nickname }}
+                    <el-tag type="info" size="mini">{{
+                      item.assigneeUser.deptName
+                    }}</el-tag>
+                  </label>
+                  <label style="font-weight: normal" v-if="item.createTime"
+                    >创建时间:</label
+                  >
+                  <label style="color: #8a909c; font-weight: normal">{{
+                    item.createTime
+                  }}</label>
+                  <label
+                    v-if="item.endTime"
+                    style="margin-left: 30px; font-weight: normal"
+                    >审批时间:</label
+                  >
+                  <label
+                    v-if="item.endTime"
+                    style="color: #8a909c; font-weight: normal"
+                  >
+                    {{ item.endTime }}</label
+                  >
+                  <label
+                    v-if="item.durationInMillis"
+                    style="margin-left: 30px; font-weight: normal"
+                    >耗时:</label
+                  >
+                  <label
+                    v-if="item.durationInMillis"
+                    style="color: #8a909c; font-weight: normal"
+                  >
+                    {{ getDateStar(item.durationInMillis) }}
+                  </label>
+                  <p v-if="item.reason">
+                    <el-tag :type="getTimelineItemType(item)">{{
+                      item.reason
+                    }}</el-tag>
+                  </p>
+                </el-card>
+              </el-timeline-item>
+            </el-timeline>
+          </div>
+        </el-col>
+      </el-card>
+      <!-- 高亮流程图 -->
+      <el-card class="box-card" v-loading="processInstanceLoading">
+        <div slot="header" class="clearfix">
+          <span class="el-icon-picture-outline">流程图1</span>
+        </div>
+
+        <my-process-viewer
+          key="designer"
+          v-model="bpmnXML"
+          v-bind="bpmnControlForm"
+          :activityData="activityList"
+          :processInstanceData="processInstance"
+          :taskData="tasks"
+        />
+      </el-card>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+  import { getProcessDefinitionBpmnXML } from '@/api/bpm/index';
+  import store from '@/store';
+  import { getProcessInstance } from '@/api/bpm/index';
+  import { getDate } from '@/utils/dateUtils';
+  import dictMixins from '@/mixins/dictMixins';
+  import { getTaskListByProcessInstanceId } from '@/api/bpm/index';
+  import { getActivityList } from '@/api/bpm/index';
+  // import Vue from 'vue';
+
+  // 流程实例的详情页,可用于审批
+  export default {
+    name: 'outsourcing',
+    mixins: [dictMixins],
+
+    components: {},
+    data() {
+      return {
+        // 遮罩层
+        processInstanceLoading: true,
+        dialogVisible: false,
+
+        // 流程实例
+        id: undefined, // 流程实例的编号
+        processInstance: {},
+
+        // BPMN 数据
+        bpmnXML: null,
+        bpmnControlForm: {
+          prefix: 'flowable'
+        },
+        activityList: [],
+
+        // 审批记录
+        tasksLoad: true,
+        tasks: []
+      };
+    },
+    created() {
+      // this.id = this.$route.query.id;
+      // if (!this.id) {
+      //   this.$message.error('未传递 id 参数,无法查看流程信息');
+      //   return;
+      // }
+      // this.getDetail();
+    },
+    methods: {
+      open(id) {
+        this.id = id;
+        this.dialogVisible = true;
+        this.getDetail();
+      },
+      /** 获得流程实例 */
+      getDetail() {
+        // 获得流程实例相关
+        this.processInstanceLoading = true;
+        getProcessInstance(this.id).then((response) => {
+          if (!response) {
+            this.$message.error('查询不到流程信息!');
+            return;
+          }
+          // 设置流程信息
+          this.processInstance = response;
+
+          // //将业务表单,注册为动态组件
+          // const path = this.processInstance.processDefinition.formCustomViewPath;
+          // Vue.component("async-biz-form-component", function (resolve) {
+          //   require([`@/views${path}`], resolve);
+          // });
+          // 加载流程图
+          getProcessDefinitionBpmnXML(
+            this.processInstance.processDefinition.id
+          ).then((response) => {
+            this.bpmnXML = response;
+          });
+          // 加载活动列表
+          getActivityList({
+            processInstanceId: this.processInstance.id
+          }).then((response) => {
+            console.log(response, 'response');
+            this.activityList = response;
+          });
+
+          // 取消加载中
+          this.processInstanceLoading = false;
+        });
+
+        // 获得流程任务列表(审批记录)
+        this.tasksLoad = true;
+        getTaskListByProcessInstanceId(this.id).then((response) => {
+          // 审批记录
+          this.tasks = [];
+          // 移除已取消的审批
+          response.forEach((task) => {
+            if (task.result !== 4) {
+              this.tasks.push(task);
+            }
+          });
+          // 排序,将未完成的排在前面,已完成的排在后面;
+          this.tasks.sort((a, b) => {
+            // 有已完成的情况,按照完成时间倒序
+            if (a.endTime && b.endTime) {
+              return b.endTime - a.endTime;
+            } else if (a.endTime) {
+              return 1;
+            } else if (b.endTime) {
+              return -1;
+              // 都是未完成,按照创建时间倒序
+            } else {
+              return b.createTime - a.createTime;
+            }
+          });
+
+          // 需要审核的记录
+          const userId = store.getters.userId;
+          this.tasks.forEach((task) => {
+            if (task.result !== 1 && task.result !== 6) {
+              // 只有待处理才需要
+              return;
+            }
+            if (!task.assigneeUser || task.assigneeUser.id !== userId) {
+              // 自己不是处理人
+              return;
+            }
+          });
+
+          // 取消加载中
+          this.tasksLoad = false;
+        });
+      },
+      getDateStar(ms) {
+        return getDate(ms);
+      },
+      getTimelineItemIcon(item) {
+        if (item.result === 1) {
+          return 'el-icon-time';
+        }
+        if (item.result === 2) {
+          return 'el-icon-check';
+        }
+        if (item.result === 3) {
+          return 'el-icon-close';
+        }
+        if (item.result === 4) {
+          return 'el-icon-remove-outline';
+        }
+        if (item.result === 5) {
+          return 'el-icon-back';
+        }
+        return '';
+      },
+      getTimelineItemType(item) {
+        if (item.result === 1) {
+          return 'primary';
+        }
+        if (item.result === 2) {
+          return 'success';
+        }
+        if (item.result === 3) {
+          return 'danger';
+        }
+        if (item.result === 4) {
+          return 'info';
+        }
+        if (item.result === 5) {
+          return 'warning';
+        }
+        if (item.result === 6) {
+          return 'default';
+        }
+        return '';
+      },
+      handleClose() {
+        this.dialogVisible = false;
+      }
+    }
+  };
+</script>
+
+<style lang="scss">
+  .my-process-designer {
+    height: calc(100vh - 200px);
+  }
+
+  .box-card {
+    width: 100%;
+    margin-bottom: 20px;
+  }
+</style>

+ 226 - 14
src/views/pick/pickApply/components/selfDetailed.vue

@@ -1,12 +1,13 @@
 <template>
   <div>
-    <el-dialog
+    <ele-modal
       title="领料列表"
       :visible.sync="visible"
       :before-close="handleClose"
       :close-on-click-modal="false"
       :close-on-press-escape="false"
       append-to-body
+      :maxable="true"
       width="80%"
     >
       <div class="tableZ_box">
@@ -24,6 +25,13 @@
             <div class="name">领料人</div>
             <div class="content">{{ dataObj.executorName }}</div>
           </div>
+
+          <div class="col">
+            <div class="name">类型</div>
+            <div class="content" v-if="dataObj.type == 1">自建领料</div>
+            <div class="content" v-if="dataObj.type == 2">工单领料</div>
+            <div class="content" v-if="dataObj.type == 3">委外领料</div>
+          </div>
         </div>
       </div>
 
@@ -47,20 +55,79 @@
         <template v-slot:demandQuantity="{ row }">
           {{ row.demandQuantity }} {{ row.unit }}
         </template>
+
+        <template v-slot:specification="{ row }">
+          {{ row.specification ? row.specification : row.specifications }}
+        </template>
+
+        <template v-slot:action="{ row, $index }">
+          <el-link
+            type="text"
+            @click="outboundDetails(row, $index)"
+            v-if="dataObj.status == 2"
+            >出库详情</el-link
+          >
+        </template>
       </ele-pro-table>
-    </el-dialog>
+
+      <div class="card_box" v-if="outboundDetailList.length != 0">
+        <div class="rx-bc">
+          <div class="item_box rx-bc">
+            <div class="time">出库单详情 </div>
+          </div>
+        </div>
+        <ele-pro-table
+          ref="table"
+          :columns="columnsTwo"
+          max-height="320px"
+          :datasource="outboundDetailList"
+          cache-key="detailed"
+          highlight-current-row
+          :need-page="false"
+        >
+          <template v-slot:empty>
+            <div class="empty">暂无领料数据</div>
+          </template>
+
+          <template v-slot:index="{ row, $index }">
+            {{ $index + 1 }}
+          </template>
+
+          <template v-slot:status="{ row }">
+            <el-tag>已出库</el-tag>
+          </template>
+
+          <template v-slot:weight="{ row, $index }">
+            <span>{{ row.weight || 0 }}{{ row.weightUnit }}</span>
+          </template>
+
+          <!-- <template v-slot:action="{ row, $index }">
+            <el-link
+              type="text"
+              @click="outboundDetails(row, $index)"
+              v-if="dataObj.status == 2"
+              >出库详情</el-link
+            >
+          </template> -->
+        </ele-pro-table>
+      </div>
+    </ele-modal>
+    <outboundDetail ref="outboundDetailRef" />
   </div>
 </template>
 <script>
+  import outboundDetail from '@/views/produce/components/picking/outboundDetail.vue';
+  import { getOutboundDetail } from '@/api/produce/picking.js';
   export default {
-    components: {},
+    components: { outboundDetail },
     props: {
       detailedObj: {}
     },
     data() {
       return {
         visible: true,
-        dataObj: null
+        dataObj: null,
+        outboundDetailList: []
       };
     },
 
@@ -77,60 +144,195 @@
             showOverflowTooltip: true,
             slot: 'index'
           },
+          {
+            width: 100,
+            prop: 'batchNo',
+            label: '批次号',
+            slot: 'batchNo',
+            align: 'center'
+          },
 
           {
             prop: 'categoryCode',
             label: '编码',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
 
           {
             prop: 'categoryName',
             label: '名称',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
 
           {
             prop: 'demandQuantity',
             label: '数量',
             align: 'center',
-            slot: 'demandQuantity'
+            slot: 'demandQuantity',
+            showOverflowTooltip: true
           },
 
           {
             prop: 'warehouseName',
             label: '领料仓库',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
 
           {
             prop: 'warehouseLeaderName',
             label: '审核人',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
 
           {
             prop: 'brandNo',
             label: '牌号',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
           {
             prop: 'model',
             label: '型号',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
           {
             prop: 'specification',
             label: '规格',
-            align: 'center'
+            align: 'center',
+            slot: 'specification',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'action',
+            label: '操作',
+            align: 'center',
+            fixed: 'right',
+            slot: 'action',
+            resizable: false,
+            showOverflowTooltip: true
           }
         ];
+      },
+
+      columnsTwo() {
+        let columnsVersion = this.columnsVersion;
+        return [
+          ...[
+            {
+              width: 55,
+              type: 'index',
+              columnKey: 'index',
+              align: 'center',
+              label: '序号',
+              fixed: 'left'
+            },
+            {
+              minWidth: 120,
+              prop: 'categoryCode',
+              label: '编码',
+              align: 'center',
+              fixed: 'left',
+              showOverflowTooltip: true
+            },
+            {
+              width: 100,
+              prop: 'batchNo',
+              label: '批次号',
+              slot: 'batchNo',
+              align: 'center'
+            },
+            {
+              minWidth: 140,
+              prop: 'name',
+              label: '名称',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'feedQuantity',
+              label: '数量',
+              slot: 'feedQuantity',
+              align: 'center'
+            },
+            {
+              width: 150,
+              prop: 'unit',
+              label: '单位',
+              slot: 'unit',
+              align: 'center'
+            },
+            {
+              prop: 'weight',
+              slot: 'weight',
+              label: '重量',
+              width: 120,
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'modelType',
+              label: '型号',
+              slot: 'modelType',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'specification',
+              label: '规格',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'brandNum',
+              label: '牌号',
+              slot: 'brandNum',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'supplierName',
+              label: '供应商',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'status',
+              label: '状态',
+              slot: 'status',
+              align: 'center',
+              showOverflowTooltip: true
+            }
+          ]
+        ];
       }
     },
 
     methods: {
       handleClose() {
         this.$emit('detailedClose');
+      },
+
+      outboundDetails(item, index) {
+        this.$refs.outboundDetailRef.open(item);
+      },
+
+      async getOutboundDetailList() {
+        await getOutboundDetail({
+          pickOrderId: this.dataObj.id
+        }).then((res) => {
+          this.outboundDetailList = res;
+        });
       }
     },
 
@@ -139,6 +341,7 @@
       console.log(obj, 'obj');
 
       this.dataObj = obj;
+      this.getOutboundDetailList();
     }
   };
 </script>
@@ -161,7 +364,7 @@
       width: calc(100% / 5);
       display: flex;
       align-items: center;
-      min-width: 200px;
+      // min-width: 200px;
       min-height: 32px;
       border-bottom: 1px solid #e3e5e5;
       border-right: 1px solid #e3e5e5;
@@ -174,7 +377,7 @@
         display: flex;
         align-items: center;
         padding: 4px;
-        width: 80px;
+        width: 60px;
         height: 100%;
         background-color: #d0e4d5;
         color: #000;
@@ -204,4 +407,13 @@
       margin: 0 4px;
     }
   }
+
+  .time {
+    color: #157a2c;
+    font-family: PingFang HK;
+    font-size: 14px;
+    font-style: normal;
+    font-weight: 500;
+    margin-left: 8px;
+  }
 </style>

+ 24 - 3
src/views/pick/pickApply/index.vue

@@ -33,6 +33,12 @@
           >
         </template>
 
+        <template v-slot:code="{ row }">
+          <el-link type="primary" :underline="false" @click="handDetailed(row)">
+            {{ row.code }}
+          </el-link>
+        </template>
+
         <template v-slot:joinWorkOrderCode="{ row }">
           <el-tag type="warning" v-if="row.type == 1">自建领料单</el-tag>
           <div v-else>{{ row.joinWorkOrderCode }}</div>
@@ -47,8 +53,11 @@
         </template>
 
         <template v-slot:action="{ row }">
-          <el-button type="text" size="mini" @click="handDetailed(row)"
+          <!-- <el-button type="text" size="mini" @click="handDetailed(row)"
             >详情</el-button
+          > -->
+          <el-button type="text" size="mini" @click="checkProcess(row)"
+            >流程</el-button
           >
         </template>
       </ele-pro-table>
@@ -68,6 +77,8 @@
       v-if="selfDetailedShow"
       :detailedObj="detailedObj"
     ></selfDetailed>
+
+    <flow ref="flowRef"></flow>
   </div>
 </template>
 
@@ -75,7 +86,7 @@
   import { getAllPage, returnPage, getPage } from '@/api/pick/pickApply';
 
   import pickSearch from './components/pick-search.vue';
-
+  import flow from './components/flow.vue';
   import addPick from './components/addPick.vue';
   import selfBuildPick from './components/selfBuildPick.vue';
 
@@ -88,7 +99,8 @@
       addPick,
       selfBuildPick,
       detailed,
-      selfDetailed
+      selfDetailed,
+      flow
     },
 
     props: {
@@ -129,6 +141,7 @@
           },
           {
             prop: 'code',
+            slot: 'code',
             label: '领料单编号',
             align: 'center',
             align: 'left'
@@ -255,6 +268,14 @@
         this.selfDetailedShow = false;
       },
 
+      //查看流程
+      checkProcess(row) {
+        if (!row.processInstanceId) {
+          return this.$message.warning('暂无流程图');
+        }
+        this.$refs.flowRef.open(row.processInstanceId);
+      },
+
       handleSelectionChange(data) {
         let ids = [];
         ids = data.map((item) => item.id);

+ 3 - 4
src/views/produce/components/feeding/components/outboundOrderDialog.vue

@@ -38,7 +38,7 @@
 </template>
 
 <script>
-  import { feedOutInOrder } from '@/api/produce/feeding';
+  import { getOutboundDetail } from '@/api/produce/picking.js';
   export default {
     data() {
       return {
@@ -160,11 +160,10 @@
       },
 
       async datasource({ page, limit, where }) {
-        const res = await feedOutInOrder({
+        const res = await getOutboundDetail({
           workOrderId: this.workOrderId,
-          taskId: this.taskId,
           pageNum: page,
-          size: limit
+          size: -1
         });
         return res;
       },

+ 12 - 0
src/views/produce/components/picking/detailed.vue

@@ -115,6 +115,10 @@
             <el-tag>已出库</el-tag>
           </template>
 
+          <template v-slot:weight="{ row, $index }">
+            <span>{{ row.weight || 0 }}{{ row.weightUnit }}</span>
+          </template>
+
           <!-- <template v-slot:action="{ row, $index }">
             <el-link
               type="text"
@@ -304,6 +308,14 @@
               slot: 'unit',
               align: 'center'
             },
+            {
+              prop: 'weight',
+              slot: 'weight',
+              label: '重量',
+              width: 120,
+              align: 'center',
+              showOverflowTooltip: true
+            },
             {
               width: 150,
               prop: 'modelType',

+ 2 - 2
vue.config.js

@@ -37,7 +37,7 @@ module.exports = {
 
         // target: 'http://192.168.1.116:18086',
         // target: 'http://192.168.1.251:18086',
-        // target: 'http://192.168.1.125:18086',
+        target: 'http://192.168.1.125:18086',
 
         // target: 'http://192.168.1.116:18086', // 赵沙金
 
@@ -48,7 +48,7 @@ module.exports = {
         // target: 'http://192.168.1.33:18086',
         // target: 'http://192.168.1.251:18186',
         // target: 'http://192.168.1.251:18087',
-        target: 'http://124.71.21.222:80/api',
+        // target: 'http://124.71.21.222:80/api',
         changeOrigin: true, // 只有这个值为true的情况下 才表示开启跨域
         pathRewrite: {
           '^/api': ''