大件运输联网系统前端代码
guoshilong
2022-12-16 1e376296b2d8abbcdd051b1e75d860353c8bb19d
添加审核工作流
9 files modified
6 files added
1214 ■■■■ changed files
src/api/application/application.js 39 ●●●●● patch | view | raw | blame | history
src/api/reject/reject.js 50 ●●●●● patch | view | raw | blame | history
src/const/application/application.js 93 ●●●● patch | view | raw | blame | history
src/const/enterprise/enterprise.js 15 ●●●●● patch | view | raw | blame | history
src/lang/zh.js 2 ●●● patch | view | raw | blame | history
src/page/login/index.vue 38 ●●●● patch | view | raw | blame | history
src/router/views/index.js 38 ●●●●● patch | view | raw | blame | history
src/util/formValidator.js 19 ●●●●● patch | view | raw | blame | history
src/views/application/application.vue 39 ●●●● patch | view | raw | blame | history
src/views/application/reject.vue 81 ●●●●● patch | view | raw | blame | history
src/views/enterprise/enterprise.vue 47 ●●●●● patch | view | raw | blame | history
src/views/work/process/audit/detail.vue 154 ●●●●● patch | view | raw | blame | history
src/views/work/process/audit/form.vue 80 ●●●●● patch | view | raw | blame | history
src/views/work/process/audit/handle.vue 331 ●●●●● patch | view | raw | blame | history
src/views/work/process/leave/form.vue 188 ●●●● patch | view | raw | blame | history
src/api/application/application.js
@@ -60,3 +60,42 @@
  })
}
// =====================请假流程===========================
/*
 *开始流程
 */
export const applicationProcess = (row) => {
  return request({
    url: '/api/application/application/start-process',
    method: 'post',
    data: row
  })
}
/**
 * 获取申请流程详情
 * @param businessId
 * @returns {AxiosPromise}
 */
export const applicationDetail = (businessId) => {
  return request({
    url: '/api/application/application/process-detail',
    method: 'get',
    params: {
      businessId
    }
  })
}
/**
 * 完成任务
 * @param data
 * @returns {AxiosPromise}
 */
