【vue2+minix】vue项目中通过样式和逻辑的混入实现接入工作流

流程思维导图

仅示例申请信息tab页接入工作流流程,其他tab同理
在这里插入图片描述

vue页面里的操作

在页面中引入需要混入的minix.js文件:

import exForm from '@/views/plugin/workflow/mixins/ex-form';

注册混入文件:

mixins: [exForm],

通过操作按钮打开要接入工作流的页面:

 <el-tooltip content="审批" placement="bottom-start" v-if="row.isAudit === 1">
   <el-button
      spang-crud-operate
      class="el-tooltip operation-btn el-button--text el-button--small iconfont-menu icon-a-shenpi22x"
      @click="goApprovalFlowPage(row)">
    </el-button>
  </el-tooltip>

前往审批页:

 // 前往审批流页面
    goApprovalFlowPage(row) {
      const { auditId } = row;
      if (!auditId) {
        this.$message.warning('数据异常');
        return false;
      }
      this.dynamicRoute(
        {
          ...row,
          processInstanceId: auditId,
          processId: row.id,
          formKey: 'CorrectiveMaintenanceApproval',
          formUrl: '',
        },
        'approval'
      );
    },

在该页面中,用了混入的minix.js里的dynamicRoute方法,作用是接收参数并实现页面跳转

混入minix.js文件

 // 动态路由跳转
    dynamicRoute(row, type, async = false) {
      const { id, taskId, processInstanceId, formKey, formUrl, isEdit } = row;
      let param = Buffer.from(
        JSON.stringify({
          processId: id, //业务数据id
          taskId,
          processInsId: processInstanceId || '',
          isEdit,
        })
      ).toString('base64');

      if (formKey) {
        if (formUrl) {
          // 配置了自定义路由
          this.$router.push(formUrl + `?p=${param}`);
        } else {
          // 动态添加路由
          this.$router.push(`/workflow/process/external/${formKey}/${type}?p=${param}`);
        }
      } else {
        if (async) {
          return new Promise(resolve => {
            resolve({ row, type, param });
          });
        } else {
          this.$router.push(`/workflow/process/${type}/${param}`);
        }
      }
    },

formKey和processInstanceId是必传参数,通过dynamicRoute进行动态路由跳转,跳转页面:

this.$router.push(`/workflow/process/external/${formKey}/${type}?p=${param}`);

页面路由信息:

 {
    path: `/workflow/process/external`,
    component: Layout,
    children: [
      {
        path: `:formKey/:type`,
        name: '流程详情',
        component: () =>
          import(
            /* webpackChunkName: "views" */ `@/views/plugin/workflow/process/external/common/detail.vue`
            ),
      },
    ],
  },

跳转到external目录下的common目录里的detail.vue文件
在这里插入图片描述

页面和逻辑混入实现

申请信息

进入external模块,入口页面是common/detail.vue,detail.vue页面结构如下:
在这里插入图片描述
三个el-tab对应工作流的三个tab切换,分别是申请信息、流转信息、流程跟踪;底部是操作按钮区,常用的是通过、驳回、返回三个按钮,效果如下:
在这里插入图片描述
其中,申请信息tab为页面开发好的审批/查看页面,通过组件引入,如下:

	<el-tab-pane label="申请信息" name="first">
	 <!--自定义表单区域-->
	  <div id="printBody" :class="formType == 'approval' ? 'todoHeight' : 'height'">
	    <component
	      :is="component"
	      :processId="processId"
	      :formData="form"
	      :disabled="true"
	      :showFooter="true"></component>
	  </div>
	
	  <!--审批意见区域-->
	  <el-card class="approvalCard" v-if="formType == 'approval'">
	    <!-- 缺陷审批意见 -->
	    <corrective-maintenaceorm-form
	      :form="form"
	      v-if="formName === 'CorrectiveMaintenanceApproval' && formType === 'approval'"
	      ref="correctiveMaintenaceFormRef" />
	    <wf-examine-form
	      ref="examineForm"
	      :comment.sync="comment"
	      :process="process"
	      @user-select="handleUserSelect"></wf-examine-form>
	  </el-card>
	</el-tab-pane>

