Procházet zdrojové kódy

我的已办查看业务信息

yusheng před 1 rokem
rodič
revize
0b3b033ecf

+ 102 - 0
src/views/bpm/done/detailDialog.vue

@@ -0,0 +1,102 @@
+<template>
+  <ele-modal
+    custom-class="ele-dialog-form long-dialog-form"
+    :centered="true"
+    :visible.sync="visible"
+    title="详情"
+    :append-to-body="true"
+    :close-on-click-modal="false"
+    :maxable="true"
+    :resizable="true"
+    width="70%"
+  >
+    <div class="switch">
+      <div class="switch_left">
+        <ul>
+          <li
+            v-for="item in tabOptions"
+            :key="item.key"
+            :class="{ active: activeComp == item.key }"
+            @click="activeComp = item.key"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+      </div>
+    </div>
+    <div v-show="activeComp === 'main'">
+      <async-biz-form-component
+        :businessId="form?.businessId"
+        ref="bziRef"
+      ></async-biz-form-component>
+    </div>
+
+    <bpmDetail
+      v-if="activeComp === 'bpm' && form.processInstance.id"
+      :id="form.processInstance.id"
+    ></bpmDetail>
+
+    <div slot="footer" class="footer">
+      <el-button @click="visible=false">返回</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import bpmDetail from '@/views/bpm/processInstance/detailNew.vue';
+  import Vue from 'vue';
+
+  export default {
+    components: {
+      bpmDetail
+    },
+    data() {
+      return {
+        activeComp: 'main',
+        form: {
+          processInstance: {}
+        },
+        tabOptions: [
+          { key: 'main', name: '业务详情' },
+          { key: 'bpm', name: '流程详情' }
+        ],
+        visible: false
+      };
+    },
+    methods: {
+      async open(row) {
+        this.form = row;
+        this.activeComp='main'
+        this.visible = true;
+        Vue.component('async-biz-form-component', (resolve) => {
+          require([`@/views${this.form.pcViewRouter}`], resolve);
+        });
+      },
+
+      cancel() {
+        this.$nextTick(() => {
+          this.form = {};
+          this.visible = false;
+        });
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss">
+  .ele-dialog-form {
+    .el-form-item {
+      margin-bottom: 10px;
+    }
+  }
+
+  .headbox {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .amount {
+      font-size: 14px;
+      font-weight: bold;
+    }
+  }
+</style>

+ 2 - 2
src/views/bpm/done/index.vue

@@ -105,7 +105,7 @@
   import dictMixins from '@/mixins/dictMixins';
   import { getDoneTaskPage } from '@/api/bpm/task';
   import {getDate} from "@/utils/dateUtils";
-  import detail from '@/views/bpm/processInstance/detail.vue';
+  import detail from './detailDialog.vue';
 
   // 默认表单数据
   const defaultParams = {
@@ -247,7 +247,7 @@
       },
       /** 处理审批按钮 */
       handleAudit(row) {
-        this.$refs.detailRef.open(row.processInstance.id);
+        this.$refs.detailRef.open(row);
       },
       getTimelineItemType(result) {
       if (result === '通过') {

+ 1 - 6
src/views/bpm/handleTask/components/saleOrder/addDialog.vue

@@ -54,12 +54,7 @@
           </el-form-item>
           <el-form-item prop="orderFiles" label="订单附件">
             <fileMain v-model="form.orderFiles"></fileMain>
-<!--            <fileUpload-->
-<!--              v-model="form.orderFiles"-->
-<!--              module="main"-->
-<!--              :showLib="false"-->
-<!--              :limit="10"-->
-<!--            />-->
+
           </el-form-item>
         </el-col>
         <el-col :span="12">

+ 293 - 0
src/views/bpm/processInstance/detailNew.vue

@@ -0,0 +1,293 @@
+<template>
+  <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"
+                >
+                  {{ index == 0 ? ' 审批人' : '发起人' }}:{{
+                    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>
+                <label
+                  v-if="item.result != 1"
+                  style="margin-left: 30px; color: #8a909c; font-weight: normal"
+                >
+                  签名:
+                </label>
+                <label v-if="item.result != 1">
+                  <el-image
+                    style="
+                      width: 50px;
+                      height: 50px;
+                      position: absolute;
+                      transform: translate(0px, 0px);
+                    "
+                    :src="item?.assigneeUser?.signature[0]?.url"
+                  >
+                    <div slot="error" class="image-slot">
+                      <!--                        <i class="el-icon-picture-outline"></i>-->
+                      <span></span>
+                    </div>
+                  </el-image>
+                </label>
+
+                <p v-if="item.reason && item.result != 4">
+                  <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>
+</template>
+
+<script>
+  import { getProcessDefinitionBpmnXML } from '@/api/bpm/definition';
+  import store from '@/store';
+  import { getProcessInstance } from '@/api/bpm/processInstance';
+  import { getDate } from '@/utils/dateUtils';
+  import dictMixins from '@/mixins/dictMixins';
+  import { getTaskListByProcessInstanceId } from '@/api/bpm/task';
+  import { getActivityList } from '@/api/bpm/activity';
+
+  // import Vue from 'vue';
+
+  // 流程实例的详情页,可用于审批
+  export default {
+    name: 'ProcessInstanceDetail',
+    mixins: [dictMixins],
+    props: {
+      id: {
+        default: ''
+      }
+    },
+    components: {},
+    data() {
+      return {
+        // 遮罩层
+        processInstanceLoading: true,
+        dialogVisible: false,
+
+        // 流程实例
+        // id: undefined, // 流程实例的编号
+        processInstance: {},
+
+        // BPMN 数据
+        bpmnXML: null,
+        bpmnControlForm: {
+          prefix: 'flowable'
+        },
+        activityList: [],
+
+        // 审批记录
+        tasksLoad: true,
+        tasks: []
+      };
+    },
+    created() {
+      this.getDetail();
+    },
+    methods: {
+      /** 获得流程实例 */
+      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) => {
+            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>