فهرست منبع

新增计划流程审批

695593266@qq.com 8 ماه پیش
والد
کامیت
0249d14814

+ 21 - 6
src/api/productionPlan/order.js

@@ -3,7 +3,7 @@ import request from '@/utils/request';
 /**
  * 工单发布
  */
-export async function release (data) {
+export async function release(data) {
   const res = await request.post('/aps/workorder/release', data);
   if (res.data.code == 0) {
     return res.data.data;
@@ -11,11 +11,24 @@ export async function release (data) {
   return Promise.reject(new Error(res.data.message));
 }
 
+/**
+ * 工单审核发布
+ */
+export async function releaseByApproval(data) {
+  const res = await request.post('/aps/workorder/releaseByApproval', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
 /**
  * 工单发布
  */
-export async function getDeviceList ({ productionId }) {
-  const res = await request.get(`/aps/batchingworkorder/getDeviceList/${productionId}`);
+export async function getDeviceList({ productionId }) {
+  const res = await request.get(
+    `/aps/batchingworkorder/getDeviceList/${productionId}`
+  );
   if (res.data.code == 0) {
     return res.data.data;
   }
@@ -23,10 +36,12 @@ export async function getDeviceList ({ productionId }) {
 }
 
 // 生产计划添加工单列表
-export async function getPlanDeviceList ({ produceVersionId }) {
-  const res = await request.get(`/aps/workorder/getDeviceList/${produceVersionId}`);
+export async function getPlanDeviceList({ produceVersionId }) {
+  const res = await request.get(
+    `/aps/workorder/getDeviceList/${produceVersionId}`
+  );
   if (res.data.code == 0) {
     return res.data.data;
   }
   return Promise.reject(new Error(res.data.message));
-}
+}

+ 282 - 0
src/views/productionPlan/components/detail/processDetail.vue

@@ -0,0 +1,282 @@
+<template>
+  <el-dialog
+    title="详情"
+    :before-close="handleClose"
+    :visible.sync="dialogVisible"
+    :close-on-click-modal="true"
+    :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">流程图</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: 'ProcessInstanceDetail',
+    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>

+ 39 - 8
src/views/productionPlan/index.vue

@@ -301,6 +301,15 @@
           >
             拆批
           </el-link>
+
+          <el-link
+            type="primary"
+            :underline="false"
+            @click="process(row)"
+            v-if="row.processInstanceId"
+          >
+            流程
+          </el-link>
         </template>
       </ele-pro-table>
     </el-card>
@@ -338,6 +347,8 @@
       fileName="生产临时计划模板"
       apiUrl="/aps/productionplan/importFile"
     />
+
+    <processDetail ref="processDetailRef" />
   </div>
 </template>
 
@@ -358,13 +369,14 @@
   import unpackDetails from './components/unpackDetails.vue';
   import disassemblePlanPop from './components/disassemblePlanPop.vue';
   import factoryAdd from './components/factoryAdd/index.vue';
-  import { release } from '@/api/productionPlan/order.js';
+  import { release, releaseByApproval } from '@/api/productionPlan/order.js';
   import { getCode } from '@/api/codeManagement';
   import { fieldModel } from '@/api/saleOrder';
   import { debounce } from 'lodash';
   import tabMixins from '@/mixins/tableColumnsMixin';
   import importDialog from '@/components/upload/import-dialog.vue';
   import { parameterGetByCode } from '@/api/mainData/index';
+  import processDetail from './components/detail/processDetail.vue';
 
   import {
     findBomCategoryByCategoryId,
@@ -381,7 +393,8 @@
       factoryAdd,
       homogeneityInspectDialog,
       homogeneityInspectInstallDialog,
-      importDialog
+      importDialog,
+      processDetail
     },
     props: {
       timeDimensionPlanType: { type: Number, default: 1 },
@@ -653,14 +666,14 @@
             label: '机型',
             align: 'center',
             minWidth: 120,
-            showOverflowTooltip: true,
+            showOverflowTooltip: true
           },
           {
             prop: 'colorKey',
             label: '颜色',
             align: 'center',
             minWidth: 120,
-            showOverflowTooltip: true,
+            showOverflowTooltip: true
           },
           {
             prop: 'productNum',
@@ -969,12 +982,20 @@
           return this.$message.error('请先选择工艺路线!');
         }
 
-        this.$confirm('发布工单后不可撤回,确定发布吗?', '发布确认')
+        const titleText = this.isReview
+          ? '是否发起流程'
+          : '发布工单后不可撤回,确定发布吗?';
+
+        const title = this.isReview ? '流程确认' : '发布确认';
+
+        const text = this.isReview ? '流程发布中...' : '工单发布中...';
+
+        this.$confirm(titleText, title)
           .then(async () => {
             const loading = this.$loading({
               lock: true,
               fullscreen: true,
-              text: '工单发布中...'
+              text
             });
             try {
               let code = row.workOrderCode;
@@ -982,7 +1003,9 @@
                 code = await getCode('product_order_code');
               }
               // 反显对象会报错 status
-              const data = await release([row.id]);
+              const URL = this.isReview ? releaseByApproval : release;
+
+              const data = await URL([row.id]);
               if (data || data === 0) {
                 this.$message.success('发布成功!');
               } else {
@@ -1078,7 +1101,7 @@
             privateColumn.push({
               columnKey: 'action',
               label: '操作',
-              width: 200,
+              width: 240,
               align: 'center',
               resizable: false,
               fixed: 'right',
@@ -1166,6 +1189,14 @@
         }
       },
 
+      process(row) {
+        if (row.approvalStatus == 0) {
+          this.$message.info('未提交没有审核流程');
+        } else {
+          this.$refs.processDetailRef.open(row.processInstanceId);
+        }
+      },
+
       handOneSelection(row) {
         const index = this.selection.findIndex((item) => item.id == row.id);
         if (index >= 0) {

+ 67 - 47
src/views/saleOrder/salesToProductionNew.vue

@@ -949,45 +949,65 @@
         }
 
         if (type === 2) {
-          this.$confirm('发布工单后不可撤回,确定发布吗?', '发布确认').then(
-            async () => {
-              const loading = this.$loading({
-                lock: true,
-                fullscreen: true,
-                text: '工单发布中...'
-              });
-              try {
-                const code = await getCode('product_order_code');
-                const data = {
-                  productionPlan: params,
-                  workOrder: {
-                    productionPlanCode: params.code,
-                    code: code,
-                    // formingNum: params.contractNum,
-                    formingNum: this.form.requiredFormingNum,
-                    formingWeight: params.sumOrderWeight,
-                    produceRoutingId: params.produceRoutingId,
-                    status: 4,
-                    model: params.model,
-                    brandNo: params.brandNo,
-                    categoryId: params.categoryId,
-                    productCode: params.productCode,
-                    productName: params.productName,
-
-                    newWeightUnit: this.form.newWeightUnit,
-                    newSumOrderWeight: this.form.newSumOrderWeight
-                  }
-                };
-                if (this.$route.query.type == 'edit') {
-                  data.workOrder.productionPlanId = params.id;
+          const titleText = this.isReview
+            ? '是否发起流程'
+            : '发布工单后不可撤回,确定发布吗?';
+
+          const title = this.isReview ? '流程确认' : '发布确认';
+
+          const text = this.isReview ? '流程发布中...' : '工单发布中...';
+
+          this.$confirm(titleText, title).then(async () => {
+            const loading = this.$loading({
+              lock: true,
+              fullscreen: true,
+              text
+            });
+            try {
+              const code = await getCode('product_order_code');
+              const data = {
+                productionPlan: params,
+                workOrder: {
+                  productionPlanCode: params.code,
+                  code: code,
+                  // formingNum: params.contractNum,
+                  formingNum: this.form.requiredFormingNum,
+                  formingWeight: params.sumOrderWeight,
+                  produceRoutingId: params.produceRoutingId,
+                  status: 4,
+                  model: params.model,
+                  brandNo: params.brandNo,
+                  categoryId: params.categoryId,
+                  productCode: params.productCode,
+                  productName: params.productName,
+
+                  newWeightUnit: this.form.newWeightUnit,
+                  newSumOrderWeight: this.form.newSumOrderWeight
                 }
-                console.log(data);
-                const URL = this.isReview ? planIsReview : releaseSave;
-                await URL(data)
-                  // await releaseSave(data)
-                  .then((res) => {
-                    if (res === 1) {
+              };
+              if (this.$route.query.type == 'edit') {
+                data.workOrder.productionPlanId = params.id;
+              }
+              console.log(data);
+              const URL = this.isReview ? planIsReview : releaseSave;
+              await URL(data)
+                // await releaseSave(data)
+                .then((res) => {
+                  if (res === 1) {
+                    if (this.isReview) {
+                      this.$message.success('流程已发布!');
+                      this.$router.push({
+                        path: '/productionPlan'
+                      });
+                    } else {
                       this.$message.success('工单已发布!');
+                      this.$router.push({
+                        path: '/workOrder'
+                      });
+                    }
+                  } else {
+                    if (this.isReview) {
+                      this.$message.success('流程已发布!');
                       this.$router.push({
                         path: '/productionPlan'
                       });
@@ -1010,16 +1030,16 @@
                           this.$router.go(-1);
                         });
                     }
-                    removePageTab({ key });
-                  })
-                  .catch(() => {
-                    this.$message.error('发布失败,请重新发布!');
-                  });
-              } catch (error) {}
-
-              loading.close();
-            }
-          );
+                  }
+                  removePageTab({ key });
+                })
+                .catch(() => {
+                  this.$message.error('发布失败,请重新发布!');
+                });
+            } catch (error) {}
+
+            loading.close();
+          });
         } else {
           let request =
             this.$route.query.type == 'edit'

+ 82 - 47
src/views/saleOrder/salesToProductionNewTwo.vue

@@ -838,7 +838,10 @@
     getFactoryList,
     getInventoryTotalAPI
   } from '@/api/saleOrder';
-  import { findBomCategoryByCategoryId } from '@/api/productionPlan/index';
+  import {
+    findBomCategoryByCategoryId,
+    planIsReview
+  } from '@/api/productionPlan/index';
   import { getByCode } from '@/api/system/dictionary-data';
   import { parameterGetByCode } from '@/api/mainData/index';
   import dictMixins from '@/mixins/dictMixins';
@@ -928,7 +931,8 @@
         selectionRowShow: false, // 工艺路线输入框展示 状态
         validDate,
         modelList: [], // 机型数据
-        colorList: [] // 颜色数据
+        colorList: [], // 颜色数据
+        isReview: false
       };
     },
     props: {
@@ -973,6 +977,7 @@
     mounted() {
       this.mandatoryField();
       this.getCodeData();
+      this.getplannedReleaseRequire('planned_release_require');
     },
     computed: {
       clientEnvironmentId() {
@@ -1035,6 +1040,14 @@
           this.$message.error(err.message);
         }
       },
+
+      async getplannedReleaseRequire(code) {
+        parameterGetByCode({ code }).then((res) => {
+          if (res) {
+            this.isReview = res.value == '1' ? true : false;
+          }
+        });
+      },
       async getProducedData() {
         console.log(111111111111111);
         let query = { ...this.$route.query };
@@ -1722,42 +1735,64 @@
         });
 
         if (type === 2) {
-          this.$confirm('发布工单后不可撤回,确定发布吗?', '发布确认').then(
-            async () => {
-              const loading = this.$loading({
-                lock: true,
-                fullscreen: true,
-                text: '工单发布中...'
-              });
-              try {
-                const code = await getCode('product_order_code');
-                const data = {
-                  productionPlan: params,
-                  workOrder: {
-                    productionPlanCode: params.code,
-                    code: code,
-                    // formingNum: params.contractNum,
-                    formingNum: this.form.requiredFormingNum,
-                    formingWeight: params.sumOrderWeight,
-                    produceRoutingId: params.produceRoutingId,
-                    status: 4,
-                    model: params.model,
-                    brandNo: params.brandNo,
-                    categoryId: params.categoryId,
-                    productCode: params.productCode,
-                    productName: params.productName,
-
-                    newWeightUnit: this.form.newWeightUnit,
-                    newSumOrderWeight: this.form.newSumOrderWeight
-                  }
-                };
-                if (this.$route.query.type == 'edit') {
-                  data.workOrder.productionPlanId = params.id;
+          const titleText = this.isReview
+            ? '是否发起流程'
+            : '发布工单后不可撤回,确定发布吗?';
+
+          const title = this.isReview ? '流程确认' : '发布确认';
+
+          const text = this.isReview ? '流程发布中...' : '工单发布中...';
+
+          this.$confirm(titleText, title).then(async () => {
+            const loading = this.$loading({
+              lock: true,
+              fullscreen: true,
+              text
+            });
+            try {
+              const code = await getCode('product_order_code');
+              const data = {
+                productionPlan: params,
+                workOrder: {
+                  productionPlanCode: params.code,
+                  code: code,
+                  // formingNum: params.contractNum,
+                  formingNum: this.form.requiredFormingNum,
+                  formingWeight: params.sumOrderWeight,
+                  produceRoutingId: params.produceRoutingId,
+                  status: 4,
+                  model: params.model,
+                  brandNo: params.brandNo,
+                  categoryId: params.categoryId,
+                  productCode: params.productCode,
+                  productName: params.productName,
+
+                  newWeightUnit: this.form.newWeightUnit,
+                  newSumOrderWeight: this.form.newSumOrderWeight
                 }
-                await releaseSave(data)
-                  .then((res) => {
-                    if (res === 1) {
+              };
+              if (this.$route.query.type == 'edit') {
+                data.workOrder.productionPlanId = params.id;
+              }
+              const URL = this.isReview ? planIsReview : releaseSave;
+              await URL(data)
+                // await releaseSave(data)
+                .then((res) => {
+                  if (res === 1) {
+                    if (this.isReview) {
+                      this.$message.success('流程已发布!');
+                      this.$router.push({
+                        path: '/productionPlan'
+                      });
+                    } else {
                       this.$message.success('工单已发布!');
+                      this.$router.push({
+                        path: '/workOrder'
+                      });
+                    }
+                  } else {
+                    if (this.isReview) {
+                      this.$message.success('流程已发布!');
                       this.$router.push({
                         path: '/productionPlan'
                       });
@@ -1780,18 +1815,18 @@
                           this.$router.go(-1);
                         });
                     }
-                    removePageTab({ key });
-                  })
-                  .catch(() => {
-                    this.$message.error('发布失败,请重新发布!');
-                  });
-              } catch (error) {
-                this.$message.error(error.message || '发布失败,请重新发布!');
-              }
-
-              loading.close();
+                  }
+                  removePageTab({ key });
+                })
+                .catch(() => {
+                  this.$message.error('发布失败,请重新发布!');
+                });
+            } catch (error) {
+              this.$message.error(error.message || '发布失败,请重新发布!');
             }
-          );
+
+            loading.close();
+          });
         } else {
           let request =
             this.$route.query.type == 'edit'