export const completeTask = (data) => {
  return request({
    url: '/api/application/application/complete-task',
    method: 'post',
    data
  })
}
src/api/reject/reject.js
New file
@@ -0,0 +1,50 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
  return request({
    url: '/api/reject/reject/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    }
  })
}
export const getDetail = (id) => {
  return request({
    url: '/api/reject/reject/detail',
    method: 'get',
    params: {
      id
    }
  })
}
export const remove = (ids) => {
  return request({
    url: '/api/reject/reject/remove',
    method: 'post',
    params: {
      ids,
    }
  })
}
export const add = (row) => {
  return request({
    url: '/api/reject/reject/save',
    method: 'post',
    data: row
  })
}
export const update = (row) => {
  return request({
    url: '/api/reject/reject/submit',
    method: 'post',
    data: row
  })
}
src/const/application/application.js
@@ -1,3 +1,5 @@
import {idCardValidate, mobileValidate} from "@/util/formValidator";
const uploadUrl = '/api/blade-resource/oss/endpoint/put-file-attach'
const propsHttp = {
  url:'link',
@@ -6,6 +8,7 @@
const labelWidth = '25%'
const urlLabelWidth='17%'
export default {
  tabs:true,
  height: 'auto',
  calcHeight: 30,
  tip: false,
@@ -29,13 +32,15 @@
          label: "经办人姓名",
          prop: "name",
          type: "input",
          labelWidth:labelWidth
          labelWidth:labelWidth,
          rules: [{required: true, message: "请输入经办人姓名", trigger: ['blur','change']}]
        },
        {
          label: "经办人身份证号",
          prop: "idCard",
          type: "input",
          labelWidth:labelWidth
          labelWidth:labelWidth,
          rules: [{required: true, trigger: ['blur','change'],validator:idCardValidate}]
        },
        {
          label: "手机号",
@@ -43,7 +48,8 @@
          type: "input",
          span:12,
          row:true,
          labelWidth:labelWidth
          labelWidth:labelWidth,
          rules: [{required: true, trigger: ['blur','change'],validator:mobileValidate}]
        },
        {
          label: "通行开始时间",
@@ -140,6 +146,28 @@
          prop: "goodsName",
          labelWidth:labelWidth,
          type: "input",
        },
        {
          label: "货物分类",
          prop: "goodsCategory",
          labelWidth:labelWidth,
          type: "select",
          dicUrl: "/api/blade-system/dict-biz/dictionary?code=goods_category",
          props:{
            label:"dictValue",
            value:"dictKey"
          }
        },
        {
          label: "货物类别",
          prop: "goodsType",
          labelWidth:labelWidth,
          type: "select",
          dicUrl: "/api/blade-system/dict-biz/dictionary?code=goods_type",
          props:{
            label:"dictValue",
            value:"dictKey"
          }
        },
        {
          label: "轴荷分布",
@@ -349,15 +377,17 @@
      editDisplay: false,
      viewDisplay: false,
      display:false,
      hide:true,
    },
    // {
    //   label: "申请编号",
    //   prop: "no",
    //   type: "input",
    //   addDisplay: false,
    //   editDisplay: false,
    //   viewDisplay: false,
    // },
    {
      label: "申请编号",
      prop: "no",
      type: "input",
      addDisplay: false,
      editDisplay: false,
      viewDisplay: false,
      display:false,
    },
    {
      label: "车牌号",
      prop: "licensePlate",
@@ -408,17 +438,44 @@
      viewDisplay: false,
      display:false,
    },
    {
      label: "完善意见",
      prop: "suggestion",
      type: "textarea",
      label: "货物分类",
      prop: "goodsCategory",
      labelWidth:labelWidth,
      type: "select",
      dicUrl: "/api/blade-system/dict-biz/dictionary?code=goods_category",
      props:{
        label:"dictValue",
        value:"dictKey"
      },
      addDisplay: false,
      editDisplay: false,
      viewDisplay: false,
      hide: true,
      span:24,
      labelWidth:'10%'
      display:false,
    },
    // {
    //   label: "完善意见",
    //   prop: "suggestion",
    //   type: "textarea",
    //   addDisplay: false,
    //   editDisplay: false,
    //   viewDisplay: false,
    //   display: true,
    //   hide: true,
    //   span:24,
    //   labelWidth:'10%'
    // },
    // {
    //   label: "批复意见",
    //   prop: "comment",
    //   type: "textarea",
    //   addDisplay: false,
    //   editDisplay: false,
    //   viewDisplay: false,
    //   display: true,
    //   hide: true,
    //   span:24,
    //   labelWidth:'10%'
    // }
  ]
}
src/const/enterprise/enterprise.js
@@ -31,6 +31,7 @@
          labelWidth:labelWidth,
          type: "input",
          hide: true,
          disabled:false
        },
        {
          label: "联系人姓名",
@@ -221,5 +222,19 @@
      hide: true,
      display:false,
    },
    {
      label: "企业名称",
      labelWidth:labelWidth,
      prop: "enterpriseName",
      type: "input",
      display: false,
    },
    {
      label: "单位地址",
      labelWidth:labelWidth,
      prop: "address",
      type: "input",
      display: false,
    },
  ]
}
src/lang/zh.js
@@ -78,7 +78,7 @@
  },
  login: {
    title: '登录 ',
    info: 'BladeX 企业级开发平台',
    info: '大件审批系统',
    tenantId: '请输入租户ID',
    username: '请输入账号',
    password: '请输入密码',
src/page/login/index.vue
@@ -10,25 +10,25 @@
        </div>
        <p class="title">{{ $t('login.info') }}</p>
        <div style="font-size: 15px">
          <span>----------------------------------------------</span>
          <br>
          <span>管理租户编号:000000</span>
          <br>
          <span>超级管理员账号: admin / admin</span>
          <br>
          <span>人事账号: hr / hr</span>
          <br>
          <span>经理账号: manager / manager</span>
          <br>
          <span>老板账号: boss / boss</span>
          <br>
          <span>----------------------------------------------</span>
          <br>
          <span>普通租户编号:详见租户管理模块</span>
          <br>
          <span>租户管理员账号: admin / admin</span>
          <br>
          <span>----------------------------------------------</span>
<!--          <span>&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;</span>-->
<!--          <br>-->
<!--          <span>管理租户编号:000000</span>-->
<!--          <br>-->
<!--          <span>超级管理员账号: admin / admin</span>-->
<!--          <br>-->
<!--          <span>人事账号: hr / hr</span>-->
<!--          <br>-->
<!--          <span>经理账号: manager / manager</span>-->
<!--          <br>-->
<!--          <span>老板账号: boss / boss</span>-->
<!--          <br>-->
<!--          <span>&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;</span>-->
<!--          <br>-->
<!--          <span>普通租户编号:详见租户管理模块</span>-->
<!--          <br>-->
<!--          <span>租户管理员账号: admin / admin</span>-->
<!--          <br>-->
<!--          <span>&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;</span>-->
        </div>
      <!--<img class="img" src="/img/logo.png" alt="">-->
      </div>
src/router/views/index.js
@@ -103,4 +103,40 @@
    component: () =>
      import( /* webpackChunkName: "views" */ '@/views/work/process/leave/detail')
  }]
}]
},
  {
    path: '/work/process/audit',
    component: Layout,
    redirect: '/work/process/audit/form',
    children: [
      {
        path: 'form/:processDefinitionId',
        name: '审核流程',
        meta: {
          i18n: 'work'
        },
        component: () =>
          import( /* webpackChunkName: "views" */ '@/views/work/process/audit/form')
      },
      {
        path: 'handle/:taskId/:processInstanceId/:businessId',
        name: '处理审核流程',
        meta: {
          i18n: 'work'
        },
        component: () =>
          import( /* webpackChunkName: "views" */ '@/views/work/process/audit/handle')
      },
      {
        path: 'detail/:processInstanceId/:businessId',
        name: '审核流程详情',
        meta: {
          i18n: 'work'
        },
        component: () =>
          import( /* webpackChunkName: "views" */ '@/views/work/process/audit/detail')
      }]
  }
]
src/util/formValidator.js
New file
@@ -0,0 +1,19 @@
import {cardid, isvalidatemobile} from "@/util/validate";
export function mobileValidate(rule, value, callback){
  let result = isvalidatemobile(value)
  if (result[0]){
    callback("请输入正确手机号")
  }else {
    callback()
  }
}
export function idCardValidate(rule,value,callback){
  let result = cardid(value)
  if (result[0]){
    callback("请输入正确身份证号")
  }else {
    callback()
  }
}
src/views/application/application.vue
@@ -30,7 +30,9 @@
      </template>
      <template slot-scope="{type,size,row,index}" slot="menu">
        <el-button icon="el-icon-edit" :size="size" :type="type"  @click="$refs.crud.rowEdit(row,index)">编 辑</el-button>
        <el-button icon="el-icon-tickets" :size="size" :type="type" @click="polishApplication">完善信息</el-button>
        <el-button icon="el-icon-tickets" :size="size" :type="type" @click="polishApplication(row.id)">补正</el-button>
        <el-button v-if="permit" icon="el-icon-tickets" :size="size" :type="type">受 理</el-button>
        <el-button v-if="permit" icon="el-icon-tickets" :size="size" :type="type" @click="rejectApplication(row)">不予受理</el-button>