在created中通过loader计算属性初始化component组件

 created() {
    const {
      params: { formKey, type },
      query: { p },
    } = this.$route;
    const resolveP = JSON.parse(Buffer.from(p, 'base64').toString());
    const { processId, isEdit } = resolveP;
    this.isEdit = isEdit;
    if (formKey) {
      this.processId = isEdit && processId;
      this.formName = formKey;
      this.formType = type;
      this.waiting = false;
      this.component = this.loader();//初始化组件
    }
  },
computed: {
    loader() {
      const componentPath = dynamicPaths[this.formName].flowPath[this.formType];
      return () => resolve => require(['@/views' + componentPath], resolve);
    },
  },

dynamicPaths 是引入的对接工作流的页面的formKey和路径的对应关系,formName是路由传入的formKey,formType也是路由传入的工作流页面类型:审批页/查看页,通过这两个字段查询到dynamicPaths中的页面路径,完成导入该页面和初始化component

// 引入流程表单组件
import { dynamicPaths } from './index.js';
// formKey 到组件的映射
export const dynamicPaths = {
  // 缺陷管理审批
  CorrectiveMaintenanceApproval: {
    // 审批流界面
    flowPath: {
      approval: '/health-management/corrective-maintenance/corrective-maintenance/approval.vue',
      details: '/health-management/corrective-maintenance/corrective-maintenance/details.vue',
    },
    // 返回界面
    goBackPath: {
      defaultPath: '/health-management/corrective-maintenance/corrective-maintenance/list',
    },
  },
};

以上,便可实现通过在当前页面引入混入,实现将当前页面内容作为组件插入到工作流的申请信息tab页

审批意见

   <!--审批意见区域-->
   <el-card class="approvalCard" v-if="formType == 'approval'">
    <!-- 缺陷审批意见 -->
     <corrective-maintenaceorm-form
       :form="form"
       v-if="formName === 'CorrectiveMaintenanceApproval' && formType === 'approval'"
       ref="correctiveMaintenaceFormRef" />
     <wf-examine-form
       ref="examineForm"
       :comment.sync="comment"
       :process="process"
       @user-select="handleUserSelect"></wf-examine-form>
   </el-card>

引入组件

import WfExamineForm from '@/views/plugin/workflow/process/components/examForm.vue';

传入的:process="process"是混入的exForm中的响应字段

import exForm from '@/views/plugin/workflow/mixins/ex-form';
  mixins: [exForm, theme],

在exForm.js里,调接口获取工作流详情信息,将接口返回的process 保存到data里,在混入exForm的页面detail.vue中给审批意见区组件wf-examine-form传入process

  /**
     * 获取流程任务详情
     * @param taskId 任务id
     * @param processInsId 流程实例id
     * @returns Promise({"process": "流程实例信息", "form": "表单信息", "flow": "流转信息", "button": "配置按钮信息", "bpmnOption": "流程图配置"})
     */
    getTaskDetail(taskId, processInsId) {
      return new Promise((resolve, reject) => {
        detail({ taskId, processInsId })
          .then(res => {
            const { process, form, flow, button, hisVariable } = res.data.data;
            const { xml } = process;

            const bpmnOption = {
              mode: 'view',
              xml,
              flows: this.handleResolveFlows(flow),
            };
            this.process = process;
            this.flow = flow;
            this.buttonList = button;
            this.bpmnOption = bpmnOption;
            // this.tag.label = '流程详情 - ' + process.processDefinitionName;
            this.tag.label = process.processDefinitionName || '详情';
            resolve({ process, form, flow, button, bpmnOption, hisVariable });
          })
          .catch(() => {
            reject();
          });
      });
    },

审批意见区组件——examForm.vue:
通props获取展示审批字段:

 props: {
    process: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },

