Files
zhxg_pc/src/views/flowable/task/todo/detail/disqualificationIndex.vue
2025-10-18 17:13:04 +08:00

709 lines
27 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span class="el-icon-document">待办任务</span>
<el-tag style="margin-left: 10px">发起人:{{ startUser }}</el-tag>
<el-tag>任务节点:{{ taskName }}</el-tag>
<el-button style="float: right" size="mini" type="danger" @click="goBack">关闭</el-button>
</div>
<el-tabs v-model="activeName" tab-position="top" @tab-click="handleClick">
<!--表单信息-->
<el-tab-pane label="表单信息" name="1">
<el-col :span="16" :offset="4">
<div class="">
<!-- 退学 -->
<el-descriptions v-if="disqualificationForm" class="margin-top" title="" :column="3" size="medium" border style="width: 100%">
<el-descriptions-item>
<template slot="label"> 学号 </template>
{{ form.stuNo }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 姓名 </template>
{{ form.stuName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 辅导员 </template>
{{ form.applicantName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 性别 </template>
{{ form.gender }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 院部 </template>
{{ form.departmentName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 年级 </template>
{{ form.gradeName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 班级 </template>
{{ form.className }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 民族 </template>
{{ form.mz }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 政治面貌 </template>
{{ form.politicalStatus }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 籍贯/自治区/直辖市 </template>
{{ form.jg }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 辅导员 </template>
{{ form.applicantName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 退学类别 </template>
{{ quitSchoolMethodFormat(form) }}
</el-descriptions-item>
<el-descriptions-item span="3">
<template slot="label"> 附件上传 </template>
<Affix v-model="form.attachmentUpload" :disabled="true" />
</el-descriptions-item>
<el-descriptions-item span="3">
<template slot="label"> 辅导员联系情况 </template>
{{ form.ideologicalEducation }}
</el-descriptions-item>
<el-descriptions-item span="3">
<template slot="label"> 在校时间说明 </template>
{{ form.instructionSchoolHours }}
</el-descriptions-item>
<el-descriptions-item span="3">
<template slot="label"> 退学文号 </template>
{{ form.reentryNumber }}
</el-descriptions-item>
<el-descriptions-item span="3">
<template slot="label"> 注销类型 </template>
{{ quitSchoolMethodFormat(form) }}
</el-descriptions-item>
<el-descriptions-item span="3">
<template slot="label"> 退学年份 </template>
{{ reentryYearMethodFormat(form) }}
</el-descriptions-item>
<el-descriptions-item span="3">
<template slot="label"> 退学下文 </template>
{{ form.dropOutGLKSHGDShow }}
</el-descriptions-item>
<el-descriptions-item span="3">
<template slot="label"> 备注 </template>
{{ form.remark }}
</el-descriptions-item>
</el-descriptions>
<!-- 给予退学 -->
</div>
<div style="margin-left: 15%; margin-bottom: 20px; font-size: 14px; margin-top: 20px">
<el-button v-if="!formKeyExist" icon="el-icon-edit-outline" type="success" size="mini" @click="handleComplete">同意 </el-button>
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate">委派</el-button>-->
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleAssign">转办</el-button>-->
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate">签收</el-button>-->
<el-button v-if="rejectBtn" icon="el-icon-refresh-left" type="warning" size="mini" @click="handleReturn">退回</el-button>
<el-button v-if="rejectBtn" icon="el-icon-circle-close" type="danger" size="mini" @click="handleReject">驳回</el-button>
</div>
</el-col>
</el-tab-pane>
<!--流程流转记录-->
<el-tab-pane label="流转记录" name="2">
<!--flowRecordList-->
<el-col :span="16" :offset="4">
<div class="block">
<el-timeline>
<el-timeline-item v-for="(item, index) in flowRecordList" :key="index" :icon="setIcon(item.finishTime)" :color="setColor(item.finishTime)">
<p style="font-weight: 700">{{ item.taskName }}</p>
<el-card :body-style="{ padding: '10px' }">
<el-descriptions class="margin-top" :column="1" size="small" border>
<el-descriptions-item v-if="item.assigneeName" label-class-name="my-label">
<template slot="label"><i class="el-icon-user" />办理人</template>
{{ item.assigneeName }}
<el-tag type="info" size="mini">{{ item.deptName }}</el-tag>
</el-descriptions-item>
<el-descriptions-item v-if="item.candidate" label-class-name="my-label">
<template slot="label"><i class="el-icon-user" />候选办理</template>
{{ item.candidate }}
</el-descriptions-item>
<el-descriptions-item label-class-name="my-label">
<template slot="label"><i class="el-icon-date" />接收时间</template>
{{ item.createTime }}
</el-descriptions-item>
<el-descriptions-item v-if="item.finishTime" label-class-name="my-label">
<template slot="label"><i class="el-icon-date" />处理时间</template>
{{ item.finishTime }}
</el-descriptions-item>
<el-descriptions-item v-if="item.duration" label-class-name="my-label">
<template slot="label"><i class="el-icon-time" />耗时</template>
{{ item.duration }}
</el-descriptions-item>
<el-descriptions-item v-if="item.comment" label-class-name="my-label">
<template slot="label"><i class="el-icon-tickets" />处理意见</template>
{{ item.comment.comment }}
</el-descriptions-item>
</el-descriptions>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
</el-col>
</el-tab-pane>
<!--流程图-->
<el-tab-pane label="流程图" name="3">
<flow :flow-data="flowData" />
</el-tab-pane>
</el-tabs>
<!--审批任务-->
<el-dialog :title="completeTitle" class="certificate-service" :visible.sync="completeOpen" width="60%" append-to-body>
<el-button type="danger" @click="fileUpload">下载退学下文</el-button>
<el-form ref="taskForm" :model="taskForm" :rules="rules" label-width="130px">
<el-form-item prop="targetKey">
<flow-user v-if="checkSendUser" :check-type="checkType" @handleUserSelect="handleUserSelect" />
<flow-role v-if="checkSendRole" @handleRoleSelect="handleRoleSelect" />
</el-form-item>
<!-- 退学表单学生教育管理科审核归档 -->
<el-form-item v-if="dropOutGLKSHGDShow" label="退学文号" prop="reentryNumber">
<el-input v-model="taskForm.reentryNumber" placeholder="请输入退学文号" />
</el-form-item>
<el-form-item v-if="dropOutGLKSHGDShow" label="注销类型" prop="disqualificatioType">
<el-select v-model="taskForm.disqualificatioType" placeholder="请选择注销类型">
<el-option v-for="dict in dict.type.rt_logout_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item v-if="dropOutGLKSHGDShow" label="退学年份" prop="reentryYear">
<el-select v-model="taskForm.reentryYear" clearable placeholder="请选择退学年份">
<el-option v-for="dict in dict.type.sys_teacher_kpi_filling_year" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item v-if="dropOutGLKSHGDShow" label="退学下文" prop="ihandlingSuggestion">
<file-upload v-model="taskForm.ihandlingSuggestion" :disabled="true" />
</el-form-item>
<el-form-item v-if="dropOutGLKSHGDShow" label="备注" prop="remark">
<el-input v-model="taskForm.remark" placeholder="请输入备注" type="textarea" rows="3" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="completeOpen = false"> </el-button>
<el-button type="primary" @click="taskComplete"> </el-button>
</span>
</el-dialog>
<!--退回流程-->
<el-dialog :title="returnTitle" :visible.sync="returnOpen" width="40%" append-to-body>
<el-form ref="taskForm" :model="taskForm" label-width="80px">
<el-form-item label="退回节点" prop="targetKey">
<el-radio-group v-model="taskForm.targetKey">
<el-radio-button v-for="item in returnTaskList" :key="item.id" :label="item.id">{{ item.name }} </el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="退回意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input v-model="taskForm.comment" style="width: 50%" type="textarea" placeholder="请输入意见" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="returnOpen = false"> </el-button>
<el-button type="primary" @click="taskReturn"> </el-button>
</span>
</el-dialog>
<!--驳回流程-->
<el-dialog :title="rejectTitle" :visible.sync="rejectOpen" width="40%" append-to-body>
<el-form ref="taskForm" :model="taskForm" label-width="80px">
<el-form-item label="驳回意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input v-model="taskForm.comment" style="width: 50%" type="textarea" placeholder="请输入意见" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="rejectOpen = false"> </el-button>
<el-button type="primary" @click="taskReject"> </el-button>
</span>
</el-dialog>
</el-card>
</div>
</template>
<script>
import { flowXmlAndNode, getProcessVariables } from '@/api/flowable/definition'
import { flowRecord } from '@/api/flowable/finished'
import { complete, delegate, flowTaskForm, getNextFlowNode, rejectTask, returnList, returnTask } from '@/api/flowable/todo'
import { getRtStuDisqualificationByProcInsId, updateDisqualification } from '@/api/routine/disqualification'
import FlowRole from '@/components/flow/Role'
import FlowUser from '@/components/flow/User'
import Parser from '@/components/parser/Parser'
import download from '@/plugins/download'
import { checkRole } from '@/utils/permission' // 权限判断函数
import flow from '@/views/flowable/task/todo/detail/flow'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import pdf from 'vue-pdf'
export default {
name: 'DisqualificationIndex',
dicts: ['rt_penalty_type', 'rt_penalty_status', 'rt_quit_type', 'sys_teacher_kpi_filling_year', 'rt_logout_type'],
components: {
Parser,
flow,
FlowUser,
FlowRole,
pdf,
},
props: {},
data() {
return {
// 模型xml数据
xmlData: '',
flowData: {},
activeName: '1',
// 部门名称
deptName: undefined,
// 部门树选项
// 用户表格数据
userList: null,
defaultProps: {
children: 'children',
label: 'label',
},
// 查询参数
queryParams: {
deptId: undefined,
},
// 遮罩层
loading: true,
flowRecordList: [], // 流程流转数据
formConfCopy: {},
src: null,
rules: {
reentryNumber: [{ required: true, message: '请输入退学文号', trigger: 'blur' }],
disqualificatioType: [{ required: true, message: '请选择注销类型', trigger: 'blur' }],
reentryYear: [{ required: true, message: '请选择退学年份', trigger: 'blur' }],
ihandlingSuggestion: [{ required: true, message: '请上传退学下文', trigger: 'blur' }],
}, // 表单校验
variablesForm: {}, // 流程变量数据
taskForm: {
returnTaskShow: false, // 是否展示回退表单
delegateTaskShow: false, // 是否展示回退表单
defaultTaskShow: true, // 默认处理
comment: '', // 意见内容
procInsId: '', // 流程实例编号
instanceId: '', // 流程实例编号
deployId: '', // 流程定义编号
taskId: '', // 流程任务编号
procDefId: '', // 流程编号
targetKey: '',
variables: {
variables: {},
},
penaltyNumber: '',
letterServiceContent: '',
violationDate: '',
relieveNumber: '',
dispositionServiceContent: '',
ideologicalEducation: '',
},
assignee: null,
formConf: {}, // 默认表单数据
variables: [], // 流程变量数据
variablesData: {}, // 流程变量数据
returnTaskList: [], // 回退列表数据
completeTitle: null,
completeOpen: false,
returnTitle: null,
returnOpen: false,
rejectOpen: false,
rejectTitle: null,
userData: [],
checkSendUser: false, // 是否展示人员选择模块
checkSendRole: false, // 是否展示角色选择模块
checkType: 'single', // 选择类型
taskName: null, // 任务节点
startUser: null, // 发起人信息,
multiInstanceVars: '', // 会签节点
formKeyExist: false, // 当前节点是否存在表单
// 表单参数:目前是考勤表单
form: {},
// 学生基础信息
stuInfo: {},
baseUrl: process.env.VUE_APP_BASE_API,
category: null, // 流程分类
disqualificationForm: false, // 退学申请表单
dropOutShow: false, // 退学申请输入框显示
dropOutGLKSHGDShow: false, // 学生退学教育管理科审核归档
rejectBtn: true, //驳回按钮
dispositionServiceContent: '', //处分下文
pdfURL: '', // pdf路径
letterServiceContent: '', // 送达书文字
showFileDowload: false, //是否显示下载下文
quitTypeOptions: [], //退学类别
}
},
created() {
if (this.$route.query) {
this.taskName = this.$route.query.taskName
this.startUser = this.$route.query.startUser
this.taskForm.deployId = this.$route.query.deployId
this.taskForm.taskId = this.$route.query.taskId
this.taskForm.procInsId = this.$route.query.procInsId
this.taskForm.executionId = this.$route.query.executionId
this.taskForm.instanceId = this.$route.query.procInsId
this.category = this.$route.query.category
// 如果任务名是其中的两个,则改变审批意见的输入框内容
if (this.category == 'disqualification') {
this.disqualificationForm = true
this.getRtStuDisqualificationByProcInsId(this.taskForm.procInsId)
if (this.taskName == '学生教育管理科审批归档') {
this.dropOutGLKSHGDShow = true
}
}
if (this.taskName == '学生接收' || (this.taskName == '辅导员接收' && this.category == 'disqualification')) {
this.showFileDowload = true
}
// 流程任务获取变量信息
if (this.taskForm.taskId) {
this.processVariables(this.taskForm.taskId)
this.getFlowTaskForm(this.taskForm.taskId)
}
this.getFlowRecordList(this.taskForm.procInsId, this.taskForm.deployId)
this.rejectBtn = !checkRole(['teststu'])
}
},
methods: {
reentryYearMethodFormat(row, column) {
return this.selectDictLabel(this.dict.type.sys_teacher_kpi_filling_year, row.reentryYear)
},
penaltyTypeMethodFormat(row, column) {
return this.selectDictLabel(this.dict.type.rt_penalty_type, row.penaltyType)
},
quitSchoolMethodFormat(row, column) {
return this.selectDictLabel(this.dict.type.rt_logout_type, row.disqualificatioType)
},
// 查询退学表单信息
getRtStuDisqualificationByProcInsId(procInsId) {
getRtStuDisqualificationByProcInsId(procInsId).then((res) => {
this.form = res.data
this.pdfURL = this.baseUrl + this.form.ihandlingSuggestion
})
},
handleClick(tab, event) {
if (tab.name === '3') {
flowXmlAndNode({ procInsId: this.taskForm.procInsId, deployId: this.taskForm.deployId }).then((res) => {
this.flowData = res.data
})
}
},
setIcon(val) {
if (val) {
return 'el-icon-check'
} else {
return 'el-icon-time'
}
},
setColor(val) {
if (val) {
return '#2bc418'
} else {
return '#b3bdbb'
}
},
// 用户信息选中数据
handleUserSelect(selection) {
if (selection) {
if (selection instanceof Array) {
const selectVal = selection.map((item) => item.userId)
if (this.multiInstanceVars) {
this.$set(this.taskForm.variables, this.multiInstanceVars, selectVal)
} else {
this.$set(this.taskForm.variables, 'approval', selectVal.join(','))
}
} else {
this.$set(this.taskForm.variables, 'approval', selection.userId.toString())
}
}
},
// 角色信息选中数据
handleRoleSelect(selection) {
if (selection) {
if (selection instanceof Array) {
const selectVal = selection.map((item) => item.roleId)
this.$set(this.taskForm.variables, 'approval', selectVal.join(','))
} else {
this.$set(this.taskForm.variables, 'approval', selection)
}
}
},
/** 流程流转记录 */
getFlowRecordList(procInsId, deployId) {
const that = this
const params = { procInsId: procInsId, deployId: deployId }
flowRecord(params)
.then((res) => {
that.flowRecordList = res.data.flowList
})
.catch((res) => {
this.goBack()
})
},
fillFormData(form, data) {
form.fields.forEach((item) => {
const val = data[item.__vModel__]
if (val) {
item.__config__.defaultValue = val
}
})
},
/** 获取流程变量内容 */
processVariables(taskId) {
if (taskId) {
// 提交流程申请时填写的表单存入了流程变量中后续任务处理时需要展示
getProcessVariables(taskId).then((res) => {
this.variablesData = res.data.variables
})
}
},
/** 流程节点表单 */
getFlowTaskForm(taskId) {
if (taskId) {
// 提交流程申请时填写的表单存入了流程变量中后续任务处理时需要展示
flowTaskForm({ taskId: taskId }).then((res) => {
this.variablesData = res.data.formData
this.taskForm.variables = res.data.formData
this.formKeyExist = res.data.formKeyExist
})
}
},
/** 加载审批任务弹框 */
handleComplete() {
// this.completeOpen = true;
// this.completeTitle = "流程审批";
this.submitForm(null)
},
/** 用户审批任务 */
taskComplete() {
// if (!this.taskForm.variables && this.checkSendUser) {
// this.$modal.msgError('请选择流程接收人员!')
// return
// }
// if (!this.taskForm.variables && this.checkSendRole) {
// this.$modal.msgError('请选择流程接收角色组!')
// return
// }
this.$refs['taskForm'].validate((valid) => {
if (valid) {
this.$modal.loading('正在努力加载中,请稍等。。。')
this.taskForm.comment = '同意'
// 流程设计人员类型配置为固定人员接收任务时,直接提交任务到下一步
complete(this.taskForm).then((response) => {
if (this.taskName == '学生教育管理科审批归档' && this.category == 'disqualification') {
// 学生教育管理科审核,赋值
this.form.reentryNumber = this.taskForm.reentryNumber
this.form.disqualificatioType = this.taskForm.disqualificatioType
this.form.reentryYear = this.taskForm.reentryYear
this.form.ihandlingSuggestion = this.taskForm.ihandlingSuggestion
this.form.remark = this.taskForm.remark
this.updateDisqualification()
} else {
this.$modal.msgSuccess(response.msg)
}
this.$modal.closeLoading()
this.goBack()
})
}
})
},
updateDisqualification() {
updateDisqualification(this.form).then((response) => {
this.$modal.msgSuccess(response.msg)
})
},
/** 委派任务 */
handleDelegate() {
this.taskForm.delegateTaskShow = true
this.taskForm.defaultTaskShow = false
},
handleAssign() {},
/** 返回页面 */
goBack() {
// 关闭当前标签页并返回上个页面
const obj = { path: '/task/todo', query: { t: Date.now() } }
console.log(obj)
this.$tab.closeOpenPage(obj)
},
/** 驳回任务 */
handleReject() {
this.rejectOpen = true
this.rejectTitle = '驳回流程'
},
/** 驳回任务 */
taskReject() {
this.$refs['taskForm'].validate((valid) => {
if (valid) {
rejectTask(this.taskForm).then((res) => {
this.$modal.msgSuccess(res.msg)
this.goBack()
})
}
})
},
/** 可退回任务列表 */
handleReturn() {
this.returnOpen = true
this.returnTitle = '退回流程'
returnList(this.taskForm).then((res) => {
this.returnTaskList = res.data
this.taskForm.variables = null
})
},
/** 提交退回任务 */
taskReturn() {
this.$refs['taskForm'].validate((valid) => {
if (valid) {
returnTask(this.taskForm).then((res) => {
this.$modal.msgSuccess(res.msg)
this.goBack()
})
}
})
},
/** 取消回退任务按钮 */
cancelTask() {
this.taskForm.returnTaskShow = false
this.taskForm.defaultTaskShow = true
this.returnTaskList = []
},
/** 委派任务 */
submitDeleteTask() {
this.$refs['taskForm'].validate((valid) => {
if (valid) {
delegate(this.taskForm).then((response) => {
this.$modal.msgSuccess(response.msg)
this.goBack()
})
}
})
},
/** 取消回退任务按钮 */
cancelDelegateTask() {
this.taskForm.delegateTaskShow = false
this.taskForm.defaultTaskShow = true
this.returnTaskList = []
},
/** 申请流程表单数据提交 */
submitForm(formData) {
// 根据当前任务或者流程设计配置的下一步节点 todo 暂时未涉及到考虑网关、表达式和多节点情况
const params = { taskId: this.taskForm.taskId }
getNextFlowNode(params).then((res) => {
const data = res.data
this.taskForm.formData = formData
// if (data) {
// 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.completeOpen = true
this.completeTitle = '流程审批'
})
},
fileUpload() {
download.resource(this.pdfURL)
},
},
}
</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;
}
.indented-text {
text-indent: 1em;
}
.gongzhang {
margin-right: 10px;
margin-bottom: 10px;
position: relative;
}
.gongzhang img {
position: absolute;
top: -20px;
/* 根据需要调整图片的垂直位置 */
left: 0;
/* 根据需要调整图片的水平位置 */
}
.gongzhang p {
margin-top: 20px;
/* 根据需要调整两个 p 标签之间的垂直距离 */
}
.certificate-service {
.desc {
text-indent: 2em;
}
.stamp {
text-align: right;
& > div {
margin-top: -70px;
margin-right: 25px;
}
img {
width: 120px;
height: 120px;
}
}
}
</style>