<!--        <el-button icon="el-icon-delete" :size="size" :type="type">车辆变更</el-button>-->
<!--        <el-button icon="el-icon-delete" :size="size" :type="type">延 期</el-button>-->
<!--        <el-button icon="el-icon-delete" :size="size" :type="type">撤 销</el-button>-->
@@ -38,8 +40,8 @@
      <!--按钮自定义-End-->
      <!--cell自定义-Begin-->
      <template slot-scope="{row}" slot="id">
        <a href="#javascript" style="color: #337ab7" @click="$refs.crud.rowView(row)">{{row.id}}</a>
      <template slot-scope="{row}" slot="no">
        <a href="#javascript" style="color: #337ab7" @click="$refs.crud.rowView(row)">{{row.no}}</a>
      </template>
      <template slot-scope="{row}" slot="enterpriseName">
        <a href="#javascript" style="color: #337ab7" @click="getEnterpriseDetail(row.userId)">{{row.enterpriseName}}</a>
@@ -47,7 +49,8 @@
      <!--cell自定义-End-->
    </avue-crud>
    <!--不予受理的表单-->
    <reject v-if="rejectVisible" ref="reject" @refreshLoad="refreshLoad"></reject>
  </basic-container>
</template>
@@ -57,8 +60,10 @@
  import option from "@/const/application/application";
  import enterpriseOption from "@/const/enterprise/enterprise"
  import {mapGetters} from "vuex";
  import Reject from "@/views/application/reject";
  export default {
    components: {Reject},
    data() {
      return {
        form: {},
@@ -73,6 +78,7 @@
        selectionList: [],
        option: option,
        data: [],
        rejectVisible:false
      };
    },
    computed: {
@@ -91,6 +97,9 @@
          ids.push(ele.id);
        });
        return ids.join(",");
      },
      permit(){
        return this.userInfo.role_name == 'admin' || this.userInfo.role_name == 'administrator' ? true:false
      }
    },
    methods: {
@@ -198,6 +207,9 @@
      },
      onLoad(page, params = {}) {
        this.loading = true;
        if (this.userInfo.role_name != 'admin' && this.userInfo.role_name !="administrator"){
          params.userId = this.userInfo.user_id
        }
        getPage(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
          const data = res.data.data;
          this.page.total = data.total;
@@ -242,9 +254,9 @@
        this.form.goodsEntity.id = goodsId
      },
      //完善信息
      polishApplication(){
      polishApplication(id){
        let that = this
        getDetail(this.form.id).then(res => {
        getDetail(id).then(res => {
          let data = res.data.data
          this.form = data
          this.init()
@@ -278,6 +290,13 @@
          })
        });
      },
      //不予受理
      rejectApplication(row){
        this.rejectVisible = true
        this.$nextTick(()=>{
          this.$refs.reject.init(row)
        })
      },
      //获取企业信息
      getEnterpriseDetail(userId){
        getDetailByUserId(userId).then(res=>{
@@ -290,13 +309,19 @@
              width: '70%',
              data:enterpriseDetail,
              option: enterpriseOption,
              callback:(res)=>{
              callback:()=>{
                enterpriseOption.detail = false
              }
            })
          }
        })
      },
      //刷新页面
      refreshLoad(){
        this.onLoad(this.page, this.query);
      }
    }
  };
