<template> <view> <cu-custom bgColor="bg-blue" :isBack="true"> <block slot="backText">返回</block> <block slot="content">{{title}}</block> </cu-custom> <!-- 菜单 --> <view class="bg-white nav fixed flex text-center" :style="[{top:CustomBar + 'px'}]"> <view class="cu-item flex-sub" :class="0==tabIndex?'text-blue cur':''" @tap="tabSelect" data-id="0"> 表单信息 </view> <view class="cu-item flex-sub" v-if="procInsId" :class="2==tabIndex?'text-blue cur':''" @tap="tabSelect" data-id="2"> 流转记录 </view> <!-- <view class="cu-item flex-sub" :class="1==tabIndex?'text-blue cur':''" @tap="tabSelect" data-id="1"> 流程图 </view> --> </view> <view v-show="0 === tabIndex"> <scroll-view scroll-y class="page"> <view class=" bg-white margin-top"> <TestActivitiLeaveForm v-if="formUrl.endsWith('TestActivitiAuditForm')" :formReadOnly="formReadOnly" :class="formReadOnly?'readonly':''" ref="form" :businessId="businessId"></TestActivitiLeaveForm> <!-- <component :formReadOnly="formReadOnly" :class="formReadOnly?'readonly':''" ref="form" :businessId="businessId" :is="form"></component> --> <PreviewForm :formData="formData" v-if="formType !== '2'" :processDefinitionId="procDefId" :edit="true" ref="form"></PreviewForm> </view> <view class=" bg-white margin-top" v-if="!procInsId || taskId"> <form @submit="formSubmit"> <view class="cu-list menu"> <view class="cu-form-group" v-if="!procInsId" > <view class="title"> <text class="red-color">* </text> 标题 </view> <input placeholder="请输入流程标题" maxlength="200" v-model="title" name="title"></input> </view> <view class="cu-form-group" v-if="taskId"> <view class="title"> <text class="red-color">* </text> 内容 </view> <textarea maxlength="2000" v-model="auditForm.message" name="message" placeholder="请输入审批意见"></textarea> </view> <view class="cu-form-group"> <view class="title">是否抄送</view> <jp-switch v-model="isCC" ></jp-switch> </view> <view class="cu-form-group" v-if="isCC"> <view class="title">抄送给</view> <user-select v-model="auditForm.userIds" ></user-select> </view> <view class="cu-form-group"> <view class="title">指定下一步处理者</view> <jp-switch v-model="isAssign"></jp-switch> </view> <view class="cu-form-group" v-if="isAssign"> <view class="title">指定</view> <user-select v-model="auditForm.assignee" ></user-select> </view> <user-select-dialog title="选择转办用户" ref="transferUserSelectDialog" :showRadio="true" :showCheckBox="false" @doSubmit="selectUsersToTransferTask"></user-select-dialog> <user-select-dialog title="选择委派用户" ref="delegateUserSelectDialog" :showRadio="true" :showCheckBox="false" @doSubmit="selectUsersToDelateTask"></user-select-dialog> <user-select-dialog title="选择加签用户" ref="addSignTaskUserSelectDialog" @doSubmit="selectUsersToAddSignTask"></user-select-dialog> <task-back-nodes ref="taskBackNodes" @getBackTaskDefKey="back"></task-back-nodes> </view> <view class="bottom-wrap flex"> <view class="flex-sub" v-show="button.isHide === '0'" v-for="(button, index) in buttons" :key="index" > <button class="cu-btn lg block buttonBox" @click="submit(button, buttons)"> {{button.name}}</button> </view> </view> </form> </view> <view class="cu-tabbar-height"></view> </scroll-view> </view> <view v-show="1 === tabIndex"> <view class="padding bg-white margin-top"> <!-- <img :src="`/getAppFlowChart/`+procDefId+`/`+procInsId" class="procPic"/> --> </view> </view> <view v-show="2 === tabIndex"> <view class="padding bg-white margin-top"> <view class="cu-timeline" :key="index" v-for="(act, index) in historicTaskList"> <view class="cu-time">{{act.histIns.startTime |formatDate('MM-DD')}}</view> <view class="cu-item text-blue"> <view class="content"> <view class="cu-capsule radius"> <view class="cu-tag bg-cyan">{{act.histIns.activityName}}</view> <!-- <view class="cu-tag line-cyan">{{act.histIns.activityName}}</view> --> </view> <view class="margin-top"> 审批人 : {{act.assigneeName}} </view> <view class="margin-top"> 办理状态 :<view class="cu-tag bg-blue">{{act.comment.status}}</view> </view> <view class="margin-top"> 审批意见 : {{act.comment.message}} </view> <view class="margin-top"> 开始时间 : {{act.histIns.startTime |formatDate}} </view> <view class="margin-top"> 结束时间 : {{act.histIns.endTime |formatDate}} </view> <view class="margin-top"> 用时 : {{act.durationTime || '0秒'}} </view> </view> </view> </view> </view> </view> </view> </template> <script> import userSelect from '@/components/user-select/user-select.vue' import userSelectDialog from '@/components/user-select/user-select-dialog.vue' import PreviewForm from '../form/GenerateFlowableForm' import TaskBackNodes from './components/TaskBackNodes.vue' import TestActivitiLeaveForm from '@/pages/test/activiti/TestActivitiLeaveForm.vue' import moment from 'moment' import taskService from "@/api/flowable/taskService" import formService from "@/api/flowable/formService" import processService from "@/api/flowable/processService" import flowCopyService from "@/api/flowable/flowCopyService" import taskDefExtensionService from "@/api/flowable/taskDefExtensionService" var graceChecker = require("@/common/graceChecker.js"); export default { onLoad: function (option) { this.flow = JSON.parse(decodeURIComponent(option.flow)); this.procDefId = this.flow.procDefId this.procDefKey = this.flow.procDefKey this.formType = this.flow.formType this.formUrl = this.flow.formUrl this.taskId = this.flow.taskId this.taskDefKey = this.flow.taskDefKey this.status = this.flow.status this.title = this.flow.formTitle this.businessId = this.flow.businessId this.procInsId = this.flow.procInsId this.formReadOnly = this.flow.formReadOnly !== undefined && this.flow.formReadOnly !== 'false' && this.flow.formReadOnly !== false this.isCC = false this.isAssign = false this.auditForm.assignee = null this.auditForm.userIds = null this.auditForm.message = '' }, async mounted () { if (this.formType === '2') { //外置表单 if (this.formUrl === '/404') { this.form = null uni.showToast({ title: '没有关联流程表单!', icon: "none" }); } else { // uniapp 不支持动态组件,所以通过名称匹配决定调用的表单组件 if(this.formUrl.endsWith('TestActivitiAuditForm')){ this.form = TestActivitiLeaveForm }else{ uni.showToast({ title: '没有关联流程表单!', icon: "none" }); } } } else { // 动态表单 // 读取流程表单 if (this.formUrl === '/404') { uni.showToast({ title: '没有关联流程表单!', icon: "none" }); } else { let {data} = await formService.getMobileForm(this.formUrl); // 初始化动态表单 data.forEach((item)=>{ //挂载 writable,readable,value 属性,是为了触发对这三个属性的监听 item.writable = true item.readable = true if(this.isObjectValue(item)){ item.value = null }else{ item.value = '' } let input = JSON.parse(JSON.stringify(item)) this.formData.push(input) }) if (this.status === 'start') { // 读取启动表单配置 let {data} = await formService.getStartFormData({processDefinitionId: this.procDefId}) this.setData(data, 'start') } else { // 读取任务表单配置 let {data} = await formService.getTaskFormData({taskId: this.taskId}) this.setData(data, 'audit') } } } // 读取按钮配置 if (this.status === 'start') { this.buttons = [{code: '_flow_start', name: '启动', isHide: '0'}] } else if (this.procDefKey && this.taskDefKey) { // 读取按钮 taskDefExtensionService.queryByDefIdAndTaskId({ processDefId: this.procDefKey, taskDefId: this.taskDefKey }).then(({data}) => { this.buttons = data.flowButtonList }) } // 读取历史任务列表 taskService.historicTaskList(this.procInsId).then(({data}) => { this.historicTaskList = data.reverse() }) }, components:{ userSelect, userSelectDialog, TestActivitiLeaveForm, TaskBackNodes, PreviewForm }, data() { return { flow: null, tabIndex: 0, form: null, formType: '', formUrl: '', taskSelectedTab: 'frist', historicTaskList: [], procDefId: '', procInsId: '', formReadOnly: false, procDefKey: '', taskId: '', formData: [], taskDefKey: '', status: '', title: '', businessId: '', buttons: [], isCC: false, isAssign: false, auditForm: { message: '', type: '', status: '', userIds: null, assignee: null } } }, methods:{ tabSelect (e) { this.tabIndex = parseInt(e.currentTarget.dataset.id); }, // 为任务表单赋值 setData (taskFormData, status) { this.formData.forEach((input)=>{ let item = taskFormData.filter((item)=>{ if(input.model === item.id){ return true }else{ return false } })[0] if(item){ if(status === 'start'){ this.isFixParam(input) if(this.isObjectValue(input)){ if(input.options.defaultValue && typeof input.options.defaultValue=== 'string'){ input.value = JSON.parse(input.options.defaultValue) }else{ input.value = input.options.defaultValue } }else{ input.value = input.options.defaultValue || '' } }else{ if(this.isObjectValue(input)){ if(item.value && typeof item.value=== 'string'){ input.value = JSON.parse(item.value) }else { input.value = item.value } }else{ input.value = item.value } } input.readable = item.readable input.writable = item.writable }else{ input.readable = false } }) }, // 默认参数赋值替换 ${user.name}... isFixParam (input) { if(/^[$][{].*[}]$/.test(input.options.defaultValue)){ let params = input.options.defaultValue.substring(2, input.options.defaultValue.length-1) if(params === "new Date()"){ input.options.defaultValue = moment(new Date()).format('YYYY-MM-DD HH:mm:ss') }else{ let value = {user: this.$store.state.user.userInfo} params.split('.').forEach((param)=>{ value = value?.[param] }) input.options.defaultValue = value } } }, // 判断数据类型是否是非String类型 isObjectValue (input) { if(input.type === 'checkbox' || input.type === 'slider' || input.type === 'switch' || input.type === 'rate' || input.type === 'imgupload' || input.type === 'select' && input.options.multiple || input.type === 'fileupload'){ return true } return false }, // 抄送 cc (procInsId) { if (this.isCC && this.auditForm.userIds) { flowCopyService.save({ userIds: this.auditForm.userIds, procDefId: this.procDefId, procInsId: procInsId, procDefName: '', procInsName: this.title, taskName: '' }) } }, // 暂存草稿 save () { }, // 启动流程 start (vars) { if (this.formType === '2') { // 外置表单启动 this.$refs.form.saveForm((businessTable, businessId) => { taskService.start({ procDefKey: this.procDefKey, businessTable: businessTable, businessId: businessId, ...vars, title: this.title, assignee: this.auditForm.assignee }).then(({data}) => { uni.showToast({ title: "启动成功", icon: "success" }); uni.navigateTo({ url: '/pages/workbench/task/TodoList' }) this.cc(data) }) }) } else { //动态表单启动 this.$refs.form.submitStartFormData({ processDefinitionId: this.procDefId, ...vars, title: this.title, assignee: this.auditForm.assignee }, (data) => { uni.showToast({ title: "启动成功", icon: "success" }); uni.navigateTo({ url: '/pages/workbench/task/TodoList' }) this.cc(data) }) } }, // 同意 agree (vars) { this.commit(vars) // 同意 }, // 驳回 reject () { uni.showLoading() uni.showModal({ title: '提示', content: '确定驳回流程吗?', success: (res) => { if (res.confirm) { taskService.backNodes(this.taskId).then(({data}) => { let backNodes = data if (backNodes.length > 0) { let backTaskDefKey = backNodes[backNodes.length - 1].taskDefKey this.back(backTaskDefKey) } }) } else if (res.cancel) { uni.hideLoading() } } }); }, // 驳回到任意节点 turnBack () { this.$refs.taskBackNodes.init(this.taskId) }, // 回退到任意节点 back (backTaskDefKey) { taskService.back({ taskId: this.taskId, backTaskDefKey: backTaskDefKey, ...this.auditForm }).then(({data}) => { uni.showToast({ title: "驳回成功", icon: "success" }); uni.navigateTo({ url: '/pages/workbench/task/TodoList' }) this.cc(data) }) }, // 加签 addMultiInstance () { // this.$refs.addSignTaskUserSelectDialog.showModal() }, selectUsersToAddSignTask (users) { let userIds = users.map((user) => { return user.id }).join(',') taskService.addSignTask({taskId: this.taskId, userIds: JSON.stringify(userIds), message: '', flag: false}).then(({data}) => { uni.showToast({ title: data, icon: "success" }); }) }, // 减签 delMultiInstance () { }, // 转办 transfer () { this.$refs.transferUserSelectDialog.showModal() }, selectUsersToTransferTask (userId) { if(!userId){ uni.showToast({ title: '没有选择任何用户!', icon: "none" }); return } taskService.transfer(this.taskId, userId).then(({data}) => { uni.showToast({ title: data, icon: "success" }); uni.navigateTo({ url: '/pages/workbench/task/TodoList' }) }) }, // 委托 delegate () { this.$refs.delegateUserSelectDialog.showModal() }, selectUsersToDelateTask (userId) { if(!userId){ uni.showToast({ title: '没有选择任何用户!', icon: "none" }); return } taskService.delegate(this.taskId, userId).then(({data}) => { uni.showToast({ title: data, icon: "success" }); uni.navigateTo({ url: '/pages/workbench/task/TodoList' }) }) }, // 终止 stop () { uni.showLoading() uni.showModal({ title: '提示', content: '确定终止流程吗?', success: (res) => { if (res.confirm) { processService.stop(this.procInsId, this.auditForm.message).then(({data}) => { uni.showToast({ title: data, icon: "success" }); uni.navigateTo({ url: '/pages/workbench/task/TodoList' }) }) } else if (res.cancel) { uni.hideLoading() } } }); }, // 打印 print () { }, // 自定义按钮提交 commit (vars) { //定义表单规则 var rule = [ {name:"message", checkType : "notnull", checkRule:"", errorMsg:"审批意见不能为空!"} ]; //进行表单检查 var formData = this.auditForm; var checkRes = graceChecker.check(formData, rule); if(!checkRes){ uni.showToast({ title: graceChecker.error, icon: "none" }); return; } if (this.formType === '2') { //外置表单审批 this.$refs.form.saveForm((businessTable, businessId) => { taskService.audit({ taskId: this.taskId, taskDefKey: this.taskDefKey, procInsId: this.procInsId, procDefId: this.procDefId, vars: vars, message: this.auditForm.message, assignee: this.auditForm.assignee }).then(({data}) => { uni.showToast({ title: "审批成功", icon: "success" }); uni.navigateTo({ url: '/pages/workbench/task/TodoList' }) this.cc(data) }) }) } else { // 动态表单启动 this.$refs.form.submitTaskFormData(vars, this.procInsId, this.taskId, this.auditForm.assignee, this.auditForm, (data) => { uni.showToast({ title: "启动成功", icon: "success" }); uni.navigateTo({ url: '/pages/workbench/task/TodoList' }) //抄送 this.cc(data) }) } }, submit (currentBtn, buttons) { let vars = {} // 存储流程变量 // 把当前操作对应的自定义按钮(以_flow_开头的是系统按钮,排除在外)的编码,存储为对应的流程变量,值设置为true,其余自定义按钮编码对应的流程变量值为false。 buttons.forEach((btn) => { if (btn.code && !btn.code.startsWith('_flow_')) { vars[btn.code] = false } }) if (currentBtn.code && !currentBtn.code.startsWith('_flow_')) { vars[currentBtn.code] = true } vars.title = this.title // 标题 vars.assignee = this.auditForm.assignee // 指定的下一步骤处理人 this.auditForm.type = currentBtn.code // 提交类型 this.auditForm.status = currentBtn.name // 按钮文字 switch (currentBtn.code) { case '_flow_start': // 自动流程 this.start(vars) break case '_flow_save': // 保存草稿 this.save() break case '_flow_agree': // 同意 this.agree() break case '_flow_reject': // 驳回 this.reject() break case '_flow_back': // 驳回到任意步骤 this.turnBack() break case '_flow_add_multi_instance': // 加签 this.addMultiInstance() break case '_flow_del_multi_instance': // 减签 this.delMultiInstance() break case '_flow_transfer': // 转办 this.transfer() break case '_flow_delegate':// 外派 this.delegate() break case '_flow_stop':// 终止 this.stop() break case '_flow_print':// 打印 this.print() break default: this.commit(vars) // 自定义按钮提交 } } } } </script> <style> page { padding-top: 45px; } .cu-form-group .title { min-width: calc(4em + 40px); } uni-view:nth-child(1n+1)>uni-button.buttonBox{ background:#0081ff; color: #FFFFFF; } uni-view:nth-child(1n+2)>uni-button.buttonBox{ background:#f37b1d; color: #FFFFFF; } uni-button:nth-child(1n+3).buttonBox{ background:#8dc63f; color: #FFFFFF; } uni-button:nth-child(1n+4).buttonBox{ background:#1cbbb4; color: #FFFFFF; } uni-button:nth-child(1n+5).buttonBox{ background:#a5673f; color: #FFFFFF; } </style>