import { mapMutations, mapState } from 'vuex' import ApprovalComments from '@/views/matter/components/ApprovalComments' import LeaderDialog from '@/views/matter/components/LeaderDialog' import { getNextTaskByDefId, savaTaskComplete, canLock, getAfterJumpNodesByDefId, getNextExecutor, } from '@/api/process' import { getBpmSaveOpinionByTeam } from '@/api/flow' import request from '@/utils/request' import { ACTION_MAP, ADD_SIGN_ACTION_MAP, TASK_STATUS_ARRAY, CAN_LOCK_STATUS, TASK_STATUS_MESSAGE, } from '@/views/matter/components/const' import { Base64 } from 'js-base64' import { validObject } from '@/utils' import { getValueByPath, setValueByPath } from '@/utils/value.js' export default { components: { ApprovalComments, LeaderDialog, }, props: { name: { type: String, default: '', }, alias: { type: String, default: '', }, nodeType: { type: String, default: '', }, data: { type: Object, default: () => { return {} }, }, formKey: { type: String, default: '', }, formType: { type: String, default: '', }, disabled: { type: Boolean, default: false, }, btnSize: { type: String, default: 'small', }, opinionField: { type: String, default: '', }, appendOpinion: { type: Boolean, default: false, }, beforeClick: { type: Function, default: null, }, dialogBeforeClick: { type: Function, default: null, }, dialogAfterClick: { type: Function, default: null, }, approvalButtonList: { type: Array, default: () => [], }, isGetApprovalBtn: { type: Boolean, default: false, }, }, data() { return { approvalOpinion: '', //审批意见 opinionValue: '', //意见输入框中的值 dialogVisible: false, taskStatus: '', //任务是否锁定状态 isNewProcess: false, //是否新建流程 loading: false, fileList: '', addSignAction: '', signaturePassword: '', //签章密码 jumpNodes: {}, requestParams: {}, //启动或处理待办时发送到后台的参数 oldOpinion: {}, isDialog: false, } }, computed: { ...mapState('user', ['userId', 'username', 'account']), ...mapState('process', ['bpmTask', 'curNodeDef']), ...mapState('signature', ['signatureStatus']), ...mapState('routes', ['fullScreenState']), ...mapState('matter', [ 'currentShowDialogAlias', 'isFromApplicationModule', ]), ...mapState('settings', ['layout']), taskId() { return this.$route.query.taskId || this.bpmTask.id }, doneTaskId() { return this.$route.query.doneTaskId }, instId() { return this.$route.query.instId || this.bpmTask.procInstId }, leaderId() { return this.$route.query.leaderId || 0 }, isFree() { return this.$route.query.type === 'free' }, excludeStatus() { return !TASK_STATUS_ARRAY.includes(this.bpmTask.status) }, //自动签章字段 signatureField() { return this.getNodeProperties()?.signatureField }, // 签章是否免密 secretFree() { return this.getNodeProperties()?.secretFree }, //是否显示签章密码输入框 isShowSignature() { if (this.signatureField) { return !this.secretFree && this.alias === 'agree' } else { return false } // return this.signatureField && this.secretFree && this.alias === 'agree' }, isFromTaskManager() { return this.$route.query.isDefAuthorize }, }, watch: { dialogVisible(val) { if (val) { this.setCurrentShowDialogAlias(this.alias) } }, currentShowDialogAlias(val) { if (val && val !== this.alias) { this.handleClose('autoClose') } }, }, created() { this.$on('update:params', (params) => { Object.assign(this.requestParams, params || {}) }) this.isDialog = JSON.parse(localStorage.getItem('isDialog')) }, methods: { ...mapMutations('signature', [ 'setSignatureConfig', 'setSignatureStatus', 'initSignatureConfig', ]), ...mapMutations('matter', ['setCurrentShowDialogAlias']), //获取任务是否能锁定状态 getTaskIsLock(type) { this.$emit('update:disabled', true) const query = { taskId: this.taskId, leaderId: this.leaderId, } canLock(query, (res) => { if (res || res == '0') { this.taskStatus = CAN_LOCK_STATUS[res] if (['LockedBySomeone', 'hasHandle'].includes(CAN_LOCK_STATUS[res])) { this.$message.warning(TASK_STATUS_MESSAGE[CAN_LOCK_STATUS[res]]) if (this.isDialog) { this.$emit('close-dialog') } else { this.$tabs.close() } } else { if (type === 'agree') { this.openAgreeOrSelectPathJumpDialogBefore() } else if (type === 'savaDraft') { this.dialogVisible = true } } } else { this.$emit('update:disabled', false) } }) }, //7.设置审批意见 setApprovalOpinion(opinion) { this.approvalOpinion = opinion }, //获取意见输入框中的值 getOpinion(val) { this.opinionValue = val }, //10.配置了签章 handleSignature() { //修改签章配置前先初始化配置信息 this.initSignatureConfig() const { signatureCover, secretFree } = this.getNodeProperties() const signatureConfig = { field: this.signatureField, //自动签章字段 isCover: signatureCover, //自动签章时是否覆盖 secretFree: secretFree, //自动签章时是否免密 password: this.signaturePassword, } this.setSignatureConfig(signatureConfig) this.setSignatureStatus('start') }, getNodeProperties() { let currentNodeProperties = {} const nodeProperties = (this.curNodeDef || {}).nodeProperties if (nodeProperties && nodeProperties.length) { const { nodeProperties, localProperties } = this.curNodeDef currentNodeProperties = nodeProperties[0] || localProperties } return currentNodeProperties }, //用户任务加签设置action setAddSignAction() { if (this.nodeType === 'USERTASK' && this.bpmTask.parentId !== '0') { this.addSignAction = ADD_SIGN_ACTION_MAP[this.alias] } }, //判断打开同意审批弹窗或选择路径跳转弹窗 openAgreeOrSelectPathJumpDialogBefore() { if (this.taskStatus === 'LockedBySomeone') { return this.$message.warning(TASK_STATUS_MESSAGE[this.taskStatus]) } this.setAddSignAction() const { choiceExcutor, jumpType } = this.getNodeProperties() if ((choiceExcutor || jumpType || this.isFree) && this.excludeStatus) { const params = { defId: '', instId: '', type: this.$route.query.type || jumpType, } this.getAfterJumpNodes(params, this.openCurrentDialogByJumpNodes) } else { const isGetNextExecutor = this.alias === 'agree' && this.bpmTask.status === 'SIGNSEQUENCEED' isGetNextExecutor ? this.getSequenceSignNextExecutor() : this.openAgreeDialog() } }, openCurrentDialogByJumpNodes() { const onlyOneExecutor = this.jumpNodes.length === 1 && this.jumpNodes[0]?.excutorList?.length === 1 if (this.jumpNodes.length === 0 || onlyOneExecutor) { this.openAgreeDialog() } else { this.$refs.selectPathJump.openSelectPathJumpDialog(this.data) } }, //获取顺序签署下一步执行人 getSequenceSignNextExecutor() { getNextExecutor(this.taskId, (res) => { if (!res.data) return if (res.data.state && res.data.value) { this.$confirm( `下一步执行人为:${res.data?.value?.name},您确定要继续?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', } ) .then(() => { this.openAgreeDialog() }) .catch(() => {}) } }) }, //获取跳转节点 getAfterJumpNodes(params, callback) { const requestParams = { taskId: this.taskId || '', data: Base64.encode(JSON.stringify(this.data)), alias: this.alias, ...params, } getAfterJumpNodesByDefId(requestParams).then((res) => { this.jumpNodes = res this.selectConfig = res callback() }) }, //通过实例id和任务id获取审批意见 getApprovalOpinionByInstIdAndTaskId() { getBpmSaveOpinionByTeam(this.instId, this.taskId, ({ state, value }) => { const opinion = state && value ? value : ACTION_MAP[this.alias] this.setApprovalOpinion(opinion) }) }, // 审批意见前缀 添加节点名称和当前操作名称 getOpinionPre() { return `${this.bpmTask.name}:${this.name}  ` }, //审批意见的后缀 getOpinionTail() { return `  审核人:${this.username}  审核日期:${new Date().format( 'yyyy-MM-dd HH:mm:ss' )}` }, //设置审批意见回填 setOpinionWrap() { if (this.opinionField && this.opinionValue) { let opinion4Fill = null //是否覆盖审批意见 if (this.appendOpinion) { opinion4Fill = `${this.getOpinionPre()}审核意见:${ this.opinionValue }${this.getOpinionTail()}\n` } else { const oldVal = getValueByPath(this.data, this.opinionField) this.oldOpinion[this.opinionField] = oldVal let preVal = '' if (oldVal && oldVal.trim() != '


') { preVal = `${oldVal}\n ` } if (preVal && preVal.indexOf('\n') == -1) { opinion4Fill = `${this.getOpinionPre()}审核意见:${preVal}${ this.opinionValue }${this.getOpinionTail()}\n` } else { opinion4Fill = `${preVal} ${this.getOpinionPre()}审核意见:${ this.opinionValue }${this.getOpinionTail()}\n` } } setValueByPath(this.data, this.opinionField, opinion4Fill) } }, //11.执行前置脚本 handlePreScript(btnAlias) { //执行前置脚本内容 const _this = this const _req = request const boData = this.data const buttonConfig = this.getCurrentButtonConfigByBtnAlias(btnAlias) const preScript = `const scriptFunction = function(_req,boData,_this){ ${buttonConfig?.beforeScript} };` try { const result = eval(`${preScript}scriptFunction(_req,boData,_this);`) if (result && result.then && typeof result.then === 'function') { return result } if (result === false) return false return true } catch (err) { this.$message.error(`操作按钮的前置事件执行错误:${err}`) } }, submitBefore(btnAlias, formScopeName) { this.isNewProcess = formScopeName === 'isNewProcess' //获取执行前置脚本返回结果 const preScriptResult = this.handlePreScript(btnAlias) //前置脚本结果为false直接return if (!preScriptResult) { this.startFlowLoading = false this.saveDraftLoading = false this.loading = false return false } //执行前置脚本返回的接口时先执行前置事件接口 if (preScriptResult.then && typeof preScriptResult.then === 'function') { preScriptResult.then( () => { this.onSubmit(formScopeName) }, (fail) => { //接口返回失败则终止按钮操作,并输出错误信息 this.startFlowLoading = false this.saveDraftLoading = false this.loading = false return this.$message.warning(fail) } ) } else { //执行前置脚本返回true时继续提交 this.onSubmit(formScopeName) } }, //最后执行后置事件 submitAfter(btnAlias) { const _this = this const _req = request const boData = this.data const buttonConfig = this.getCurrentButtonConfigByBtnAlias(btnAlias) const afterScript = `const scriptFunction = function(_req,boData,_this){${buttonConfig?.afterScript}};` try { eval(`${afterScript}scriptFunction(_req,boData,_this);`) } catch (err) { this.$message.error(`操作按钮的后置事件执行错误:${err}`) } }, //12.提交表单(表单校验在页面内进行) onSubmit() { this.handleSubmitting() }, //处理请求提交接口 handleSubmitting() { //审批意见回填 this.setOpinionWrap() //获取agreeForm表单数据 const currentUrgentConfig = localStorage.getItem('urgentStateValue') const data = { formKey: this.formKey, data: Base64.encode(JSON.stringify(this.data)), opinion: this.opinionValue, ...this.getSubmitCommonData(), } // 如果有紧急状态,需要传递这个参数 if (currentUrgentConfig) { data.urgentStateValue = JSON.parse(currentUrgentConfig) } const this_ = this this.loading = true savaTaskComplete(data) .then((res) => { if (!res.state) return this.$message.error(res.message) this.filterHasHandleTask() this.handleClose() this.$emit('update:disabled', false) this.$message.success(res.message) const isAutoOpenNextTodo = JSON.parse( localStorage.getItem('isAutoOpenNextTodo') ) const isAutoOpenNextLeaderTodo = JSON.parse( localStorage.getItem('isAutoOpenNextLeaderTodo') ) const isFromLeaderTodo = this.$refs.leaderDialog.getIsFromLeaderTodo() const isAutoOpenNext = isFromLeaderTodo ? isAutoOpenNextLeaderTodo : isAutoOpenNextTodo //默认未设置值时isAutoOpenNext等于null,值为null和true时自动获取下一条任务 if (isAutoOpenNext == null || isAutoOpenNext) { //跳转下一个任务 this.nextTask(res) } else { const path = '/matter/myTask?tabActiveName=todo' if (this.isDialog) { this.$emit('close-dialog') } else { if (this.fullScreenState) { this.$router.go(-1) } else { this.$tabs.replace({ path }) } } } this.dialogAfterClick(this.alias) }) .catch(() => { //处理任务失败吧意见回填的值改回去 for (let key in this_.oldOpinion) { setValueByPath(this_.data, key, this_.oldOpinion[key]) } this_.oldOpinion = {} }) .finally(() => { this.loading = false }) }, getCurrentButtonConfigByBtnAlias(btnAlias) { const btnList = this.isNewProcess ? this.startButtonList : this.approvalButtonList const buttonConfig = btnList?.find((btn) => btn.alias === btnAlias) return buttonConfig }, //跳转下一个任务 nextTask(res) { if (res.state) { let map = res.value ? JSON.parse(res.value) : {} this.executorIsEmptyRow = map //节点属性配置执行人为空时选择 assign:由审批人指定 if (map.executorIsEmpty && map.executorIsEmpty == 'assign') { this.executorIsEmptyDialog = true } else { this.getNextTaskByDefKeyAndDefId() } } else { this.getNextTaskByDefKeyAndDefId() } }, //获取下一个待办任务根据defId,defKey getNextTaskByDefKeyAndDefId() { let loading = this.$loading({ target: document.querySelector('.form-container'), text: '正在获取下一个任务,请稍等...', spinner: 'el-icon-loading', background: '', }) const { procDefId, procDefKey } = this.bpmTask const query = { defKey: procDefKey, defId: procDefId, } let time = 1500 getNextTaskByDefId(query).then((res) => { if (res.value) { if (this.isDialog) { this.$baseEventBus.$emit('approval-form-load-data', res.value) } else { this.$refs.leaderDialog.handleJumpsTodoPage( res.value, { isGetApprovalBtn: true, }, true ) } } else { //判断是否是模块开发 time = 0 const path = '/matter/myTask?tabActiveName=todo' if (this.fullScreenState) { this.$router.go(-1) } else { this.$tabs.replace({ path }) } if (this.isDialog) { this.$emit('close-dialog') } } setTimeout(() => { loading.close() }, time) }) }, //获取点击审批按钮时需要提交的共同数据 getSubmitCommonData() { let formType = '' if (this.formType) { formType = this.formType.toLowerCase() } const formData = { formType: formType, vars: this.data?.vars || '', data: formType === 'inner' ? Base64.encode(JSON.stringify(this.data)) : '', } const data = { taskId: this.taskId, actionName: this.alias, destination: '', zfiles: '', jumpType: '', agentLeaderId: this.leaderId, files: JSON.stringify(this.fileList), ...validObject(formData), } Object.assign(data, this.requestParams) return data }, handleClose(type) { this.approvalOpinion = '' this.signaturePassword = '' if (this.users) { this.users = '' } this.dialogVisible = false this.$emit('update:disabled', false) if (type !== 'autoClose') { this.setCurrentShowDialogAlias('') } }, dialogModeApprovalCompletionToMyTask() { this.isDialog ? this.$emit('close-dialog') : this.$router.push('/matter/myTask') }, //审批完成回到上一个页面 dialogModeApprovalCompletionToPre(from = '') { if (['inquiryReply', 'feedback'].includes(from)) { this.isDialog ? this.$emit('close-dialog') : this.$router.push('/matter/myTask') } else { this.isDialog ? this.$emit('close-dialog') : this.$router.go(-1) } }, //过滤掉已处理的特别关注的任务 filterHasHandleTask() { if (localStorage.getItem(this.account)) { const specialFocusTaskList = JSON.parse(localStorage.getItem(this.account)) || [] const currentSpecialFocusTask = specialFocusTaskList.filter( (item) => item.taskId !== this.taskId ) localStorage.setItem( this.account, JSON.stringify(currentSpecialFocusTask) ) } }, }, }