</script>
src/views/application/reject.vue
New file
@@ -0,0 +1,81 @@
<template>
  <el-dialog
    :title="title"
    :modal-append-to-body="false"
    :append-to-body="true"
    :close-on-click-modal="false"
    width="60%"
    :visible.sync="visible"
  >
    <avue-form ref="form" v-model="form" :option="option" @submit="submit">
    </avue-form>
  </el-dialog>
</template>
<script>
import {add} from '@/api/reject/reject'
export default {
  name: "reject",
  data() {
    return {
      title:"不予受理",
      form: {},
      visible: false,
      option: {
        emptyBtn: false,
        submitText: "保存",
        gutter: 30,
        column: [
          {
            label: "理由",
            prop: "rejectReason",
            type: "select",
            dicUrl: "/api/blade-system/dict-biz/dictionary?code=reject_reason",
            props:{
              label:"dictValue",
              value:"dictKey"
            },
            hide: true,
            rules: [{
              required: true,
              message: "请选择理由",
              trigger: "blur"
            }]
          },
          {
            label: "备注",
            prop: "remark",
            type: "textarea",
            span: 24
          }
        ]
      }
    }
  },
  methods: {
    init(data) {
      this.form.no = data.no
      this.visible = true
    },
    // 表单提交
    submit(row,done) {
      add(row).then(res=>{
        if (res.data.code ==200){
          this.$refs.form.resetFields()
          this.$emit("refreshLoad")
          this.visible = false
          this.$message.success("处理成功")
          done();
        }else {
          this.$message.error("处理失败")
          done();
        }
      })
    }
  }
}
</script>
<style scoped>
</style>
src/views/enterprise/enterprise.vue
@@ -1,6 +1,6 @@
<template>
  <basic-container>
    <avue-crud :option="option"
    <avue-crud v-if="permit" :option="option"
               :table-loading="loading"
               :data="data"
               :page.sync="page"
@@ -28,11 +28,17 @@
        </el-button>
      </template>
    </avue-crud>
    <avue-form v-else
               v-model="form"
               :option="option"
               @submit="handleSubmit"
    ></avue-form>
  </basic-container>
</template>
<script>
  import {getList, getDetail, add, update, remove} from "@/api/enterprise/enterprise";
  import {getList, getDetail,getDetailByUserId, add, update, remove} from "@/api/enterprise/enterprise";
  import option from "@/const/enterprise/enterprise";
  import {mapGetters} from "vuex";
