新的流程页面对接自带的流程页面,查询表单使用同一个接口,其接口内部做判定、流程推进详情页面
5个文件已修改
2个文件已添加
608 ■■■■■ 已修改文件
src/api/flowable/process.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/projectProcess/projectProcess.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/flowable/task/myProcess/send/index.vue 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/flowable/task/myProcess/send/index1.vue 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/projectProcess/components/RunProcess.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/projectProcess/detail/index.vue 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/projectProcess/index.vue 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/flowable/process.js
@@ -35,6 +35,15 @@
  })
}
// 完成表单提交任务/普通提交任务
export function completeSubmitFormTask(taskId, data) {
  return request({
    url: '/flowable/task/complete/form/' + taskId,
    method: 'post',
    data: data
  })
}
// 取消申请
export function stopProcess(data) {
  return request({
src/api/projectProcess/projectProcess.js
@@ -17,3 +17,20 @@
    data: data
  })
}
// 获取项目流程详情数据
export const getProjectProcessDetail = (projectId, processId) => {
  return request({
    url: "/project-process/detail/" + projectId + "/" + processId,
    method: "GET"
  })
}
// 启动流程
export const startProcess = (projectId, processId) => {
  return request({
    url: "/project-process/start/" + projectId + "/" + processId,
    method: "POST"
  })
}
src/views/flowable/task/myProcess/send/index.vue
@@ -2,7 +2,7 @@
  <div class="app-container">
    <el-card class="box-card" >
      <div slot="header" class="clearfix">
        <span class="el-icon-document">发起任务</span>
        <span class="el-icon-document">{{`流程处理:` + processName}}</span>
        <el-button style="float: right;" size="mini" type="danger" @click="goBack">关闭</el-button>
      </div>
      <el-tabs  tab-position="top" v-model="activeName"  @tab-click="handleClick">