在watch中监听:

 watch: {
    process: {
      handler(val) {
        if (!val) return;
        const { hideComment, hideAttachment, hideCopy, hideExamine, copyUser, copyUserName } = val;      
        if (hideComment) this.findObject(this.examineOption.column, 'comment').display = false; // 隐藏评论
        if (hideComment || hideAttachment) this.findObject(this.examineOption.column, 'attachment').display = false; // 隐藏评论附件
        if (hideCopy) this.findObject(this.examineOption.column, '$copyUser').display = false; // 隐藏抄送人
        if (hideExamine) this.findObject(this.examineOption.column, '$assignee').display = false; // 隐藏指定下一步审核人
        if (copyUser) this.$set(this.examineForm, 'copyUser', val.copyUser); // 默认抄送人
        if (copyUserName) this.$set(this.examineForm, '$copyUser', val.copyUserName); // 默认抄送人
      },
      deep: true,
      immediate: true,
    },
  },

根据exForm.js里接口返回的审批意见展示结果,操作column的display字段,展示和隐藏审批意见字段

在这里插入图片描述

  {
	   label: '批复意见',
	   prop: 'comment',
	   type: 'textarea',
	   maxlength: '100',
	   placeholder: '请输入批复意见,最多100字',
	   span: 24,
	   event: {
	     change: val => {
	       this.$emit('update:comment', val);
	     },
	   },
	   display: true,
 },

提交时,在exForm.js里通过ref获取审批意见组件的必填项字段,提交前进行校验

 /**
     * 任务审核
     * @param pass 驳回/通过
     */
    handleCompleteTask(pass, variables, processVariables) {
      return new Promise((resolve, reject) => {
        const { comment, copyUser, assignee, attachment } = this.$refs.examineForm.examineForm;
        if (!pass && !comment) {
          // this.$message.error('请在"申请信息"下填写批复意见');
          this.$message.error('请填写批复意见');
          this.submitLoading = false;
          reject();
          return;
        }
        const { taskId, processInstanceId, processDefinitionName, processDefinitionId } = this.process;
        const param = {
          taskId,
          processInstanceId,
          processDefinitionName,
          processDefinitionId,
          pass,
          comment,
          copyUser,
          assignee,
          variables,
          attachment,
          processVariables,
        };
        completeTask(param)
          .then(() => {
            resolve();
          })
          .catch(() => {
            reject();
          });
      });
    },

底部按钮

和审批意见区类似,底部按钮区是导入组件:

  <!-- 底部按钮 -->
    <wf-button
      :loading="submitLoading"
      :button-list="buttonList"
      :process="process"
      :formType="formType"
      :comment="comment"
      @examine="handleExamine"
      @user-select="handleUserSelect"
      @print="handlePrint"
      @rollback="handleRollbackTask"
      @terminate="handleTerminateProcess"
      @refuse="handleRefuse"
      @goDealt="handleGodealt"></wf-button>
import WfButton from '@/views/plugin/workflow/process/components/button.vue';

button.vue结构如下:

   <template>
      <el-button
        v-if="formType === 'approval' && buttonList.find(b => b.buttonKey == 'wf_pass')"
        type="success"
        :size="$widgetSize"
        :loading="loading"
        @click="$emit('examine', true)">
        通过
      </el-button>         
      <el-button
        v-if="formType === 'approval' && buttonList.find(b => b.buttonKey == 'wf_refuse')"
        type="danger"
        :size="$widgetSize"
        :loading="loading"
        @click="$emit('refuse', false)">
        驳回
      </el-button>     
    </template>
    <el-button plain :size="$widgetSize" :loading="loading" @click="$emit('goDealt')">返回</el-button>

examine和refuse是从detail传入组件的自定义事件,处理审批和驳回操作:

 @examine="handleExamine"
 @refuse="handleRefuse"

handleExamine和handleRefuse方法进行一些接口前处理,比如获取参数和必填字段校验,然后调用混入的exForm.js里的handleCompleteTask和handleRefuse方法调接口传给后端

实现效果

在这里插入图片描述

申请信息tab页由详情信息、审批意见、审批按钮三部分组成

  • 详情信息:工作流详情页混入业务详情页
  • 审批意见:工作流审批意见区组件
  • 审批按钮:工作流审批按钮区组件

审批通过时,批复意见不是必填项,该工作流直接通过;审批驳回时,批复意见是必填项,会校验必填项,需要输入批复意见后才能成功驳回

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值