@@ -68,9 +74,36 @@
          ids.push(ele.id);
        });
        return ids.join(",");
      },
      permit(){
        return this.userInfo.role_name == 'admin' || this.userInfo.role_name == 'administrator' ? true:false
      }
    },
    created() {
      if (this.permit){
        this.getEnterpriseDetailByUserId()
      }
    },
    methods: {
      handleSubmit(){
        if (this.form.id){
          update(this.form).then(res=>{
            if (res.data.code == 200){
              this.$message.success(res.data.msg)
            }else {
              this.$message.error(res.data.msg)
            }
          })
        }else {
          add(this.form).then(res=>{
            if (res.data.code == 200){
              this.$message.success(res.data.msg)
            }else {
              this.$message.error(res.data.msg)
            }
          })
        }
      },
      rowSave(row, done, loading) {
        row.userId = this.userInfo.user_id
        add(row).then(() => {
@@ -180,6 +213,16 @@
          this.loading = false;
          this.selectionClear();
        });
      },
      getEnterpriseDetailByUserId(){
        getDetailByUserId(this.userInfo.user_id).then(res=>{
          if (res.data.code == 200){
            this.form = res.data.data
            this.form.account = this.userInfo.account
            const group = this.findObject(this.option.group,"account");
            group.disabled = true
          }
        })
      }
    }
  };
src/views/work/process/audit/detail.vue
New file
@@ -0,0 +1,154 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" label-width="80px">
      <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row>
        <!--审批信息-->
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <avue-form :option="option" v-model="form"/>
      </el-card>
        <!--流程信息-->
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{flow.assigneeName}} 在 [{{flow.createTime}}] 开始处理 [{{flow.historyActivityName}}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{flow.historyActivityDurationTime}}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{flow.comment}}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{flow.endTime}}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
        <!--流程跟踪-->
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
  </basic-container>
</template>
<script>
import {historyFlowList} from "@/api/work/process";
import {applicationDetail} from "@/api/application/application";
import option from "@/const/application/application";
export default {
  name: "detail",
  data() {
    return {
      businessId: '',
      processInstanceId: '',
      src: '',
      flowList: [],
      form: {
        flow:{
          assigneeName:'',
        },
      },
      option:option
    }
  },
  created() {
    this.init();
  },
  beforeDestroy() {
    this.controlOption('close')
  },
  methods: {
    init() {
      this.processInstanceId = this.$route.params.processInstanceId;
      this.businessId = this.$route.params.businessId;
      //控制option
      this.controlOption('open')
      historyFlowList(this.processInstanceId).then(res => {
        const data = res.data;
        if (data.success) {
          this.flowList = data.data;
        }
      })
      applicationDetail(this.businessId).then(res => {
        const data = res.data;
        if (data.success) {
          this.form = data.data;
          this.initForm()
        }
      })
    },
    handleCancel() {
      this.$router.$avueRouter.closeTag();
      this.$router.push({path: `/work/start`});
    },
    //给form表单中的字段赋值
    initForm(){
      let basic = this.form.basicInfoEntity
      let basicId = basic.id
      let plan = this.form.planEntity
      let planId = plan.id
      let scheme = this.form.schemeEntity
      let schemeId = scheme.id
      let car= this.form.carEntity
      let catId = car.id
      let goods = this.form.goodsEntity
      let goodsId = goods.id
      let form = this.form
      //保留原form中的字段
      let common = Object.assign({},form)
      form = Object.assign(form,basic)
      form = Object.assign(form,plan)
      form = Object.assign(form,scheme)
      form = Object.assign(form,car)
      form = Object.assign(form,goods)
      //覆盖回原form
      form = Object.assign(form,common)
      this.form.basicInfoEntity.id = basicId
      this.form.planEntity.id = planId
      this.form.schemeEntity.id = schemeId
      this.form.carEntity.id =catId
      this.form.goodsEntity.id = goodsId
    },
    controlOption(arg){
      const suggestion = this.findObject(this.option.column,"suggestion")
      const comment = this.findObject(this.option.column,"comment")
      if (arg == 'open'){
        this.option.detail = true
        if (!this.form.suggestion){
          // suggestion.display = false
        }
        // comment.display = false
      }else if (arg == 'close'){
        this.option.detail = false
        // suggestion.display = true
        // comment.display = true
      }
    }
  }
}
</script>
<style scoped>
</style>
src/views/work/process/audit/form.vue
New file
@@ -0,0 +1,80 @@
<template>
  <div>
    <basic-container>
      <avue-form :option="option" v-model="form" @submit="handleSubmit"/>
    </basic-container>
    <basic-container>
      <flow-design :is-display="true" :process-definition-id="processDefinitionId"></flow-design>
    </basic-container>
  </div>