@@ -38,7 +38,8 @@
<script>
import {definitionStart, flowXmlAndNode} from "@/api/flowable/definition";
import BpmnViewer from '@/components/Process/viewer';
import {flowFormData} from "@/api/flowable/process";
import {completeSubmitFormTask} from "@/api/flowable/process";
import { flowTaskForm } from "@/api/flowable/todo";
import {getNextFlowNodeByStart} from "@/api/flowable/todo";
import FlowUser from '@/components/flow/User'
import FlowRole from '@/components/flow/Role'
@@ -53,6 +54,8 @@
  props: {},
  data() {
    return {
      taskId: '',
      processName: '',
      // 模型xml数据
      flowData: {},
      activeName: '1', // 切换tab标签
@@ -78,11 +81,13 @@
    };
  },
  created() {
    this.processName = this.$route.query && this.$route.query.processName;
    this.deployId = this.$route.query && this.$route.query.deployId;
    this.taskId = this.$route.query && this.$route.query.taskId;
    // 初始化表单
    this.procDefId  = this.$route.query && this.$route.query.procDefId;
    // this.getNextFlowNodeByStart(this.deployId);
    this.getFlowFormData(this.deployId);
    this.getFlowFormData(this.taskId);
  },
  methods: {
    handleClick(tab, event) {
@@ -93,15 +98,28 @@
      }
    },
    /** 流程表单数据 */
    getFlowFormData(deployId) {
      const params = {deployId: deployId}
      flowFormData(params).then(res => {
        // 流程过程中不存在初始化表单 直接读取的流程变量中存储的表单值
    getFlowFormData(taskId) {
      const params = {taskId: taskId}
      flowTaskForm(params).then(res => {
        if (res.data.formJson) {
          // 回显表单
          this.$refs.vFormRef.setFormJson(res.data.formJson);
          this.formJson = res.data.formJson;
          this.$nextTick(() => {
            // 加载表单填写的数据
            this.$refs.vFormRef.setFormData(res.data);
            // this.$nextTick(() => {
            //   // 表单禁用
            //   this.$refs.vFormRef.disableForm();
            // })
          })
        } else {
        this.$nextTick(() => {
          // 回显数据
          this.$refs.vFormRef.setFormJson(res.data);
          this.formJson = res.data;
        })
        }
      }).catch(res => {
        this.goBack();
      })
@@ -144,11 +162,16 @@
                }
                // 复制对象的属性值给新的对象
                Object.assign(param, formData);
                // 启动流程并将表单数据加入流程变量
                definitionStart(this.procDefId, param).then(res => {
                // 完成任务
                completeSubmitFormTask(this.taskId, param).then(res => {
                  this.$modal.msgSuccess(res.msg);
                  this.goBack();
                })
                // // 启动流程并将表单数据加入流程变量
                // definitionStart(this.procDefId, param).then(res => {
                //   this.$modal.msgSuccess(res.msg);
                //   this.goBack();
                // })
              }
            }
          }
@@ -182,11 +205,16 @@
        } else {
          this.$set(param, "approval", this.checkValues);
        }
        // 启动流程并将表单数据加入流程变量
        definitionStart(this.procDefId, param).then(res => {
        // 完成任务
        completeSubmitFormTask(this.taskId, param).then(res => {
          this.$modal.msgSuccess(res.msg);
          this.goBack();
        })
        // // 启动流程并将表单数据加入流程变量
        // definitionStart(this.procDefId, param).then(res => {
        //   this.$modal.msgSuccess(res.msg);
        //   this.goBack();
        // })
      }
    },
    // 用户信息选中数据
src/views/flowable/task/myProcess/send/index1.vue
New file
@@ -0,0 +1,249 @@
<template>
  <div class="app-container">
    <el-card class="box-card" >
      <div slot="header" class="clearfix">
        <span class="el-icon-document">发起任务</span>
        <el-button style="float: right;" size="mini" type="danger" @click="goBack">关闭</el-button>
      </div>
      <el-tabs  tab-position="top" v-model="activeName"  @tab-click="handleClick">
        <!--表单信息-->
        <el-tab-pane label="表单信息" name="1">
          <!--初始化流程加载表单信息-->
          <el-col :span="16" :offset="4">
            <v-form-render :form-data="formRenderData" ref="vFormRef"/>
            <div style="margin-left:15%;margin-bottom: 20px;font-size: 14px;">
              <el-button type="primary" @click="submitForm">提 交</el-button>
              <el-button type="primary" @click="resetForm">重 置</el-button>
            </div>
          </el-col>
        </el-tab-pane>
        <!--流程图-->
        <el-tab-pane label="流程图" name="2">
          <bpmn-viewer :flowData="flowData"/>
        </el-tab-pane>
      </el-tabs>
      <!--选择流程接收人-->
      <el-dialog :title="taskTitle" :visible.sync="taskOpen" width="65%" append-to-body>
        <flow-user v-if="checkSendUser" :checkType="checkType"  @handleUserSelect="handleUserSelect"/>
        <flow-role v-if="checkSendRole" @handleRoleSelect="handleRoleSelect"/>
        <span slot="footer" class="dialog-footer">
          <el-button @click="taskOpen = false">取 消</el-button>
          <el-button type="primary" @click="submitTask">提 交</el-button>
        </span>
      </el-dialog>
    </el-card>
  </div>
</template>
<script>
import {definitionStart, flowXmlAndNode} from "@/api/flowable/definition";
import BpmnViewer from '@/components/Process/viewer';
import {flowFormData} from "@/api/flowable/process";
import {getNextFlowNodeByStart} from "@/api/flowable/todo";
import FlowUser from '@/components/flow/User'
import FlowRole from '@/components/flow/Role'
export default {
  name: "Record",
  components: {
    BpmnViewer,
    FlowUser,
    FlowRole,
  },
  props: {},
  data() {
    return {
      // 模型xml数据
      flowData: {},
      activeName: '1', // 切换tab标签
      // 查询参数
      queryParams: {
        deptId: undefined
      },
      // 遮罩层
      loading: true,
      deployId: "",  // 流程定义编号
      procDefId: "",  // 流程实例编号
      formRenderData: {},
      variables: [], // 流程变量数据
      taskTitle: null,
      taskOpen: false,
      checkSendUser: false, // 是否展示人员选择模块
      checkSendRole: false,// 是否展示角色选择模块
      checkType: '', // 选择类型
      checkValues: null, // 选中任务接收人员数据
      formData: {}, // 填写的表单数据,
      multiInstanceVars: '', // 会签节点
      formJson: {} // 表单json
    };
  },
  created() {
    this.deployId = this.$route.query && this.$route.query.deployId;
    // 初始化表单
    this.procDefId  = this.$route.query && this.$route.query.procDefId;
    // this.getNextFlowNodeByStart(this.deployId);
    this.getFlowFormData(this.deployId);
  },
  methods: {
    handleClick(tab, event) {
      if (tab.name === '2'){
        flowXmlAndNode({deployId:this.deployId}).then(res => {
          this.flowData = res.data;
        })
      }
    },
    /** 流程表单数据 */
    getFlowFormData(deployId) {
      const params = {deployId: deployId}
      flowFormData(params).then(res => {
        // 流程过程中不存在初始化表单 直接读取的流程变量中存储的表单值
        this.$nextTick(() => {
          // 回显数据
          this.$refs.vFormRef.setFormJson(res.data);
          this.formJson = res.data;
        })
      }).catch(res => {
        this.goBack();
      })
    },
    /** 返回页面 */
    goBack() {
      // 关闭当前标签页并返回上个页面
      const obj = { path: "/task/process", query: { t: Date.now()} };
      this.$tab.closeOpenPage(obj);
    },
    /** 申请流程表单数据提交 */
    submitForm() {
      this.$refs.vFormRef.getFormData().then(formData => {
        // 根据当前任务或者流程设计配置的下一步节点 todo 暂时未涉及到考虑网关、表达式和多节点情况
        getNextFlowNodeByStart({deploymentId: this.deployId, variables: formData}).then(res => {
          const data = res.data;
          if (data) {
            this.formData = formData;
            if (data.dataType === 'dynamic') {
              if (data.type === 'assignee') { // 指定人员
                this.checkSendUser = true;
                this.checkType = "single";
              } else if (data.type === 'candidateUsers') {  // 候选人员(多个)
                this.checkSendUser = true;
                this.checkType = "multiple";
              } else if (data.type === 'candidateGroups') { // 指定组(所属角色接收任务)
                this.checkSendRole = true;
              } else { // 会签
                // 流程设计指定的 elementVariable 作为会签人员列表
                this.multiInstanceVars = data.vars;
                this.checkSendUser = true;
                this.checkType = "multiple";
              }
              this.taskOpen = true;
              this.taskTitle = "选择任务接收";
            } else {
              if (this.procDefId) {
                const param = {
                  formJson:  this.formJson,
                }
                // 复制对象的属性值给新的对象
                Object.assign(param, formData);
                // 启动流程并将表单数据加入流程变量
                definitionStart(this.procDefId, param).then(res => {
                  this.$modal.msgSuccess(res.msg);
                  this.goBack();
                })
              }
            }
          }
        })
      }).catch(error => {
        // this.$modal.msgError(error)
      })
    },
    /** 重置表单 */
    resetForm() {
      this.$refs.vFormRef.resetForm();
    },
    /** 提交流程 */
    submitTask() {
      if (!this.checkValues && this.checkSendUser){
        this.$modal.msgError("请选择任务接收!");
        return;
      }
      if (!this.checkValues && this.checkSendRole){
        this.$modal.msgError("请选择流程接收角色组!");
        return;
      }
      if (this.formData) {
        const param = {
          formJson:  this.formJson,
        }
        // 复制对象的属性值给新的对象
        Object.assign(param, this.formData);
        if (this.multiInstanceVars) {
          this.$set(param, this.multiInstanceVars, this.checkValues);
        } else {
          this.$set(param, "approval", this.checkValues);
        }
        // 启动流程并将表单数据加入流程变量
        definitionStart(this.procDefId, param).then(res => {
          this.$modal.msgSuccess(res.msg);
          this.goBack();
        })
      }
    },
    // 用户信息选中数据
    handleUserSelect(selection) {
      if (selection) {
        if (selection instanceof Array) {
          const selectVal = selection.map(item => item.userId);
          if (this.multiInstanceVars) {
            this.checkValues = selectVal;
          } else {
            this.checkValues = selectVal.join(',');
          }
        } else {
          this.checkValues = selection.userId;
        }
      }
    },
    // 角色信息选中数据
    handleRoleSelect(selection) {
      if (selection) {
        if (selection instanceof Array) {
          const selectVal = selection.map(item => item.roleId);
          this.checkValues = selectVal.join(',')
        } else {
          this.checkValues = selection;
        }
      }
    },
  }
};
</script>
<style lang="scss" scoped>
.test-form {
  margin: 15px auto;
  width: 800px;
  padding: 15px;
}
.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}
.clearfix:after {
  clear: both
}
.box-card {
  width: 100%;
  margin-bottom: 20px;
}
.el-tag + .el-tag {
  margin-left: 10px;
}
.my-label {
  background: #E1F3D8;
}
</style>
src/views/projectProcess/components/RunProcess.vue
@@ -74,7 +74,7 @@
        </el-table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button type="danger" @click="startProcess">启动</el-button>
        <el-button type="danger" @click="startProcess" :disable="!this.selectProcessId">启动流程</el-button>
        <el-button type="primary" @click="changeProcess">变更</el-button>
      </span>
    </el-dialog>
