submitVerify.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <template>
  2. <el-dialog v-model="dialog.visible" :title="dialog.title" width="50%" draggable :before-close="cancel" center :close-on-click-modal="false">
  3. <el-form v-loading="loading" :model="form" label-width="120px">
  4. <el-form-item label="消息提醒">
  5. <el-checkbox-group v-model="form.messageType">
  6. <el-checkbox label="1" name="type" disabled>站内信</el-checkbox>
  7. <el-checkbox label="2" name="type">邮件</el-checkbox>
  8. <el-checkbox label="3" name="type">短信</el-checkbox>
  9. </el-checkbox-group>
  10. </el-form-item>
  11. <el-form-item label="附件" v-if="task.businessStatus === 'waiting'">
  12. <fileUpload v-model="form.fileId" :fileType="['doc', 'xls', 'ppt', 'txt', 'pdf', 'xlsx', 'docx', 'zip']" :fileSize="'20'"/>
  13. </el-form-item>
  14. <el-form-item label="抄送">
  15. <el-button type="primary" @click="openUserSelectCopy" icon="Plus" circle />
  16. <el-tag v-for="user in selectCopyUserList" :key="user.userId" closable style="margin: 2px" @close="handleCopyCloseTag(user)">
  17. {{ user.userName }}
  18. </el-tag>
  19. </el-form-item>
  20. <el-form-item label="审批意见" v-if="task.businessStatus === 'waiting'">
  21. <el-input v-model="form.message" type="textarea" resize="none" />
  22. </el-form-item>
  23. </el-form>
  24. <template #footer>
  25. <span class="dialog-footer">
  26. <el-button v-loading="buttonLoading" type="primary" @click="handleCompleteTask"> 提交 </el-button>
  27. <el-button v-if="task.businessStatus === 'waiting'" v-loading="buttonLoading" type="primary" @click="openDelegateTask"> 委托 </el-button>
  28. <el-button v-if="task.businessStatus === 'waiting'" v-loading="buttonLoading" type="primary" @click="openTransferTask"> 转办 </el-button>
  29. <el-button v-if="task.businessStatus === 'waiting' && task.multiInstance" v-loading="buttonLoading" type="primary" @click="addMultiInstanceUser"> 加签 </el-button>
  30. <el-button v-if="task.businessStatus === 'waiting' && task.multiInstance" v-loading="buttonLoading" type="primary" @click="deleteMultiInstanceUser"> 减签 </el-button>
  31. <el-button v-if="task.businessStatus === 'waiting'" v-loading="buttonLoading" type="danger" @click="handleTerminationTask"> 终止 </el-button>
  32. <el-button v-if="task.businessStatus === 'waiting'" v-loading="buttonLoading" type="danger" @click="handleBackProcessOpen"> 退回 </el-button>
  33. <el-button v-loading="buttonLoading" @click="cancel">取消</el-button>
  34. </span>
  35. </template>
  36. <!-- 抄送 -->
  37. <UserSelect ref="userSelectCopyRef" :multiple="true" :data="selectCopyUserIds" @confirm-call-back="userSelectCopyCallBack"></UserSelect>
  38. <!-- 转办 -->
  39. <UserSelect ref="transferTaskRef" :multiple="false" @confirm-call-back="handleTransferTask"></UserSelect>
  40. <!-- 委托 -->
  41. <UserSelect ref="delegateTaskRef" :multiple="false" @confirm-call-back="handleDelegateTask"></UserSelect>
  42. <!-- 加签组件 -->
  43. <multiInstanceUser ref="multiInstanceUserRef" :title="title" @submit-callback='closeDialog' />
  44. <!-- 驳回开始 -->
  45. <el-dialog v-model="backVisible" draggable title="驳回" width="40%" :close-on-click-modal="false">
  46. <el-form v-loading="backLoading" :model="backForm" label-width="120px" v-if="task.businessStatus === 'waiting'">
  47. <el-form-item label="驳回节点">
  48. <el-select clearable placeholder="请选择" v-model="backForm.targetActivityId" style="width: 300px">
  49. <el-option
  50. v-for="item in taskNodeList"
  51. :key="item.nodeId"
  52. :label="item.nodeName"
  53. :value="item.nodeId"
  54. />
  55. </el-select>
  56. </el-form-item>
  57. <el-form-item label="消息提醒">
  58. <el-checkbox-group v-model="backForm.messageType">
  59. <el-checkbox label="1" name="type" disabled>站内信</el-checkbox>
  60. <el-checkbox label="2" name="type">邮件</el-checkbox>
  61. <el-checkbox label="3" name="type">短信</el-checkbox>
  62. </el-checkbox-group>
  63. </el-form-item>
  64. <el-form-item label="审批意见">
  65. <el-input v-model="backForm.message" type="textarea" resize="none" />
  66. </el-form-item>
  67. </el-form>
  68. <template #footer>
  69. <div class="dialog-footer" style="float: right;padding-bottom: 20px;">
  70. <el-button type="primary" v-loading="backLoading" @click="handleBackProcess">确认</el-button>
  71. <el-button v-loading="backLoading" @click="backVisible = false">取消</el-button>
  72. </div>
  73. </template>
  74. </el-dialog>
  75. <!-- 驳回结束 -->
  76. </el-dialog>
  77. </template>
  78. <script lang="ts" setup>
  79. import { ref } from 'vue';
  80. import { ComponentInternalInstance } from 'vue';
  81. import { ElForm } from 'element-plus';
  82. import { completeTask, backProcess, getTaskById,transferTask,terminationTask,getTaskNodeList,delegateTask } from '@/api/workflow/task';
  83. import UserSelect from '@/components/UserSelect';
  84. import MultiInstanceUser from '@/components/Process/multiInstanceUser.vue';
  85. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  86. import { UserVO } from '@/api/system/user/types';
  87. import { TaskVO } from '@/api/workflow/task/types';
  88. const userSelectCopyRef = ref<InstanceType<typeof UserSelect>>();
  89. const transferTaskRef = ref<InstanceType<typeof UserSelect>>();
  90. const delegateTaskRef = ref<InstanceType<typeof UserSelect>>();
  91. //加签组件
  92. const multiInstanceUserRef = ref<InstanceType<typeof MultiInstanceUser>>();
  93. const props = defineProps({
  94. taskVariables: {
  95. type: Object as () => Record<string, any>,
  96. default: {}
  97. }
  98. });
  99. //遮罩层
  100. const loading = ref(true);
  101. //按钮
  102. const buttonLoading = ref(true);
  103. //任务id
  104. const taskId = ref<string>('');
  105. //抄送人
  106. const selectCopyUserList = ref<UserVO[]>([]);
  107. //抄送人id
  108. const selectCopyUserIds = ref<string>(undefined);
  109. // 驳回是否显示
  110. const backVisible = ref(false);
  111. const backLoading = ref(true);
  112. // 可驳回得任务节点
  113. const taskNodeList = ref([]);
  114. //任务
  115. const task = ref<TaskVO>({
  116. id: undefined,
  117. name: undefined,
  118. description: undefined,
  119. priority: undefined,
  120. owner: undefined,
  121. assignee: undefined,
  122. assigneeName: undefined,
  123. processInstanceId: undefined,
  124. executionId: undefined,
  125. taskDefinitionId: undefined,
  126. processDefinitionId: undefined,
  127. endTime: undefined,
  128. taskDefinitionKey: undefined,
  129. dueDate: undefined,
  130. category: undefined,
  131. parentTaskId: undefined,
  132. tenantId: undefined,
  133. claimTime: undefined,
  134. businessStatus: undefined,
  135. businessStatusName: undefined,
  136. processDefinitionName: undefined,
  137. processDefinitionKey: undefined,
  138. participantVo: undefined,
  139. multiInstance: undefined,
  140. businessKey: undefined,
  141. wfNodeConfigVo: undefined,
  142. wfDefinitionConfigVo: undefined
  143. });
  144. //加签 减签标题
  145. const title = ref('');
  146. const dialog = reactive<DialogOption>({
  147. visible: false,
  148. title: '提示'
  149. });
  150. const form = ref<Record<string, any>>({
  151. taskId: undefined,
  152. message: undefined,
  153. variables: {},
  154. messageType: ['1'],
  155. wfCopyList: []
  156. });
  157. const backForm = ref<Record<string, any>>({
  158. taskId: undefined,
  159. targetActivityId: undefined,
  160. message: undefined,
  161. variables: {},
  162. messageType: ['1']
  163. });
  164. const closeDialog = () => {
  165. dialog.visible = false
  166. }
  167. //打开弹窗
  168. const openDialog = (id?: string) => {
  169. selectCopyUserIds.value = undefined
  170. selectCopyUserList.value = []
  171. form.value.fileId = undefined
  172. taskId.value = id;
  173. form.value.message = undefined;
  174. dialog.visible = true;
  175. loading.value = true;
  176. buttonLoading.value = true;
  177. nextTick(() => {
  178. getTaskById(taskId.value).then((response) => {
  179. task.value = response.data;
  180. loading.value = false;
  181. buttonLoading.value = false;
  182. });
  183. });
  184. };
  185. onMounted(() => {});
  186. const emits = defineEmits(['submitCallback', 'cancelCallback']);
  187. /** 办理流程 */
  188. const handleCompleteTask = async () => {
  189. form.value.taskId = taskId.value;
  190. form.value.taskVariables = props.taskVariables;
  191. if(selectCopyUserList && selectCopyUserList.value.length > 0){
  192. let wfCopyList = []
  193. selectCopyUserList.value.forEach( e=> {
  194. let copyUser = {
  195. userId: e.userId,
  196. userName: e.nickName
  197. }
  198. wfCopyList.push(copyUser)
  199. })
  200. form.value.wfCopyList = wfCopyList
  201. }
  202. await proxy?.$modal.confirm('是否确认提交?');
  203. loading.value = true;
  204. buttonLoading.value = true;
  205. try {
  206. await completeTask(form.value);
  207. dialog.visible = false;
  208. emits('submitCallback');
  209. proxy?.$modal.msgSuccess('操作成功');
  210. }finally {
  211. loading.value = false
  212. buttonLoading.value = false
  213. }
  214. };
  215. /** 驳回弹窗打开 */
  216. const handleBackProcessOpen = async () => {
  217. backForm.value = {}
  218. backForm.value.messageType = ['1']
  219. backVisible.value = true
  220. backLoading.value = true
  221. let data = await getTaskNodeList(task.value.processInstanceId)
  222. taskNodeList.value = data.data
  223. backLoading.value = false
  224. backForm.value.targetActivityId = taskNodeList.value[0].nodeId
  225. }
  226. /** 驳回流程 */
  227. const handleBackProcess = async () => {
  228. backForm.value.taskId = taskId.value;
  229. await proxy?.$modal.confirm('是否确认驳回到申请人?');
  230. loading.value = true;
  231. backLoading.value = true;
  232. await backProcess(backForm.value).finally(() => (loading.value = false));
  233. dialog.visible = false;
  234. backLoading.value = false
  235. emits('submitCallback');
  236. proxy?.$modal.msgSuccess('操作成功');
  237. };
  238. //取消
  239. const cancel = async () => {
  240. dialog.visible = false;
  241. buttonLoading.value = false;
  242. emits('cancelCallback');
  243. };
  244. //打开抄送人员
  245. const openUserSelectCopy = () => {
  246. userSelectCopyRef.value.open();
  247. };
  248. //确认抄送人员
  249. const userSelectCopyCallBack = (data: UserVO[]) => {
  250. if(data && data.length > 0){
  251. selectCopyUserList.value = data
  252. selectCopyUserIds.value = selectCopyUserList.value.map((item) => item.userId).join(',');
  253. }
  254. }
  255. //删除抄送人员
  256. const handleCopyCloseTag = (user: UserVO) => {
  257. const userId = user.userId;
  258. // 使用split删除用户
  259. const index = selectCopyUserList.value.findIndex((item) => item.userId === userId);
  260. selectCopyUserList.value.splice(index, 1);
  261. selectCopyUserIds.value = selectCopyUserList.value.map((item) => item.userId).join(',');
  262. };
  263. //加签
  264. const addMultiInstanceUser = () => {
  265. if (multiInstanceUserRef.value) {
  266. title.value = '加签人员';
  267. multiInstanceUserRef.value.getAddMultiInstanceList(taskId.value, []);
  268. }
  269. };
  270. //减签
  271. const deleteMultiInstanceUser = () => {
  272. if (multiInstanceUserRef.value) {
  273. title.value = '减签人员';
  274. multiInstanceUserRef.value.getDeleteMultiInstanceList(taskId.value);
  275. }
  276. };
  277. //打开转办
  278. const openTransferTask = () => {
  279. transferTaskRef.value.open();
  280. };
  281. //转办
  282. const handleTransferTask = async (data) => {
  283. if(data && data.length > 0){
  284. let params = {
  285. taskId: taskId.value,
  286. userId: data[0].userId,
  287. comment: form.value.message
  288. }
  289. await proxy?.$modal.confirm('是否确认提交?');
  290. loading.value = true;
  291. buttonLoading.value = true;
  292. await transferTask(params).finally(() => (loading.value = false));
  293. dialog.visible = false;
  294. emits('submitCallback');
  295. proxy?.$modal.msgSuccess('操作成功');
  296. }else{
  297. proxy?.$modal.msgWarning('请选择用户!');
  298. }
  299. }
  300. //打开委托
  301. const openDelegateTask = () => {
  302. delegateTaskRef.value.open();
  303. };
  304. //委托
  305. const handleDelegateTask = async (data) => {
  306. if(data && data.length > 0){
  307. let params = {
  308. taskId: taskId.value,
  309. userId: data[0].userId,
  310. nickName: data[0].nickName
  311. }
  312. await proxy?.$modal.confirm('是否确认提交?');
  313. loading.value = true;
  314. buttonLoading.value = true;
  315. await delegateTask(params).finally(() => (loading.value = false));
  316. dialog.visible = false;
  317. emits('submitCallback');
  318. proxy?.$modal.msgSuccess('操作成功');
  319. }else{
  320. proxy?.$modal.msgWarning('请选择用户!');
  321. }
  322. }
  323. //终止任务
  324. const handleTerminationTask = async (data) => {
  325. let params = {
  326. taskId: taskId.value,
  327. comment: form.value.message
  328. }
  329. await proxy?.$modal.confirm('是否确认终止?');
  330. loading.value = true;
  331. buttonLoading.value = true;
  332. await terminationTask(params).finally(() => (loading.value = false));
  333. dialog.visible = false;
  334. emits('submitCallback');
  335. proxy?.$modal.msgSuccess('操作成功');
  336. }
  337. /**
  338. * 对外暴露子组件方法
  339. */
  340. defineExpose({
  341. openDialog
  342. });
  343. </script>