</template>
<script>
import {applicationProcess} from "@/api/application/application"
import option from "@/const/application/application"
import {mapGetters} from "vuex";
export default {
  name: "form",
  data() {
    return {
      processDefinitionId: '',
      form: {},
      option:option
    }
  },
  computed: {
    ...mapGetters(["permission", 'userInfo']),
  },
  created() {
    this.controlOption('open')
    this.processDefinitionId = this.$route.params.processDefinitionId;
  },
  beforeDestroy() {
    this.controlOption('close')
  },
  methods: {
    handleSubmit() {
      const params = {
        processDefinitionId: this.$route.params.processDefinitionId,
        userId: this.userInfo.user_id,
        ...this.form,
      };
      applicationProcess(params).then(resp => {
        const data = resp.data;
        if (data.success) {
          this.$message.success(data.msg);
          this.$router.$avueRouter.closeTag();
          this.$router.push({path: `/work/start`});
        } else {
          this.$message.error(data.msg || '提交失败');
        }
      });
    },
    controlOption(arg) {
      const suggestion = this.findObject(this.option.column,"suggestion")
      const comment = this.findObject(this.option.column,"comment")
      if (arg == 'open'){
        //解除禁用状态
        this.option.group.forEach(group=>{
          group.column.forEach(item=>{
            item.disabled = false
          })
        })
        //
        // //隐藏完善意见
        // suggestion.display = false
        // //隐藏批复意见
        // comment.display = false
      }else if (arg == 'close'){
        // suggestion.display = true
        // comment.display = true
      }
    }
  }
}
</script>
<style scoped>
</style>
src/views/work/process/audit/handle.vue
New file
@@ -0,0 +1,331 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <!--          <el-button type="primary" @click="handleAgree">同意</el-button>-->
<!--          <el-button type="success" @click="handlePolish">完善</el-button>-->
<!--          <el-button type="danger" @click="handleDisagree">驳回</el-button>-->
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row>
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <avue-form :option="option" v-model="form"/>
        <el-tabs type="border-card">
          <el-tab-pane label="同意">
            <avue-form ref="form" v-model="agreeModel" :option="agreeOption" @submit="handleAgree"/>
          </el-tab-pane>
          <el-tab-pane label="完善">
            <avue-form ref="form" v-model="polishModel" :option="polishOption" @submit="handlePolish"/>
          </el-tab-pane>
          <el-tab-pane label="驳回">
            <avue-form ref="form" v-model="rejectModel" :option="rejectOption" @submit="handleDisagree"/>
          </el-tab-pane>
        </el-tabs>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{ flow.assigneeName }} 在 [{{ flow.createTime }}] 开始处理 [{{ flow.historyActivityName }}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{ flow.historyActivityDurationTime }}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{ flow.comment }}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{ flow.endTime }}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
  </basic-container>