@@ -82,7 +82,7 @@
</template>
<script>
import {projectSetProcess} from "@/api/projectProcess/projectProcess";
import {projectSetProcess, startProcess} from "@/api/projectProcess/projectProcess";
export default {
  dicts: ['sys_project_type', 'sys_funding_type', 'sys_investment_type', 'sys_key_categories'],
@@ -148,7 +148,9 @@
    },
    // 启动流程
    startProcess() {
      startProcess(this.projectInfo.projectId, this.selectProcessId).then(res => {
        this.$message.success(res.msg);
      })
    },
    // 变更流程
    changeProcess() {
src/views/projectProcess/detail/index.vue
New file
@@ -0,0 +1,251 @@
<template>
  <div class="app-container">
    <div class="top">
      <div class="project-title">
        <h2>项目名称:{{detailData.projectName}}</h2>
      </div>
      <div class="project-info">
        <div class="project-info-item"></div>
        <div class="project-info-item">项目代码:{{detailData.projectCode}}</div>
        <div class="project-info-item">
          <div style="color: black">
            <div>中预资金</div>
            <div>市重点项目</div>
          </div>
        </div>
      </div>
    </div>
    <div class="search-warp">
      <div @click="changeTab(1, 'all')" :class="{'item-warm': true, 'all-color': true, 'active': 1 === selectTabId}">全部事项({{detailData.statistics.totalTaskNum}})</div>
      <div @click="changeTab(2, 'todo')" :class="{'item-warm': true, 'all-color': true, 'active': 2 === selectTabId}">代办事项({{detailData.statistics.todoTaskNum}})</div>
      <div @click="changeTab(3, 'current')" :class="{'item-warm': true, 'current-color': true, 'active': 3 === selectTabId}">当前环节</div>
      <div @click="changeTab(4, 'remaining')" :class="{'item-warm': true, 'remaining-color': true, 'active': 4 === selectTabId}">剩余事项({{detailData.statistics.totalTaskNum}})</div>
      <div @click="changeTab(5, 'timely')" :class="{'item-warm': true, 'timely-color': true, 'active': 5 === selectTabId}">按时完成(0)</div>
      <div @click="changeTab(6, 'overtime')" :class="{'item-warm': true, 'overtime-color': true, 'active': 6 === selectTabId}">超时事项(0)</div>
      <div @click="changeTab(7, 'willOvertime')" :class="{'item-warm': true, 'willOvertime-color': true, 'active': 7 === selectTabId}">临期事项(0)</div>
      <div @click="changeTab(8, 'urge')" :class="{'item-warm': true, 'urge-color': true, 'active': 8 === selectTabId}">督办事项(0)</div>
    </div>
    <div style="display: flex;justify-content: center;align-items: center;margin-top: 20px">
      <el-form :inline="true" :model="queryParams" class="demo-form-inline">
        <el-form-item label="任务名称">
          <el-input v-model="queryParams.taskName" placeholder="任务名称"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="getList">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="table">
      <el-table
        :data="taskList"
        border
        style="width: 100%">
        <el-table-column
          prop="taskName"
          label="任务名称"
         >
        </el-table-column>
        <el-table-column
          prop="procDefName"
          label="流程名称"
         >
        </el-table-column>
        <el-table-column
          prop="startUserName"
          label="发起人"
        >
        </el-table-column>
        <el-table-column
          prop="startDeptName"
          label="发起单位"
        >
        </el-table-column>
        <el-table-column
          prop="assigneeDeptName"
          label="处理单位"
        >
        </el-table-column>
        <el-table-column
          prop="assigneeName"
          label="实际处理人"
        >
        </el-table-column>
        <el-table-column
          fixed="right"
          label="操作"
          width="100">
          <template slot-scope="scope">
            <el-button @click="goToProcessDetail(scope.row)" type="text" size="small">查看</el-button>
            <el-button @click="goToDo(scope.row)" type="text" size="small">办理</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div>
        <el-pagination
          v-if="total > pageSize"
          :page-size="pageSize"
          :current-page="pageNum"
          :total="total"
          layout="total, prev, pager, next"
          @current-change="getList"
        ></el-pagination>
      </div>
    </div>
  </div>
</template>
<script>
import {getProjectProcessDetail} from "@/api/projectProcess/projectProcess";
export default {
  name: "index",
  data() {
    return {
      projectId: null,
      processId: null,
      detailData: {},
      selectTabId: 2,
      taskList: [],
      total: 0,
      pageSize: 5,
      pageNum: 1,
      queryParams: {
        taskName: ''
      }
    }
  },
  mounted() {
    this.projectId = this.$route.query.projectId
    this.processId = this.$route.query.processId
    this.getProjectProcessInfo()
  },
  methods: {
    goToDo(row) {
      // TODO 这里的判断条件根据实际情况设置
      if (this.$auth.hasRole('admin')) {
        console.log("zhe")
        this.$router.push({
          path: '/flowable/task/todo/detail/index',
          query: {
            taskName: row.procDefName,
            startUser: row.startUserName,
            deployId: row.deployId,
            taskId: row.taskId,
            procInsId: row.procInsId,
            executionId: row.executionId
          }
        })
      } else {
        this.$router.push({
          path: '/flowable/task/myProcess/send/index',
          query: {
            deployId: row.deployId,
            procDefId: row.procDefId,
            processName: row.procDefName,
            taskId: row.taskId
          }
        })
      }
    },
    goToProcessDetail(row) {
      this.$router.push({ path: '/flowable/task/myProcess/detail/index',
        query: {
          procInsId: row.procInsId,
          deployId: row.deployId,
          taskId: row.taskId
        }})
    },
    getList() {
      // 获取任务列表
    },
    // 查询详情
    getProjectProcessInfo() {
      getProjectProcessDetail(this.projectId, this.processId).then(res => {
        this.detailData = res.data
        this.taskList = res.taskList
      })
    },
    changeTab(id, event) {
      this.selectTabId = id
    }
  }
}
</script>
<style scoped>
.project-title {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
.project-info {
  display: flex;
  color: #a9a8a8;
}
.project-info-item {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
}
.search-warp {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  margin-top: 20px;
}
.item-warm {
  width: 134px;
  height: 60px;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  border-radius: 20px;
  margin: 0 20px;
  transition: transform 0.3s ease; /* 添加过渡效果 */
}
.item-warm:hover {
  cursor: pointer;
  transform: translateY(-10px);
}
.all-color {
  background-color: rgb(180, 253, 255);
}
.current-color {
  background-color: rgb(127, 131, 247);
  color: white;
}
.remaining-color {
  background-color: rgb(164, 173, 179);
  color: white;
}
.timely-color {
  background-color: rgb(204, 247, 131);
}
.overtime-color {
  background-color: rgb(129, 179, 55);
  color: white;
}
.willOvertime-color {
  background-color: rgb(255, 248, 29);
}
.urge-color {
  background-color: rgb(0, 0, 0);
  color: white;
}
.active {
  transform: translateY(-10px);
}
.table {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
src/views/projectProcess/index.vue
@@ -226,13 +226,13 @@
      <!-- 操作列 -->
      <el-table-column label="操作" width="140" align="center" >
        <template slot-scope="scope">
          <!--          <el-button-->
          <!--            size="medium"-->
          <!--            type="text"-->
          <!--            icon="el-icon-view"-->
          <!--            @click="lookProcessDetail(scope.row)"-->
          <!--          >-->
          <!--          </el-button>-->
                    <el-button
                      size="medium"
                      type="text"
                      icon="el-icon-view"
                      @click="lookProcessDetail(scope.row)"
                    >
                    </el-button>
          <!--          <el-button-->
          <!--            v-if="isReserve"-->
          <!--            size="medium"-->
@@ -387,6 +387,16 @@
    this.getList();
  },
  methods: {
    // 查看详情
    lookProcessDetail(row) {
      this.$router.push({
        path: '/projectFlow/detail',
        query: {
          projectId: row.id,
          processId: row.flowableProcessId
        }
      })
    },
    closeRunProcess() {
      this.projectRunFrom = {
        projectId: null,