</template>
<script>
import {historyFlowList, leaveDetail} from "@/api/work/process";
import option from "@/const/application/application";
import {applicationDetail,completeTask} from "@/api/application/application";
export default {
  name: "handle",
  data() {
    return {
      taskId: '',
      businessId: '',
      processInstanceId: '',
      src: '',
      flowList: [],
      form: {
        flow: {
          assigneeName: '',
        },
        startTime: '',
        endTime: '',
        reason: '',
        comment: '',
      },
      option: option,
      //批复相关数据
      agreeModel: {},
      agreeOption: {
        emptyBtn: false,
        submitText: "提交",
        gutter: 30,
        column: [
          {
            label: "批复意见",
            prop: "comment",
            span:24,
            type:'textarea',
            hide: true,
            rules: [{
              required: true,
              message: "请输入批复意见",
              trigger: "blur"
            }]
          },
        ]
      },
      polishModel: {},
      polishOption: {
        emptyBtn: false,
        submitText: "提交",
        gutter: 30,
        column: [
          {
            label: "完善意见",
            prop: "suggestion",
            type:'textarea',
            span:24,
            hide: true,
            rules: [{
              required: true,
              message: "请输入完善意见",
              trigger: "blur"
            }]
          },
          {
            label: "批复意见",
            prop: "comment",
            type:'textarea',
            span:24,
            hide: true,
            rules: [{
              required: true,
              message: "请输入批复意见",
              trigger: "blur"
            }]
          },
        ]
      },
      rejectModel: {},
      rejectOption: {
        emptyBtn: false,
        submitText: "提交",
        gutter: 30,
        column: [
          {
            label: "理由",
            prop: "rejectReason",
            type: "select",
            dicUrl: "/api/blade-system/dict-biz/dictionary?code=reject_reason",
            props: {
              label: "dictValue",
              value: "dictKey"
            },
            hide: true,
            rules: [{
              required: true,
              message: "请选择理由",
              trigger: "blur"
            }]
          },
          {
            label: "备注",
            prop: "remark",
            type: "textarea",
            span: 24
          }
        ]
      }
    }
  },
  created() {
    this.init();
  },
  beforeDestroy() {
    this.controlOption("close")
  },
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用
    // 可以访问组件实例 `this`
    if (to.fullPath !== from.fullPath) {
      next();
      this.init();
    }
  },
  methods: {
    init() {
      this.taskId = this.$route.params.taskId;
      this.processInstanceId = this.$route.params.processInstanceId;
      this.businessId = this.$route.params.businessId;
      this.controlOption('open')
      historyFlowList(this.processInstanceId).then(res => {
        const data = res.data;
        if (data.success) {
          this.flowList = data.data;
        }
      })
      applicationDetail(this.businessId).then(res => {
        const data = res.data;
        if (data.success) {
          this.form = data.data;
          this.initForm()
        }
      })
    },
    //同意
    handleAgree() {
      if (!this.agreeModel.comment) {
        this.$message.warning('请先填写批复意见');
        return;
      }
      const params = {
        taskId: this.taskId,
        processInstanceId: this.processInstanceId,
        flag: 'ok',
        comment: this.agreeModel.comment,
      };
      completeTask(params).then(res => {
        const data = res.data;
        if (data.success) {
          this.$message.success(data.msg);
          this.$router.$avueRouter.closeTag();
          this.$router.push({path: `/work/start`});
        } else {
          this.$message.error(data.msg || '提交失败');
        }
      })
    },
    //驳回
    handleDisagree() {
      if (!this.form.comment) {
        this.$message.warning('请先填写批复意见');
        return;
      }
      const params = {
        taskId: this.taskId,
        processInstanceId: this.processInstanceId,
        comment: this.form.comment,
      };
      completeTask(params).then(res => {
        const data = res.data;
        if (data.success) {
          this.$message.success(data.msg);
          this.$router.$avueRouter.closeTag();
          this.$router.push({path: `/work/start`});
        } else {
          this.$message.error(data.msg || '提交失败');
        }
      })
    },
    //完善
    handlePolish() {
    },
    handleCancel() {
      this.$router.$avueRouter.closeTag();
      this.$router.push({path: `/work/start`});
    },
    //给form表单中的字段赋值
    initForm() {
      let basic = this.form.basicInfoEntity
      let basicId = basic.id
      let plan = this.form.planEntity
      let planId = plan.id
      let scheme = this.form.schemeEntity
      let schemeId = scheme.id
      let car = this.form.carEntity
      let catId = car.id
      let goods = this.form.goodsEntity
      let goodsId = goods.id
      let form = this.form
      //保留原form中的字段
      let common = Object.assign({}, form)
      form = Object.assign(form, basic)
      form = Object.assign(form, plan)
      form = Object.assign(form, scheme)
      form = Object.assign(form, car)
      form = Object.assign(form, goods)
      //覆盖回原form
      form = Object.assign(form, common)
      this.form.basicInfoEntity.id = basicId
      this.form.planEntity.id = planId
      this.form.schemeEntity.id = schemeId
      this.form.carEntity.id = catId
      this.form.goodsEntity.id = goodsId
    },
    //对option进行操作
    controlOption(arg) {
      if (arg == 'open') {
        //设置group内全为禁用状态
        this.option.group.forEach(group => {
          group.column.forEach(item => {
            item.disabled = true
          })
        })
        //隐藏提交 清空按钮
        this.option.submitBtn = false
        this.option.emptyBtn = false
      } else if (arg == 'close') {
        //解除禁用状态
        this.option.group.forEach(group => {
          group.column.forEach(item => {
            item.disabled = false
          })
        })
        //显示提交 清空按钮
        this.option.submitBtn = true
        this.option.emptyBtn = true
      }
    }
  }
}
</script>
<style scoped>
</style>
src/views/work/process/leave/form.vue
@@ -10,103 +10,103 @@
</template>
<script>
  import {leaveProcess} from "@/api/work/process";
import {leaveProcess} from "@/api/work/process";
  export default {
    data() {
      return {
        processDefinitionId: '',
        form: {},
        option: {
          group: [
            {
              icon: 'el-icon-info',
              label: '请假基础信息',
              prop: 'group1',
              column: [
                {
                  label: '审批人员',
                  prop: 'taskUser',
                  type: 'select',
                  dicUrl: `/api/blade-user/user-list`,
                  props: {
                    label: "account",
                    value: "id"
                  },
                  span: 24,
                  rules: [
                    {
                      required: true,
                      message: '请选择审批人员',
                      trigger: 'blur'
                    }
                  ]
export default {
  data() {
    return {
      processDefinitionId: '',
      form: {},
      option: {
        group: [
          {
            icon: 'el-icon-info',
            label: '请假基础信息',
            prop: 'group1',
            column: [
              {
                label: '审批人员',
                prop: 'taskUser',
                type: 'select',
                dicUrl: `/api/blade-user/user-list`,
                props: {
                  label: "account",
                  value: "id"
                },
                {
                  label: '开始时间',
                  prop: 'startTime',
                  type: 'datetime',
                  valueFormat: 'yyyy-MM-dd HH:mm:ss',
                  rules: [
                    {
                      required: true,
                      message: '请选择开始时间',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '结束时间',
                  prop: 'endTime',
                  type: 'datetime',
                  valueFormat: 'yyyy-MM-dd HH:mm:ss',
                  rules: [
                    {
                      required: true,
                      message: '请选择结束时间',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '请假理由',
                  prop: 'reason',
                  type: 'textarea',
                  span: 24,
                  rules: [
                    {
                      required: true,
                      message: '请输入请假理由',
                      trigger: 'blur'
                    }
                  ]
                },
              ]
            },
          ],
        }
      }
    },
    created() {
      this.processDefinitionId = this.$route.params.processDefinitionId;
    },
    methods: {
      handleSubmit() {
        const params = {
          processDefinitionId: this.$route.params.processDefinitionId,
          ...this.form,
        };
        leaveProcess(params).then(resp => {
          const data = resp.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({path: `/work/start`});
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        });
                span: 24,
                rules: [
                  {
                    required: true,
                    message: '请选择审批人员',
                    trigger: 'blur'
                  }
                ]
              },
              {
                label: '开始时间',
                prop: 'startTime',
                type: 'datetime',
                valueFormat: 'yyyy-MM-dd HH:mm:ss',
                rules: [
                  {
                    required: true,
                    message: '请选择开始时间',
                    trigger: 'blur'
                  }
                ]
              },
              {
                label: '结束时间',
                prop: 'endTime',
                type: 'datetime',
                valueFormat: 'yyyy-MM-dd HH:mm:ss',
                rules: [
                  {
                    required: true,
                    message: '请选择结束时间',
                    trigger: 'blur'
                  }
                ]
              },
              {
                label: '请假理由',
                prop: 'reason',
                type: 'textarea',
                span: 24,
                rules: [
                  {
                    required: true,
                    message: '请输入请假理由',
                    trigger: 'blur'
                  }
                ]
              },
            ]
          },
        ],
      }
    }
  },
  created() {
    this.processDefinitionId = this.$route.params.processDefinitionId;
  },
  methods: {
    handleSubmit() {
      const params = {
        processDefinitionId: this.$route.params.processDefinitionId,
        ...this.form,
      };
      leaveProcess(params).then(resp => {
        const data = resp.data;
        if (data.success) {
          this.$message.success(data.msg);
          this.$router.$avueRouter.closeTag();
          this.$router.push({path: `/work/start`});
        } else {
          this.$message.error(data.msg || '提交失败');
        }
      });
    }
  }
}
</script>